mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
esm: bypass CJS loader in default load under --default-type=module
This allows user to opt-out from using the monkey-patchable CJS loader, even to load CJS modules. PR-URL: https://github.com/nodejs/node/pull/50004 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
This commit is contained in:
parent
3e14cfbbcf
commit
0dfc59e4fc
|
|
@ -622,7 +622,8 @@ Omitting vs providing a `source` for `'commonjs'` has very different effects:
|
||||||
registered hooks. This behavior for nullish `source` is temporary — in the
|
registered hooks. This behavior for nullish `source` is temporary — in the
|
||||||
future, nullish `source` will not be supported.
|
future, nullish `source` will not be supported.
|
||||||
|
|
||||||
The Node.js internal `load` implementation, which is the value of `next` for the
|
When `node` is run with `--experimental-default-type=commonjs`, the Node.js
|
||||||
|
internal `load` implementation, which is the value of `next` for the
|
||||||
last hook in the `load` chain, returns `null` for `source` when `format` is
|
last hook in the `load` chain, returns `null` for `source` when `format` is
|
||||||
`'commonjs'` for backward compatibility. Here is an example hook that would
|
`'commonjs'` for backward compatibility. Here is an example hook that would
|
||||||
opt-in to using the non-default behavior:
|
opt-in to using the non-default behavior:
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ const policy = getOptionValue('--experimental-policy') ?
|
||||||
null;
|
null;
|
||||||
const experimentalNetworkImports =
|
const experimentalNetworkImports =
|
||||||
getOptionValue('--experimental-network-imports');
|
getOptionValue('--experimental-network-imports');
|
||||||
|
const defaultType =
|
||||||
|
getOptionValue('--experimental-default-type');
|
||||||
|
|
||||||
const { Buffer: { from: BufferFrom } } = require('buffer');
|
const { Buffer: { from: BufferFrom } } = require('buffer');
|
||||||
|
|
||||||
|
|
@ -140,7 +142,7 @@ async function defaultLoad(url, context = kEmptyObject) {
|
||||||
// Now that we have the source for the module, run `defaultGetFormat` again in case we detect ESM syntax.
|
// Now that we have the source for the module, run `defaultGetFormat` again in case we detect ESM syntax.
|
||||||
format ??= await defaultGetFormat(urlInstance, contextToPass);
|
format ??= await defaultGetFormat(urlInstance, contextToPass);
|
||||||
|
|
||||||
if (format === 'commonjs' && contextToPass !== context) {
|
if (format === 'commonjs' && contextToPass !== context && defaultType !== 'module') {
|
||||||
// For backward compatibility reasons, we need to discard the source in
|
// For backward compatibility reasons, we need to discard the source in
|
||||||
// order for the CJS loader to re-fetch it.
|
// order for the CJS loader to re-fetch it.
|
||||||
source = null;
|
source = null;
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,101 @@
|
||||||
import { spawnPromisified } from '../common/index.mjs';
|
import { spawnPromisified } from '../common/index.mjs';
|
||||||
import * as fixtures from '../common/fixtures.mjs';
|
import * as fixtures from '../common/fixtures.mjs';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { match, strictEqual } from 'node:assert';
|
import { deepStrictEqual, match, strictEqual } from 'node:assert';
|
||||||
|
|
||||||
describe('--experimental-default-type=module should not affect the interpretation of files with unknown extensions',
|
describe('--experimental-default-type=module', { concurrency: true }, () => {
|
||||||
{ concurrency: true }, () => {
|
describe('should not affect the interpretation of files with unknown extensions', { concurrency: true }, () => {
|
||||||
it('should error on an entry point with an unknown extension', async () => {
|
it('should error on an entry point with an unknown extension', async () => {
|
||||||
const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [
|
const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [
|
||||||
'--experimental-default-type=module',
|
'--experimental-default-type=module',
|
||||||
fixtures.path('es-modules/package-type-module/extension.unknown'),
|
fixtures.path('es-modules/package-type-module/extension.unknown'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
match(stderr, /ERR_UNKNOWN_FILE_EXTENSION/);
|
match(stderr, /ERR_UNKNOWN_FILE_EXTENSION/);
|
||||||
strictEqual(stdout, '');
|
strictEqual(stdout, '');
|
||||||
strictEqual(code, 1);
|
strictEqual(code, 1);
|
||||||
strictEqual(signal, null);
|
strictEqual(signal, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error on an import with an unknown extension', async () => {
|
it('should error on an import with an unknown extension', async () => {
|
||||||
const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [
|
const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [
|
||||||
'--experimental-default-type=module',
|
'--experimental-default-type=module',
|
||||||
fixtures.path('es-modules/package-type-module/imports-unknownext.mjs'),
|
fixtures.path('es-modules/package-type-module/imports-unknownext.mjs'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
match(stderr, /ERR_UNKNOWN_FILE_EXTENSION/);
|
match(stderr, /ERR_UNKNOWN_FILE_EXTENSION/);
|
||||||
strictEqual(stdout, '');
|
strictEqual(stdout, '');
|
||||||
strictEqual(code, 1);
|
strictEqual(code, 1);
|
||||||
strictEqual(signal, null);
|
strictEqual(signal, null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should affect CJS .js files (imported, required, entry points)', async () => {
|
||||||
|
const result = await spawnPromisified(process.execPath, [
|
||||||
|
'--experimental-default-type=module',
|
||||||
|
fixtures.path('es-modules/package-type-commonjs/echo-require-cache.js'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
deepStrictEqual(result, {
|
||||||
|
code: 0,
|
||||||
|
stderr: '',
|
||||||
|
stdout: 'undefined\n',
|
||||||
|
signal: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should affect .cjs files that are imported', async () => {
|
||||||
|
const result = await spawnPromisified(process.execPath, [
|
||||||
|
'--experimental-default-type=module',
|
||||||
|
'-e',
|
||||||
|
`import ${JSON.stringify(fixtures.fileURL('es-module-require-cache/echo.cjs'))}`,
|
||||||
|
]);
|
||||||
|
|
||||||
|
deepStrictEqual(result, {
|
||||||
|
code: 0,
|
||||||
|
stderr: '',
|
||||||
|
stdout: 'undefined\n',
|
||||||
|
signal: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should affect entry point .cjs files (with no hooks)', async () => {
|
||||||
|
const { stderr, stdout, code } = await spawnPromisified(process.execPath, [
|
||||||
|
'--experimental-default-type=module',
|
||||||
|
fixtures.path('es-module-require-cache/echo.cjs'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
strictEqual(stderr, '');
|
||||||
|
match(stdout, /^undefined\n$/);
|
||||||
|
strictEqual(code, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should affect entry point .cjs files (when any hooks is registered)', async () => {
|
||||||
|
const result = await spawnPromisified(process.execPath, [
|
||||||
|
'--experimental-default-type=module',
|
||||||
|
'--import',
|
||||||
|
'data:text/javascript,import{register}from"node:module";register("data:text/javascript,");',
|
||||||
|
fixtures.path('es-module-require-cache/echo.cjs'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
deepStrictEqual(result, {
|
||||||
|
code: 0,
|
||||||
|
stderr: '',
|
||||||
|
stdout: 'undefined\n',
|
||||||
|
signal: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not affect CJS from input-type', async () => {
|
||||||
|
const { stderr, stdout, code } = await spawnPromisified(process.execPath, [
|
||||||
|
'--experimental-default-type=module',
|
||||||
|
'--input-type=commonjs',
|
||||||
|
'-p',
|
||||||
|
'require.cache',
|
||||||
|
]);
|
||||||
|
|
||||||
|
strictEqual(stderr, '');
|
||||||
|
match(stdout, /^\[Object: null prototype\] \{\}\n$/);
|
||||||
|
strictEqual(code, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
1
test/fixtures/es-module-require-cache/echo.cjs
vendored
Normal file
1
test/fixtures/es-module-require-cache/echo.cjs
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
console.log(require.cache);
|
||||||
1
test/fixtures/es-modules/package-type-commonjs/echo-require-cache.js
vendored
Normal file
1
test/fixtures/es-modules/package-type-commonjs/echo-require-cache.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
console.log(require.cache);
|
||||||
Loading…
Reference in New Issue
Block a user