GeezerVison is showing github.com — esm: do not give wrong hints when detecting file format · nodejs/node@998feda
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/esm/get_format.js +11-5Lines changed: 11 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -110,8 +110,10 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE | 110 | 110 | default: { // The user did not pass `--experimental-default-type`. | 111 | 111 | // `source` is undefined when this is called from `defaultResolve`; | 112 | 112 | // but this gets called again from `defaultLoad`/`defaultLoadSync`. | 113 | | - if (source && getOptionValue('--experimental-detect-module')) { | 114 | | - return containsModuleSyntax(`${source}`, fileURLToPath(url)) ? 'module' : 'commonjs'; | | 113 | + if (getOptionValue('--experimental-detect-module')) { | | 114 | + return source ? | | 115 | + (containsModuleSyntax(`${source}`, fileURLToPath(url)) ? 'module' : 'commonjs') : | | 116 | + null; | 115 | 117 | } | 116 | 118 | return 'commonjs'; | 117 | 119 | } | @@ -136,9 +138,13 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE | 136 | 138 | return 'commonjs'; | 137 | 139 | } | 138 | 140 | default: { // The user did not pass `--experimental-default-type`. | 139 | | - if (source && getOptionValue('--experimental-detect-module') && | 140 | | - getFormatOfExtensionlessFile(url) === 'module') { | 141 | | - return containsModuleSyntax(`${source}`, fileURLToPath(url)) ? 'module' : 'commonjs'; | | 141 | + if (getOptionValue('--experimental-detect-module')) { | | 142 | + if (!source) { return null; } | | 143 | + const format = getFormatOfExtensionlessFile(url); | | 144 | + if (format === 'module') { | | 145 | + return containsModuleSyntax(`${source}`, fileURLToPath(url)) ? 'module' : 'commonjs'; | | 146 | + } | | 147 | + return format; | 142 | 148 | } | 143 | 149 | return 'commonjs'; | 144 | 150 | } | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/esm/load.js +14-10Lines changed: 14 additions & 10 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -105,7 +105,7 @@ function getSourceSync(url, context) { | 105 | 105 | * @param {LoadContext} context | 106 | 106 | * @returns {LoadReturn} | 107 | 107 | */ | 108 | | -async function defaultLoad(url, context = { __proto__: null }) { | | 108 | +async function defaultLoad(url, context = kEmptyObject) { | 109 | 109 | let responseURL = url; | 110 | 110 | let { | 111 | 111 | importAttributes, | @@ -129,18 +129,22 @@ async function defaultLoad(url, context = { __proto__: null }) { | 129 | 129 |
| 130 | 130 | if (urlInstance.protocol === 'node:') { | 131 | 131 | source = null; | 132 | | - } else if (source == null) { | 133 | | - ({ responseURL, source } = await getSource(urlInstance, context)); | 134 | | - context.source = source; | 135 | | - } | | 132 | + format ??= 'builtin'; | | 133 | + } else { | | 134 | + let contextToPass = context; | | 135 | + if (source == null) { | | 136 | + ({ responseURL, source } = await getSource(urlInstance, context)); | | 137 | + contextToPass = { __proto__: context, source }; | | 138 | + } | 136 | 139 |
| 137 | | - if (format == null || format === 'commonjs') { | 138 | 140 | // Now that we have the source for the module, run `defaultGetFormat` again in case we detect ESM syntax. | 139 | | - format = await defaultGetFormat(urlInstance, context); | 140 | | - } | | 141 | + format ??= await defaultGetFormat(urlInstance, contextToPass); | 141 | 142 |
| 142 | | - if (format === 'commonjs') { | 143 | | - source = null; // Let the CommonJS loader handle it (for now) | | 143 | + if (format === 'commonjs' && contextToPass !== context) { | | 144 | + // For backward compatibility reasons, we need to discard the source in | | 145 | + // order for the CJS loader to re-fetch it. | | 146 | + source = null; | | 147 | + } | 144 | 148 | } | 145 | 149 |
| 146 | 150 | validateAttributes(url, format, importAttributes); | |
Collapse file Copy file name to clipboardExpand all lines: test/es-module/test-esm-detect-ambiguous.mjs +23Lines changed: 23 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -152,6 +152,29 @@ describe('--experimental-detect-module', { concurrency: true }, () => { | 152 | 152 | strictEqual(signal, null); | 153 | 153 | }); | 154 | 154 | } | | 155 | + | | 156 | + it('should not hint wrong format in resolve hook', async () => { | | 157 | + let writeSync; | | 158 | + const { stdout, stderr, code, signal } = await spawnPromisified(process.execPath, [ | | 159 | + '--experimental-detect-module', | | 160 | + '--no-warnings', | | 161 | + '--loader', | | 162 | + `data:text/javascript,import { writeSync } from "node:fs"; export ${encodeURIComponent( | | 163 | + async function resolve(s, c, next) { | | 164 | + const result = await next(s, c); | | 165 | + writeSync(1, result.format + '\n'); | | 166 | + return result; | | 167 | + } | | 168 | + )}`, | | 169 | + fixtures.path('es-modules/package-without-type/noext-esm'), | | 170 | + ]); | | 171 | + | | 172 | + strictEqual(stderr, ''); | | 173 | + strictEqual(stdout, 'null\nexecuted\n'); | | 174 | + strictEqual(code, 0); | | 175 | + strictEqual(signal, null); | | 176 | + | | 177 | + }); | 155 | 178 | }); | 156 | 179 |
| 157 | 180 | describe('file input in a "type": "commonjs" package', { concurrency: true }, () => { | |
|