@@ -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,93 @@ 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 ( 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}
0 commit comments