Skip to content

Commit 852b5e4

Browse files
committed
Upgrade ERN to support RN 0.81
1 parent 94d2faf commit 852b5e4

62 files changed

Lines changed: 1242 additions & 175 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: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,21 @@ 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['@react-native/community-cli-plugin'] =
15+
version;
16+
// Add CLI packages to ensure android and ios platforms are available
17+
compositePackageJson.dependencies['@react-native-community/cli'] = '15.1.3';
18+
compositePackageJson.dependencies[
19+
'@react-native-community/cli-platform-android'
20+
] = '15.1.3';
21+
compositePackageJson.dependencies[
22+
'@react-native-community/cli-platform-ios'
23+
] = '15.1.3';
24+
} else if (semver.gte(version, '0.77.0')) {
1125
compositePackageJson.dependencies['@react-native/metro-config'] = version;
1226
compositePackageJson.dependencies['@react-native/babel-preset'] = version;
1327
// Add CLI packages to ensure android and ios platforms are available

ern-composite-gen/src/createMetroConfig.ts

Lines changed: 132 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,95 @@ 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(
131+
reactNativeVersion,
132+
)}');
133+
module.exports = {
134+
${projectRoot ? `projectRoot: "${projectRoot}",` : ''}
135+
${
136+
watchFolders
137+
? `watchFolders: [
138+
${watchFolders
139+
.map((x) => `"${x.replace(/\\/g, '\\\\')}"`)
140+
.join(`,${os.EOL}`)}
141+
],`
142+
: ''
143+
}
144+
resolver: {
145+
blacklistRE: blacklist([
146+
// Ignore IntelliJ directories
147+
/.*\\.idea\\/.*/,
148+
// ignore git directories
149+
/.*\\.git\\/.*/,
150+
// Ignore android directories
151+
/.*\\/app\\/build\\/.*/,
152+
${blacklistRe ? blacklistRe.join(`,${os.EOL}`) : ''}
153+
]),
154+
${
155+
extraNodeModules
156+
? `extraNodeModules: ${JSON.stringify(extraNodeModules, null, 2)},`
157+
: ''
158+
}
159+
assetExts: [
160+
// Image formats
161+
"bmp",
162+
"gif",
163+
"jpg",
164+
"jpeg",
165+
"png",
166+
"psd",
167+
"webp",
168+
// Video formats
169+
"m4v",
170+
"mov",
171+
"mp4",
172+
"mpeg",
173+
"mpg",
174+
"webm",
175+
// Audio formats
176+
"aac",
177+
"aiff",
178+
"caf",
179+
"m4a",
180+
"mp3",
181+
"wav",
182+
// Document formats
183+
"html",
184+
"pdf",
185+
// Font formats
186+
"otf",
187+
"ttf",
188+
// Archives (virtual files)
189+
"zip"
190+
],
191+
sourceExts: ["js", "json", "ts", "tsx", "svg", "mjs"],
192+
},
193+
transformer: {
194+
getTransformOptions: async () => ({
195+
transform: {
196+
experimentalImportSupport: false,
197+
inlineRequires: false,
198+
},
199+
}),
200+
assetPlugins: ['ern-bundle-store-metro-asset-plugin'],
201+
babelTransformerPath: require.resolve("react-native-svg-transformer"),
202+
},
203+
};
204+
`;
80205
}

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: 6 additions & 1 deletion
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');

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)