Skip to content

Commit 86eba4d

Browse files
committed
Upgrade ERN to support RN 0.81
1 parent 94d2faf commit 86eba4d

62 files changed

Lines changed: 1236 additions & 181 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

azure/templates/system-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
steps:
22
- task: NodeTool@0
33
inputs:
4-
versionSpec: '18.x'
4+
versionSpec: '20.x'
55
displayName: 'Install Node.js'
66
- script: |
77
git config --global user.email "electrodenative@gmail.com"

azure/templates/unit-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
steps:
22
- task: NodeTool@0
33
inputs:
4-
versionSpec: '18.x'
4+
versionSpec: '20.x'
55
displayName: 'Install Node.js'
66
- script: |
77
yarn --frozen-lockfile

ern-composite-gen/src/addRNDepToPjson.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,22 @@ export async function addRNDepToPjson(dir: string, version: string) {
77

88
// For React Native 0.77+, also add required dependencies
99
// This is required by the new Metro config format and CLI
10-
if (semver.gte(version, '0.77.0')) {
10+
if (semver.gte(version, '0.81.0')) {
11+
compositePackageJson.dependencies['@react-native/metro-config'] = version;
12+
compositePackageJson.dependencies['@react-native/babel-preset'] = version;
13+
// RN 0.81+ uses @react-native/community-cli-plugin (internal to RN monorepo)
14+
compositePackageJson.dependencies[
15+
'@react-native/community-cli-plugin'
16+
] = version;
17+
// Add CLI packages to ensure android and ios platforms are available
18+
compositePackageJson.dependencies['@react-native-community/cli'] = '15.1.3';
19+
compositePackageJson.dependencies[
20+
'@react-native-community/cli-platform-android'
21+
] = '15.1.3';
22+
compositePackageJson.dependencies[
23+
'@react-native-community/cli-platform-ios'
24+
] = '15.1.3';
25+
} else if (semver.gte(version, '0.77.0')) {
1126
compositePackageJson.dependencies['@react-native/metro-config'] = version;
1227
compositePackageJson.dependencies['@react-native/babel-preset'] = version;
1328
// Add CLI packages to ensure android and ios platforms are available

ern-composite-gen/src/createMetroConfig.ts

Lines changed: 130 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,61 @@ import fs from 'fs-extra';
22
import path from 'path';
33
import beautify from 'js-beautify';
44
import os from 'os';
5+
import semver from 'semver';
6+
import { getMetroBlacklistPath } from 'ern-core';
57

68
export async function createMetroConfig({
79
cwd,
810
projectRoot,
911
blacklistRe,
1012
extraNodeModules,
1113
watchFolders,
14+
reactNativeVersion,
1215
}: {
1316
cwd?: string;
1417
projectRoot?: string;
1518
blacklistRe?: RegExp[];
1619
extraNodeModules?: { [pkg: string]: string };
1720
watchFolders?: string[];
21+
reactNativeVersion?: string;
1822
}) {
19-
// Metro config format for React Native 0.73+
20-
const metroConfigContent = `const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
23+
const useModernConfig =
24+
reactNativeVersion && semver.gte(reactNativeVersion, '0.73.0');
25+
26+
const metroConfigContent = useModernConfig
27+
? createModernMetroConfig({
28+
projectRoot,
29+
blacklistRe,
30+
extraNodeModules,
31+
watchFolders,
32+
})
33+
: createLegacyMetroConfig({
34+
projectRoot,
35+
blacklistRe,
36+
extraNodeModules,
37+
watchFolders,
38+
reactNativeVersion: reactNativeVersion || '0.60.0',
39+
});
40+
41+
return fs.writeFile(
42+
path.join(cwd ?? path.resolve(), 'metro.config.js'),
43+
beautify.js(metroConfigContent),
44+
);
45+
}
46+
47+
// Metro config format for React Native 0.73+
48+
function createModernMetroConfig({
49+
projectRoot,
50+
blacklistRe,
51+
extraNodeModules,
52+
watchFolders,
53+
}: {
54+
projectRoot?: string;
55+
blacklistRe?: RegExp[];
56+
extraNodeModules?: { [pkg: string]: string };
57+
watchFolders?: string[];
58+
}): string {
59+
return `const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2160
const defaultConfig = getDefaultConfig(__dirname);
2261
2362
const config = {
@@ -45,7 +84,7 @@ const config = {
4584
],
4685
sourceExts: [
4786
...defaultConfig.resolver.sourceExts,
48-
"svg",
87+
"svg",
4988
"mjs"
5089
],
5190
blockList: [
@@ -72,9 +111,93 @@ const config = {
72111
};
73112
74113
module.exports = mergeConfig(defaultConfig, config);`;
114+
}
75115

76-
return fs.writeFile(
77-
path.join(cwd ?? path.resolve(), 'metro.config.js'),
78-
beautify.js(metroConfigContent),
79-
);
116+
// Legacy Metro config format for React Native < 0.73
117+
function createLegacyMetroConfig({
118+
projectRoot,
119+
blacklistRe,
120+
extraNodeModules,
121+
watchFolders,
122+
reactNativeVersion,
123+
}: {
124+
projectRoot?: string;
125+
blacklistRe?: RegExp[];
126+
extraNodeModules?: { [pkg: string]: string };
127+
watchFolders?: string[];
128+
reactNativeVersion: string;
129+
}): string {
130+
return `const blacklist = require('${getMetroBlacklistPath(reactNativeVersion)}');
131+
module.exports = {
132+
${projectRoot ? `projectRoot: "${projectRoot}",` : ''}
133+
${
134+
watchFolders
135+
? `watchFolders: [
136+
${watchFolders
137+
.map((x) => `"${x.replace(/\\/g, '\\\\')}"`)
138+
.join(`,${os.EOL}`)}
139+
],`
140+
: ''
141+
}
142+
resolver: {
143+
blacklistRE: blacklist([
144+
// Ignore IntelliJ directories
145+
/.*\\.idea\\/.*/,
146+
// ignore git directories
147+
/.*\\.git\\/.*/,
148+
// Ignore android directories
149+
/.*\\/app\\/build\\/.*/,
150+
${blacklistRe ? blacklistRe.join(`,${os.EOL}`) : ''}
151+
]),
152+
${
153+
extraNodeModules
154+
? `extraNodeModules: ${JSON.stringify(extraNodeModules, null, 2)},`
155+
: ''
156+
}
157+
assetExts: [
158+
// Image formats
159+
"bmp",
160+
"gif",
161+
"jpg",
162+
"jpeg",
163+
"png",
164+
"psd",
165+
"webp",
166+
// Video formats
167+
"m4v",
168+
"mov",
169+
"mp4",
170+
"mpeg",
171+
"mpg",
172+
"webm",
173+
// Audio formats
174+
"aac",
175+
"aiff",
176+
"caf",
177+
"m4a",
178+
"mp3",
179+
"wav",
180+
// Document formats
181+
"html",
182+
"pdf",
183+
// Font formats
184+
"otf",
185+
"ttf",
186+
// Archives (virtual files)
187+
"zip"
188+
],
189+
sourceExts: ["js", "json", "ts", "tsx", "svg", "mjs"],
190+
},
191+
transformer: {
192+
getTransformOptions: async () => ({
193+
transform: {
194+
experimentalImportSupport: false,
195+
inlineRequires: false,
196+
},
197+
}),
198+
assetPlugins: ['ern-bundle-store-metro-asset-plugin'],
199+
babelTransformerPath: require.resolve("react-native-svg-transformer"),
200+
},
201+
};
202+
`;
80203
}

ern-composite-gen/src/generateComposite.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ You should resolve the following version mismatches prior to retrying.${os.EOL}`
330330
blacklistRe,
331331
cwd: outDir,
332332
extraNodeModules,
333+
reactNativeVersion: rnVersion,
333334
watchFolders: localMiniAppsPaths,
334335
});
335336
if (semver.gte(rnVersion, '0.57.0')) {

ern-container-gen-android/src/AndroidGenerator.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,12 @@ You should replace "${annotationProcessorPrefix}:${dependency}" with "annotation
388388
log.debug('Patching hull');
389389
const files = readDir(
390390
config.outDir,
391-
(f) => !f.endsWith('.jar') && !f.endsWith('.aar') && !f.endsWith('.git'),
391+
(f) =>
392+
!f.endsWith('.jar') &&
393+
!f.endsWith('.aar') &&
394+
!f.endsWith('.git') &&
395+
f !== '.gradle' &&
396+
f !== 'build',
392397
);
393398
const pathLibSrcMain = path.normalize('lib/src/main');
394399
const pathLibSrcMainJniLibs = path.normalize('lib/src/main/jniLibs');
@@ -458,8 +463,8 @@ You should replace "${annotationProcessorPrefix}:${dependency}" with "annotation
458463
? config.androidConfig.jsEngine === 'jsc'
459464
? JavaScriptEngine.JSC
460465
: config.androidConfig.jsEngine === 'hermes'
461-
? JavaScriptEngine.HERMES
462-
: JavaScriptEngine.JSC
466+
? JavaScriptEngine.HERMES
467+
: JavaScriptEngine.JSC
463468
: JavaScriptEngine.JSC;
464469
}
465470

@@ -472,9 +477,8 @@ You should replace "${annotationProcessorPrefix}:${dependency}" with "annotation
472477
// Replace versions of support libraries with set version
473478
dependencies.regular = dependencies.regular.map((d) =>
474479
d.startsWith('androidx.appcompat:')
475-
? `${d.slice(0, d.lastIndexOf(':'))}:${
476-
androidVersions.androidxAppcompactVersion
477-
}`
480+
? `${d.slice(0, d.lastIndexOf(':'))}:${androidVersions.androidxAppcompactVersion
481+
}`
478482
: d,
479483
);
480484

ern-container-gen-android/src/hull/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ buildscript {
55
}
66
dependencies {
77
classpath 'com.android.tools.build:gradle:{{{androidGradlePlugin}}}'
8-
{{#isKotlinEnabled}}
98
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:{{{kotlinVersion}}}'
10-
{{/isKotlinEnabled}}
119
}
1210
}
1311

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
44
networkTimeout=10000
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

ern-container-gen-android/src/hull/lib/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
apply plugin: 'com.android.library'
2-
{{#isKotlinEnabled}}
32
apply plugin: 'kotlin-android'
4-
{{/isKotlinEnabled}}
53

64
android {
75
namespace "com.walmartlabs.ern.container"

ern-container-gen/src/reactNativeBundleAndroid.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export async function reactNativeBundleAndroid({
4343
platform: 'android',
4444
resetCache,
4545
sourceMapOutput,
46+
workingDir: cwd,
4647
});
4748
return result;
4849
} finally {

0 commit comments

Comments
 (0)