@@ -10,33 +10,38 @@ try {
1010} catch { }
1111
1212// import.meta.resolve is only available in ESM, but this file is compiled to CJS.
13- // We can extract ir using dynamic import.
14- const resolveP =
13+ // We can extract it using dynamic import.
14+ const importMetaResolveP : Promise < ImportMeta [ "resolve" ] > =
1515 import_ &&
1616 // Due to a Node.js/V8 bug (https://github.com/nodejs/node/issues/35889), we cannot
17- // use dynamic import when running in the default Jest environment because it
18- // uses vm.SourceTextModule.
19- // Jest defines globalThis["jest-symbol-do-not-touch"] in
20- // https://github.com/facebook/jest/blob/11d79ec096a25851124356095d60352f6ca2824e/packages/jest-util/src/installCommonGlobals.ts#L49
21- // which is called by
22- // https://github.com/facebook/jest/blob/11d79ec096a25851124356095d60352f6ca2824e/packages/jest-environment-node/src/index.ts#L85
17+ // use always dynamic import because it segfaults when running in a Node.js `vm` context,
18+ // which is used by the default Jest environment and by webpack-cli.
2319 //
24- // Note that our Jest runner doesn't have this problem, because it runs ESM in the default
25- // Node.js context rather than using the `vm` module.
20+ // However, import.meta.resolve is experimental and only enabled when Node.js is run
21+ // with the `--experimental-import-meta-resolve` flag: we can avoid calling import()
22+ // when that flag is not enabled, so that the default behavior never segfaults.
2623 //
27- // When V8 fixes this bug, we can remove this check. We usually don't have package-specific hacks,
28- // but Jest is a big Babel consumer widely used in the community and they cannot workaround
29- // this problem on their side.
30- ! Object . hasOwnProperty . call ( global , "jest-symbol-do-not-touch" )
24+ // Hopefully, before Node.js unflags import.meta.resolve, either:
25+ // - we will move to ESM, so that we have direct access to import.meta.resolve, or
26+ // - the V8 bug will be fixed so that we can safely use dynamic import by default.
27+ //
28+ // I (@nicolo-ribaudo) am really anoyed by this bug, because there is no known
29+ // work-around other than "don't use dynamic import if you are running in a `vm` context",
30+ // but there is no reliable way to detect it (you cannot try/catch segfaults).
31+ //
32+ // This is the only place where we *need* to use dynamic import because we need to access
33+ // an ES module. All the other places will first try using require() and *then*, if
34+ // it throws because it's a module, will fallback to import().
35+ process . execArgv . includes ( "--experimental-import-meta-resolve" )
3136 ? import_ ( "data:text/javascript,export default import.meta.resolve" ) . then (
32- // Since import.meta.resolve is unstable and only available when
33- // using the --experimental-import-meta-resolve flag, we almost
34- // always use the polyfill for now.
3537 m => m . default || polyfill ,
3638 ( ) => polyfill ,
3739 )
3840 : Promise . resolve ( polyfill ) ;
3941
40- export default function getImportMetaResolve ( ) : Promise < ImportMeta [ "resolve" ] > {
41- return resolveP ;
42+ export default async function resolve (
43+ specifier : Parameters < ImportMeta [ "resolve" ] > [ 0 ] ,
44+ parent ?: Parameters < ImportMeta [ "resolve" ] > [ 1 ] ,
45+ ) : ReturnType < ImportMeta [ "resolve" ] > {
46+ return ( await importMetaResolveP ) ( specifier , parent ) ;
4247}
0 commit comments