@@ -2,22 +2,61 @@ import fs from 'fs-extra';
22import path from 'path' ;
33import beautify from 'js-beautify' ;
44import os from 'os' ;
5+ import semver from 'semver' ;
6+ import { getMetroBlacklistPath } from 'ern-core' ;
57
68export 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');
2160const defaultConfig = getDefaultConfig(__dirname);
2261
2362const 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
74113module.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}
0 commit comments