diff options
author | guybedford <guybedford@gmail.com> | 2018-08-28 17:28:46 +0200 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2019-03-27 15:52:11 -0400 |
commit | b1094dbe19f31f7a69ad16d193748f610b159073 (patch) | |
tree | bb623ea607ed54c27ef36ee9453f5623e19cbb90 /test | |
parent | 39141426d46a7e55d93ad2e8efa12ed86d223522 (diff) | |
download | node-new-b1094dbe19f31f7a69ad16d193748f610b159073.tar.gz |
esm: phase two of new esm implementation
This PR updates the current `--experimental-modules` implementation
based on the work of the modules team and reflects Phase 2 of our
new modules plan.
The largest differences from the current implementation include
* `packge.type` which can be either `module` or `commonjs`
- `type: "commonjs"`:
- `.js` is parsed as commonjs
- default for entry point without an extension is commonjs
- `type: "module"`:
- `.js` is parsed as esm
- does not support loading JSON or Native Module by default
- default for entry point without an extension is esm
* `--entry-type=[mode]`
- allows you set the type on entry point.
* A new file extension `.cjs`.
- this is specifically to support importing commonjs in the
`module` mode.
- this is only in the esm loader, the commonjs loader remains
untouched, but the extension will work in the old loader if you use
the full file path.
* `--es-module-specifier-resolution=[type]`
- options are `explicit` (default) and `node`
- by default our loader will not allow for optional extensions in
the import, the path for a module must include the extension if
there is one
- by default our loader will not allow for importing directories that
have an index file
- developers can use `--es-module-specifier-resolution=node` to
enable the commonjs specifier resolution algorithm
- This is not a “feature” but rather an implementation for
experimentation. It is expected to change before the flag is
removed
* `--experimental-json-loader`
- the only way to import json when `"type": "module"`
- when enable all `import 'thing.json'` will go through the
experimental loader independent of mode
- based on https://github.com/whatwg/html/issues/4315
* You can use `package.main` to set an entry point for a module
- the file extensions used in main will be resolved based on the
`type` of the module
Refs: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md
Refs: https://github.com/GeoffreyBooth/node-import-file-specifier-resolution-proposal
Refs: https://github.com/nodejs/modules/pull/180
Refs: https://github.com/nodejs/ecmascript-modules/pull/6
Refs: https://github.com/nodejs/ecmascript-modules/pull/12
Refs: https://github.com/nodejs/ecmascript-modules/pull/28
Refs: https://github.com/nodejs/modules/issues/255
Refs: https://github.com/whatwg/html/issues/4315
Refs: https://github.com/w3c/webcomponents/issues/770
Co-authored-by: Myles Borins <MylesBorins@google.com>
Co-authored-by: John-David Dalton <john.david.dalton@gmail.com>
Co-authored-by: Evan Plaice <evanplaice@gmail.com>
Co-authored-by: Geoffrey Booth <webmaster@geoffreybooth.com>
Co-authored-by: Michaël Zasso <targos@protonmail.com>
PR-URL: https://github.com/nodejs/node/pull/26745
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Ben Coe <bencoe@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Diffstat (limited to 'test')
100 files changed, 580 insertions, 145 deletions
diff --git a/test/addons/hello-world-esm/binding.cc b/test/addons/hello-world-esm/binding.cc deleted file mode 100644 index 02eecec099..0000000000 --- a/test/addons/hello-world-esm/binding.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include <node.h> -#include <v8.h> - -void Method(const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::Isolate* isolate = args.GetIsolate(); - args.GetReturnValue().Set(v8::String::NewFromUtf8( - isolate, "world", v8::NewStringType::kNormal).ToLocalChecked()); -} - -void init(v8::Local<v8::Object> exports) { - NODE_SET_METHOD(exports, "hello", Method); -} - -NODE_MODULE(NODE_GYP_MODULE_NAME, init) diff --git a/test/addons/hello-world-esm/binding.gyp b/test/addons/hello-world-esm/binding.gyp deleted file mode 100644 index 55fbe7050f..0000000000 --- a/test/addons/hello-world-esm/binding.gyp +++ /dev/null @@ -1,9 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'binding', - 'sources': [ 'binding.cc' ], - 'includes': ['../common.gypi'], - } - ] -} diff --git a/test/addons/hello-world-esm/test.js b/test/addons/hello-world-esm/test.js deleted file mode 100644 index d0faf65540..0000000000 --- a/test/addons/hello-world-esm/test.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; -const common = require('../../common'); - -const assert = require('assert'); -const { spawnSync } = require('child_process'); -const { copyFileSync } = require('fs'); -const { join } = require('path'); - -const buildDir = join(__dirname, 'build'); - -copyFileSync(join(buildDir, common.buildType, 'binding.node'), - join(buildDir, 'binding.node')); - -const result = spawnSync(process.execPath, - ['--experimental-modules', `${__dirname}/test.mjs`]); - -assert.ifError(result.error); -// TODO: Uncomment this once ESM is no longer experimental. -// assert.strictEqual(result.stderr.toString().trim(), ''); -assert.strictEqual(result.stdout.toString().trim(), 'binding.hello() = world'); diff --git a/test/addons/hello-world-esm/test.mjs b/test/addons/hello-world-esm/test.mjs deleted file mode 100644 index d98de5bf87..0000000000 --- a/test/addons/hello-world-esm/test.mjs +++ /dev/null @@ -1,6 +0,0 @@ -/* eslint-disable node-core/required-modules */ - -import assert from 'assert'; -import binding from './build/binding.node'; -assert.strictEqual(binding.hello(), 'world'); -console.log('binding.hello() =', binding.hello()); diff --git a/test/common/index.mjs b/test/common/index.mjs index de9119f37e..41592098eb 100644 --- a/test/common/index.mjs +++ b/test/common/index.mjs @@ -1,6 +1,15 @@ // Flags: --experimental-modules /* eslint-disable node-core/required-modules */ -import common from './index.js'; + +import { createRequireFromPath } from 'module'; +import { fileURLToPath as toPath } from 'url'; + +function createRequire(metaUrl) { + return createRequireFromPath(toPath(metaUrl)); +} + +const require = createRequire(import.meta.url); +const common = require('./index.js'); const { isMainThread, @@ -91,5 +100,6 @@ export { getBufferSources, disableCrashOnUnhandledRejection, getTTYfd, - runWithInvalidFD + runWithInvalidFD, + createRequire }; diff --git a/test/es-module/test-esm-basic-imports.mjs b/test/es-module/test-esm-basic-imports.mjs index 78a4106f94..d9bb22be0a 100644 --- a/test/es-module/test-esm-basic-imports.mjs +++ b/test/es-module/test-esm-basic-imports.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; import assert from 'assert'; import ok from '../fixtures/es-modules/test-esm-ok.mjs'; import okShebang from './test-esm-shebang.mjs'; diff --git a/test/es-module/test-esm-cyclic-dynamic-import.mjs b/test/es-module/test-esm-cyclic-dynamic-import.mjs index c8dfff919c..a207efc73e 100644 --- a/test/es-module/test-esm-cyclic-dynamic-import.mjs +++ b/test/es-module/test-esm-cyclic-dynamic-import.mjs @@ -1,3 +1,4 @@ // Flags: --experimental-modules -import '../common'; -import('./test-esm-cyclic-dynamic-import'); +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; +import('./test-esm-cyclic-dynamic-import.mjs'); diff --git a/test/es-module/test-esm-double-encoding.mjs b/test/es-module/test-esm-double-encoding.mjs index c81d0530d3..9366d4bd6b 100644 --- a/test/es-module/test-esm-double-encoding.mjs +++ b/test/es-module/test-esm-double-encoding.mjs @@ -1,6 +1,7 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; // Assert we can import files with `%` in their pathname. -import '../fixtures/es-modules/test-esm-double-encoding-native%2520.js'; +import '../fixtures/es-modules/test-esm-double-encoding-native%2520.mjs'; diff --git a/test/es-module/test-esm-dynamic-import.js b/test/es-module/test-esm-dynamic-import.js index b271d43c80..ca9c99007b 100644 --- a/test/es-module/test-esm-dynamic-import.js +++ b/test/es-module/test-esm-dynamic-import.js @@ -1,4 +1,5 @@ // Flags: --experimental-modules + 'use strict'; const common = require('../common'); const assert = require('assert'); @@ -17,7 +18,7 @@ function expectErrorProperty(result, propertyKey, value) { } function expectMissingModuleError(result) { - expectErrorProperty(result, 'code', 'MODULE_NOT_FOUND'); + expectErrorProperty(result, 'code', 'ERR_MODULE_NOT_FOUND'); } function expectOkNamespace(result) { diff --git a/test/es-module/test-esm-encoded-path.mjs b/test/es-module/test-esm-encoded-path.mjs index 365a425afa..2cabfdacff 100644 --- a/test/es-module/test-esm-encoded-path.mjs +++ b/test/es-module/test-esm-encoded-path.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; import assert from 'assert'; // ./test-esm-ok.mjs import ok from '../fixtures/es-modules/test-%65%73%6d-ok.mjs'; diff --git a/test/es-module/test-esm-error-cache.js b/test/es-module/test-esm-error-cache.js index 98244615ef..79f76357ec 100644 --- a/test/es-module/test-esm-error-cache.js +++ b/test/es-module/test-esm-error-cache.js @@ -1,11 +1,11 @@ -'use strict'; - // Flags: --experimental-modules +'use strict'; + require('../common'); const assert = require('assert'); -const file = '../fixtures/syntax/bad_syntax.js'; +const file = '../fixtures/syntax/bad_syntax.mjs'; let error; (async () => { diff --git a/test/es-module/test-esm-forbidden-globals.mjs b/test/es-module/test-esm-forbidden-globals.mjs index 4e777412a3..cf110ff290 100644 --- a/test/es-module/test-esm-forbidden-globals.mjs +++ b/test/es-module/test-esm-forbidden-globals.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; // eslint-disable-next-line no-undef if (typeof arguments !== 'undefined') { diff --git a/test/es-module/test-esm-import-meta.mjs b/test/es-module/test-esm-import-meta.mjs index c17e0e20d4..4c34b337fb 100644 --- a/test/es-module/test-esm-import-meta.mjs +++ b/test/es-module/test-esm-import-meta.mjs @@ -1,6 +1,7 @@ // Flags: --experimental-modules +/* eslint-disable node-core/required-modules */ -import '../common'; +import '../common/index.mjs'; import assert from 'assert'; assert.strictEqual(Object.getPrototypeOf(import.meta), null); diff --git a/test/es-module/test-esm-json-cache.mjs b/test/es-module/test-esm-json-cache.mjs new file mode 100644 index 0000000000..ecd27c5488 --- /dev/null +++ b/test/es-module/test-esm-json-cache.mjs @@ -0,0 +1,26 @@ +// Flags: --experimental-modules --experimental-json-modules +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; + +import { strictEqual, deepStrictEqual } from 'assert'; + +import { createRequireFromPath as createRequire } from 'module'; +import { fileURLToPath as fromURL } from 'url'; + +import mod from '../fixtures/es-modules/json-cache/mod.cjs'; +import another from '../fixtures/es-modules/json-cache/another.cjs'; +import test from '../fixtures/es-modules/json-cache/test.json'; + +const require = createRequire(fromURL(import.meta.url)); + +const modCjs = require('../fixtures/es-modules/json-cache/mod.cjs'); +const anotherCjs = require('../fixtures/es-modules/json-cache/another.cjs'); +const testCjs = require('../fixtures/es-modules/json-cache/test.json'); + +strictEqual(mod.one, 1); +strictEqual(another.one, 'zalgo'); +strictEqual(test.one, 'it comes'); + +deepStrictEqual(mod, modCjs); +deepStrictEqual(another, anotherCjs); +deepStrictEqual(test, testCjs); diff --git a/test/es-module/test-esm-json.mjs b/test/es-module/test-esm-json.mjs index a7146d19a9..b140d031ca 100644 --- a/test/es-module/test-esm-json.mjs +++ b/test/es-module/test-esm-json.mjs @@ -1,8 +1,9 @@ -// Flags: --experimental-modules -import '../common'; -import assert from 'assert'; -import ok from '../fixtures/es-modules/test-esm-ok.mjs'; -import json from '../fixtures/es-modules/json.json'; +// Flags: --experimental-modules --experimental-json-modules +/* eslint-disable node-core/required-modules */ -assert(ok); -assert.strictEqual(json.val, 42); +import '../common/index.mjs'; +import { strictEqual } from 'assert'; + +import secret from '../fixtures/experimental.json'; + +strictEqual(secret.ofLife, 42); diff --git a/test/es-module/test-esm-live-binding.mjs b/test/es-module/test-esm-live-binding.mjs index d151e004df..880a6c389b 100644 --- a/test/es-module/test-esm-live-binding.mjs +++ b/test/es-module/test-esm-live-binding.mjs @@ -1,6 +1,7 @@ // Flags: --experimental-modules +/* eslint-disable node-core/required-modules */ -import '../common'; +import '../common/index.mjs'; import assert from 'assert'; import fs, { readFile, readFileSync } from 'fs'; diff --git a/test/es-module/test-esm-loader-invalid-format.mjs b/test/es-module/test-esm-loader-invalid-format.mjs index f8714d4aa1..c3f3a87407 100644 --- a/test/es-module/test-esm-loader-invalid-format.mjs +++ b/test/es-module/test-esm-loader-invalid-format.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-invalid-format.mjs -import { expectsError, mustCall } from '../common'; +/* eslint-disable node-core/required-modules */ +import { expectsError, mustCall } from '../common/index.mjs'; import assert from 'assert'; import('../fixtures/es-modules/test-esm-ok.mjs') diff --git a/test/es-module/test-esm-loader-invalid-url.mjs b/test/es-module/test-esm-loader-invalid-url.mjs index 43971a2e6e..9cf17b2478 100644 --- a/test/es-module/test-esm-loader-invalid-url.mjs +++ b/test/es-module/test-esm-loader-invalid-url.mjs @@ -1,5 +1,7 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-invalid-url.mjs -import { expectsError, mustCall } from '../common'; +/* eslint-disable node-core/required-modules */ + +import { expectsError, mustCall } from '../common/index.mjs'; import assert from 'assert'; import('../fixtures/es-modules/test-esm-ok.mjs') diff --git a/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs b/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs index f2b37f7e8a..ab2da7adce 100644 --- a/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs +++ b/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs @@ -1,6 +1,7 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/missing-dynamic-instantiate-hook.mjs +/* eslint-disable node-core/required-modules */ -import { expectsError } from '../common'; +import { expectsError } from '../common/index.mjs'; import('test').catch(expectsError({ code: 'ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK', diff --git a/test/es-module/test-esm-loader-modulemap.js b/test/es-module/test-esm-loader-modulemap.js index 946d54ffaa..5493c6c47c 100644 --- a/test/es-module/test-esm-loader-modulemap.js +++ b/test/es-module/test-esm-loader-modulemap.js @@ -7,7 +7,7 @@ const common = require('../common'); const { URL } = require('url'); -const Loader = require('internal/modules/esm/loader'); +const { Loader } = require('internal/modules/esm/loader'); const ModuleMap = require('internal/modules/esm/module_map'); const ModuleJob = require('internal/modules/esm/module_job'); const createDynamicModule = require( diff --git a/test/es-module/test-esm-loader-search.js b/test/es-module/test-esm-loader-search.js index 0ca8990cb7..b5e0d8d656 100644 --- a/test/es-module/test-esm-loader-search.js +++ b/test/es-module/test-esm-loader-search.js @@ -5,13 +5,13 @@ const common = require('../common'); -const { search } = require('internal/modules/esm/default_resolve'); +const resolve = require('internal/modules/esm/default_resolve'); common.expectsError( - () => search('target', undefined), + () => resolve('target', undefined), { - code: 'ERR_MISSING_MODULE', + code: 'ERR_MODULE_NOT_FOUND', type: Error, - message: 'Cannot find module target' + message: /Cannot find package 'target'/ } ); diff --git a/test/es-module/test-esm-main-lookup.mjs b/test/es-module/test-esm-main-lookup.mjs index ca313a1d26..19c025beab 100644 --- a/test/es-module/test-esm-main-lookup.mjs +++ b/test/es-module/test-esm-main-lookup.mjs @@ -1,6 +1,26 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; import assert from 'assert'; -import main from '../fixtures/es-modules/pjson-main'; -assert.strictEqual(main, 'main'); +async function main() { + let mod; + try { + mod = await import('../fixtures/es-modules/pjson-main'); + } catch (e) { + assert.strictEqual(e.code, 'ERR_MODULE_NOT_FOUND'); + } + + assert.strictEqual(mod, undefined); + + try { + mod = await import('../fixtures/es-modules/pjson-main/main.mjs'); + } catch (e) { + console.log(e); + assert.fail(); + } + + assert.strictEqual(mod.main, 'main'); +} + +main(); diff --git a/test/es-module/test-esm-named-exports.mjs b/test/es-module/test-esm-named-exports.mjs index 3aae9230de..e235f598cb 100644 --- a/test/es-module/test-esm-named-exports.mjs +++ b/test/es-module/test-esm-named-exports.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; import { readFile } from 'fs'; import assert from 'assert'; import ok from '../fixtures/es-modules/test-esm-ok.mjs'; diff --git a/test/es-module/test-esm-namespace.mjs b/test/es-module/test-esm-namespace.mjs index da1286d0f4..38b7ef12d5 100644 --- a/test/es-module/test-esm-namespace.mjs +++ b/test/es-module/test-esm-namespace.mjs @@ -1,5 +1,7 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ + +import '../common/index.mjs'; import * as fs from 'fs'; import assert from 'assert'; import Module from 'module'; diff --git a/test/es-module/test-esm-no-extension.js b/test/es-module/test-esm-no-extension.js new file mode 100644 index 0000000000..3e9ffb2bbc --- /dev/null +++ b/test/es-module/test-esm-no-extension.js @@ -0,0 +1,35 @@ +'use strict'; + +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const { spawn } = require('child_process'); +const assert = require('assert'); + +const entry = fixtures.path('/es-modules/noext-esm'); + +// Run a module that does not have extension +// This is to ensure the --entry-type works as expected + +const child = spawn(process.execPath, [ + '--experimental-modules', + '--entry-type=module', + entry +]); + +let stderr = ''; +child.stderr.setEncoding('utf8'); +child.stderr.on('data', (data) => { + stderr += data; +}); +let stdout = ''; +child.stdout.setEncoding('utf8'); +child.stdout.on('data', (data) => { + stdout += data; +}); +child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(stdout, 'executed\n'); + assert.strictEqual(stderr, `(node:${child.pid}) ` + + 'ExperimentalWarning: The ESM module loader is experimental.\n'); +})); diff --git a/test/es-module/test-esm-preserve-symlinks-not-found.mjs b/test/es-module/test-esm-preserve-symlinks-not-found.mjs index 5119957bae..b5be2d7e63 100644 --- a/test/es-module/test-esm-preserve-symlinks-not-found.mjs +++ b/test/es-module/test-esm-preserve-symlinks-not-found.mjs @@ -1,3 +1,3 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs /* eslint-disable node-core/required-modules */ -import './not-found'; +import './not-found.mjs'; diff --git a/test/es-module/test-esm-process.mjs b/test/es-module/test-esm-process.mjs index ea9b4b4936..3a23573d33 100644 --- a/test/es-module/test-esm-process.mjs +++ b/test/es-module/test-esm-process.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; import assert from 'assert'; import process from 'process'; diff --git a/test/es-module/test-esm-require-cache.mjs b/test/es-module/test-esm-require-cache.mjs index ff32cde36f..09030e0578 100644 --- a/test/es-module/test-esm-require-cache.mjs +++ b/test/es-module/test-esm-require-cache.mjs @@ -1,7 +1,12 @@ // Flags: --experimental-modules -import '../common'; -import '../fixtures/es-module-require-cache/preload.js'; -import '../fixtures/es-module-require-cache/counter.js'; +/* eslint-disable node-core/required-modules */ +import { createRequire } from '../common/index.mjs'; import assert from 'assert'; +// +const require = createRequire(import.meta.url); + +require('../fixtures/es-module-require-cache/preload.js'); +require('../fixtures/es-module-require-cache/counter.js'); + assert.strictEqual(global.counter, 1); delete global.counter; diff --git a/test/es-module/test-esm-shared-loader-dep.mjs b/test/es-module/test-esm-shared-loader-dep.mjs index 5c274d835c..b8953ab1ec 100644 --- a/test/es-module/test-esm-shared-loader-dep.mjs +++ b/test/es-module/test-esm-shared-loader-dep.mjs @@ -1,7 +1,11 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-shared-dep.mjs -import '../common'; +/* eslint-disable node-core/required-modules */ +import { createRequire } from '../common/index.mjs'; + import assert from 'assert'; import '../fixtures/es-modules/test-esm-ok.mjs'; -import dep from '../fixtures/es-module-loaders/loader-dep.js'; -assert.strictEqual(dep.format, 'esm'); +const require = createRequire(import.meta.url); +const dep = require('../fixtures/es-module-loaders/loader-dep.js'); + +assert.strictEqual(dep.format, 'module'); diff --git a/test/es-module/test-esm-shebang.mjs b/test/es-module/test-esm-shebang.mjs index d5faace479..486e04dade 100644 --- a/test/es-module/test-esm-shebang.mjs +++ b/test/es-module/test-esm-shebang.mjs @@ -1,6 +1,7 @@ #! }]) // isn't js // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; const isJs = true; export default isJs; diff --git a/test/es-module/test-esm-snapshot.mjs b/test/es-module/test-esm-snapshot.mjs index 3d4b44bbdd..3997e24ed7 100644 --- a/test/es-module/test-esm-snapshot.mjs +++ b/test/es-module/test-esm-snapshot.mjs @@ -1,7 +1,8 @@ // Flags: --experimental-modules -import '../common'; -import '../fixtures/es-modules/esm-snapshot-mutator'; -import one from '../fixtures/es-modules/esm-snapshot'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; +import '../fixtures/es-modules/esm-snapshot-mutator.js'; +import one from '../fixtures/es-modules/esm-snapshot.js'; import assert from 'assert'; assert.strictEqual(one, 1); diff --git a/test/es-module/test-esm-specifiers.mjs b/test/es-module/test-esm-specifiers.mjs new file mode 100644 index 0000000000..0c5e1ac04a --- /dev/null +++ b/test/es-module/test-esm-specifiers.mjs @@ -0,0 +1,35 @@ +// Flags: --experimental-modules --es-module-specifier-resolution=node +import { mustNotCall } from '../common'; +import assert from 'assert'; + +// commonJS index.js +import commonjs from '../fixtures/es-module-specifiers/package-type-commonjs'; +// esm index.js +import module from '../fixtures/es-module-specifiers/package-type-module'; +// Notice the trailing slash +import success, { explicit, implicit, implicitModule, getImplicitCommonjs } + from '../fixtures/es-module-specifiers/'; + +assert.strictEqual(commonjs, 'commonjs'); +assert.strictEqual(module, 'module'); +assert.strictEqual(success, 'success'); +assert.strictEqual(explicit, 'esm'); +assert.strictEqual(implicit, 'esm'); +assert.strictEqual(implicitModule, 'esm'); + +async function main() { + try { + await import('../fixtures/es-module-specifiers/do-not-exist.js'); + } catch (e) { + // Files that do not exist should throw + assert.strictEqual(e.name, 'Error'); + } + try { + await getImplicitCommonjs(); + } catch (e) { + // Legacy loader cannot resolve .mjs automatically from main + assert.strictEqual(e.name, 'Error'); + } +} + +main().catch(mustNotCall); diff --git a/test/es-module/test-esm-symlink-main.js b/test/es-module/test-esm-symlink-main.js index f7631ef2e5..871180f5cc 100644 --- a/test/es-module/test-esm-symlink-main.js +++ b/test/es-module/test-esm-symlink-main.js @@ -9,7 +9,7 @@ const fs = require('fs'); tmpdir.refresh(); const realPath = path.resolve(__dirname, '../fixtures/es-modules/symlink.mjs'); -const symlinkPath = path.resolve(tmpdir.path, 'symlink.js'); +const symlinkPath = path.resolve(tmpdir.path, 'symlink.mjs'); try { fs.symlinkSync(realPath, symlinkPath); diff --git a/test/es-module/test-esm-symlink-type.js b/test/es-module/test-esm-symlink-type.js new file mode 100644 index 0000000000..6159ebecd1 --- /dev/null +++ b/test/es-module/test-esm-symlink-type.js @@ -0,0 +1,77 @@ +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const path = require('path'); +const assert = require('assert'); +const exec = require('child_process').execFile; +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); +const tmpDir = tmpdir.path; + +// Check that running the symlink executes the target as the correct type +const symlinks = [ + { + source: 'extensionless-symlink-to-mjs-file', + target: fixtures.path('es-modules/mjs-file.mjs'), + prints: '.mjs file', + errorsWithPreserveSymlinksMain: false + }, { + source: 'extensionless-symlink-to-cjs-file', + target: fixtures.path('es-modules/cjs-file.cjs'), + prints: '.cjs file', + errorsWithPreserveSymlinksMain: false + }, { + source: 'extensionless-symlink-to-file-in-module-scope', + target: fixtures.path('es-modules/package-type-module/index.js'), + prints: 'package-type-module', + // The package scope of the symlinks' sources is commonjs, and this + // symlink's target is a .js file in a module scope, so when the scope + // is evaluated based on the source (commonjs) this esm file should error + errorsWithPreserveSymlinksMain: true + }, { + source: 'extensionless-symlink-to-file-in-explicit-commonjs-scope', + target: fixtures.path('es-modules/package-type-commonjs/index.js'), + prints: 'package-type-commonjs', + errorsWithPreserveSymlinksMain: false + }, { + source: 'extensionless-symlink-to-file-in-implicit-commonjs-scope', + target: fixtures.path('es-modules/package-without-type/index.js'), + prints: 'package-without-type', + errorsWithPreserveSymlinksMain: false + } +]; + +symlinks.forEach((symlink) => { + const mainPath = path.join(tmpDir, symlink.source); + fs.symlinkSync(symlink.target, mainPath); + + const flags = [ + '--experimental-modules', + '--experimental-modules --preserve-symlinks-main' + ]; + flags.forEach((nodeOptions) => { + const opts = { + env: Object.assign({}, process.env, { NODE_OPTIONS: nodeOptions }) + }; + exec(process.execPath, [mainPath], opts, common.mustCall( + (err, stdout) => { + if (nodeOptions.includes('--preserve-symlinks-main')) { + if (symlink.errorsWithPreserveSymlinksMain && + err.toString().includes('Error')) return; + else if (!symlink.errorsWithPreserveSymlinksMain && + stdout.includes(symlink.prints)) return; + assert.fail(`For ${JSON.stringify(symlink)}, ${ + (symlink.errorsWithPreserveSymlinksMain) ? + 'failed to error' : 'errored unexpectedly' + } with --preserve-symlinks-main`); + } else { + if (stdout.includes(symlink.prints)) return; + assert.fail(`For ${JSON.stringify(symlink)}, failed to find ` + + `${symlink.prints} in: <\n${stdout}\n>`); + } + } + )); + }); +}); diff --git a/test/es-module/test-esm-symlink.js b/test/es-module/test-esm-symlink.js index 232925a52e..9b9eb98cd9 100644 --- a/test/es-module/test-esm-symlink.js +++ b/test/es-module/test-esm-symlink.js @@ -12,8 +12,8 @@ const tmpDir = tmpdir.path; const entry = path.join(tmpDir, 'entry.mjs'); const real = path.join(tmpDir, 'index.mjs'); -const link_absolute_path = path.join(tmpDir, 'absolute'); -const link_relative_path = path.join(tmpDir, 'relative'); +const link_absolute_path = path.join(tmpDir, 'absolute.mjs'); +const link_relative_path = path.join(tmpDir, 'relative.mjs'); const link_ignore_extension = path.join(tmpDir, 'ignore_extension.json'); const link_directory = path.join(tmpDir, 'directory'); @@ -22,15 +22,13 @@ fs.writeFileSync(real, 'export default [];'); fs.writeFileSync(entry, ` import assert from 'assert'; import real from './index.mjs'; -import absolute from './absolute'; -import relative from './relative'; +import absolute from './absolute.mjs'; +import relative from './relative.mjs'; import ignoreExtension from './ignore_extension.json'; -import directory from './directory'; assert.strictEqual(absolute, real); assert.strictEqual(relative, real); assert.strictEqual(ignoreExtension, real); -assert.strictEqual(directory, real); `); try { diff --git a/test/es-module/test-esm-throw-undefined.mjs b/test/es-module/test-esm-throw-undefined.mjs index 541127eee5..97e917da5e 100644 --- a/test/es-module/test-esm-throw-undefined.mjs +++ b/test/es-module/test-esm-throw-undefined.mjs @@ -1,11 +1,13 @@ // Flags: --experimental-modules -import '../common'; +/* eslint-disable node-core/required-modules */ + +import '../common/index.mjs'; import assert from 'assert'; async function doTest() { await assert.rejects( async () => { - await import('../fixtures/es-module-loaders/throw-undefined'); + await import('../fixtures/es-module-loaders/throw-undefined.mjs'); }, (e) => e === undefined ); diff --git a/test/es-module/test-esm-type-flag-errors.js b/test/es-module/test-esm-type-flag-errors.js new file mode 100644 index 0000000000..612ada584d --- /dev/null +++ b/test/es-module/test-esm-type-flag-errors.js @@ -0,0 +1,53 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const exec = require('child_process').execFile; + +const mjsFile = require.resolve('../fixtures/es-modules/mjs-file.mjs'); +const cjsFile = require.resolve('../fixtures/es-modules/cjs-file.cjs'); +const packageWithoutTypeMain = + require.resolve('../fixtures/es-modules/package-without-type/index.js'); +const packageTypeCommonJsMain = + require.resolve('../fixtures/es-modules/package-type-commonjs/index.js'); +const packageTypeModuleMain = + require.resolve('../fixtures/es-modules/package-type-module/index.js'); + +// Check that running `node` without options works +expect('', mjsFile, '.mjs file'); +expect('', cjsFile, '.cjs file'); +expect('', packageTypeModuleMain, 'package-type-module'); +expect('', packageTypeCommonJsMain, 'package-type-commonjs'); +expect('', packageWithoutTypeMain, 'package-without-type'); + +// Check that running with --entry-type and no package.json "type" works +expect('--entry-type=commonjs', packageWithoutTypeMain, 'package-without-type'); +expect('--entry-type=module', packageWithoutTypeMain, 'package-without-type'); + +// Check that running with conflicting --entry-type flags throws errors +expect('--entry-type=commonjs', mjsFile, 'ERR_ENTRY_TYPE_MISMATCH', true); +expect('--entry-type=module', cjsFile, 'ERR_ENTRY_TYPE_MISMATCH', true); +expect('--entry-type=commonjs', packageTypeModuleMain, + 'ERR_ENTRY_TYPE_MISMATCH', true); +expect('--entry-type=module', packageTypeCommonJsMain, + 'ERR_ENTRY_TYPE_MISMATCH', true); + +function expect(opt = '', inputFile, want, wantsError = false) { + // TODO: Remove when --experimental-modules is unflagged + opt = `--experimental-modules ${opt}`; + const argv = [inputFile]; + const opts = { + env: Object.assign({}, process.env, { NODE_OPTIONS: opt }), + maxBuffer: 1e6, + }; + exec(process.execPath, argv, opts, common.mustCall((err, stdout, stderr) => { + if (wantsError) { + stdout = stderr; + } else { + assert.ifError(err); + } + if (stdout.includes(want)) return; + + const o = JSON.stringify(opt); + assert.fail(`For ${o}, failed to find ${want} in: <\n${stdout}\n>`); + })); +} diff --git a/test/es-module/test-esm-type-flag.mjs b/test/es-module/test-esm-type-flag.mjs new file mode 100644 index 0000000000..2f5d0b626a --- /dev/null +++ b/test/es-module/test-esm-type-flag.mjs @@ -0,0 +1,11 @@ +// Flags: --experimental-modules --entry-type=module +/* eslint-disable node-core/required-modules */ +import cjs from '../fixtures/baz.js'; +import '../common/index.mjs'; +import { message } from '../fixtures/es-modules/message.mjs'; +import assert from 'assert'; + +// Assert we loaded esm dependency as ".js" in this mode +assert.strictEqual(message, 'A message'); +// Assert we loaded CommonJS dependency +assert.strictEqual(cjs, 'perhaps I work'); diff --git a/test/fixtures/es-module-loaders/example-loader.mjs b/test/fixtures/es-module-loaders/example-loader.mjs index a7cf276d4a..d8e0ddcba3 100644 --- a/test/fixtures/es-module-loaders/example-loader.mjs +++ b/test/fixtures/es-module-loaders/example-loader.mjs @@ -29,6 +29,6 @@ export function resolve(specifier, parentModuleURL = baseURL /*, defaultResolve } return { url: resolved.href, - format: 'esm' + format: 'module' }; } diff --git a/test/fixtures/es-module-loaders/js-loader.mjs b/test/fixtures/es-module-loaders/js-loader.mjs index 2ac959a464..4b8a0fc365 100644 --- a/test/fixtures/es-module-loaders/js-loader.mjs +++ b/test/fixtures/es-module-loaders/js-loader.mjs @@ -15,6 +15,6 @@ export function resolve (specifier, base = baseURL) { const url = new URL(specifier, base).href; return { url, - format: 'esm' + format: 'module' }; } diff --git a/test/fixtures/es-module-loaders/loader-dep.js b/test/fixtures/es-module-loaders/loader-dep.js index cf821afec1..c8154ac5db 100644 --- a/test/fixtures/es-module-loaders/loader-dep.js +++ b/test/fixtures/es-module-loaders/loader-dep.js @@ -1 +1 @@ -exports.format = 'esm'; +exports.format = 'module'; diff --git a/test/fixtures/es-module-loaders/loader-invalid-url.mjs b/test/fixtures/es-module-loaders/loader-invalid-url.mjs index 12efbb5021..f653155899 100644 --- a/test/fixtures/es-module-loaders/loader-invalid-url.mjs +++ b/test/fixtures/es-module-loaders/loader-invalid-url.mjs @@ -1,3 +1,4 @@ +/* eslint-disable node-core/required-modules */ export async function resolve(specifier, parentModuleURL, defaultResolve) { if (parentModuleURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') { return { diff --git a/test/fixtures/es-module-loaders/loader-shared-dep.mjs b/test/fixtures/es-module-loaders/loader-shared-dep.mjs index 1a19e4c892..3acafcce1e 100644 --- a/test/fixtures/es-module-loaders/loader-shared-dep.mjs +++ b/test/fixtures/es-module-loaders/loader-shared-dep.mjs @@ -1,7 +1,11 @@ -import dep from './loader-dep.js'; import assert from 'assert'; +import {createRequire} from '../../common/index.mjs'; + +const require = createRequire(import.meta.url); +const dep = require('./loader-dep.js'); + export function resolve(specifier, base, defaultResolve) { - assert.strictEqual(dep.format, 'esm'); + assert.strictEqual(dep.format, 'module'); return defaultResolve(specifier, base); } diff --git a/test/fixtures/es-module-loaders/loader-with-dep.mjs b/test/fixtures/es-module-loaders/loader-with-dep.mjs index 944e6e438c..5afd3b2e21 100644 --- a/test/fixtures/es-module-loaders/loader-with-dep.mjs +++ b/test/fixtures/es-module-loaders/loader-with-dep.mjs @@ -1,4 +1,8 @@ -import dep from './loader-dep.js'; +import {createRequire} from '../../common/index.mjs'; + +const require = createRequire(import.meta.url); +const dep = require('./loader-dep.js'); + export function resolve (specifier, base, defaultResolve) { return { url: defaultResolve(specifier, base).url, diff --git a/test/fixtures/es-module-loaders/not-found-assert-loader.mjs b/test/fixtures/es-module-loaders/not-found-assert-loader.mjs index d15f294fe6..d3eebcd47e 100644 --- a/test/fixtures/es-module-loaders/not-found-assert-loader.mjs +++ b/test/fixtures/es-module-loaders/not-found-assert-loader.mjs @@ -12,11 +12,11 @@ export async function resolve (specifier, base, defaultResolve) { await defaultResolve(specifier, base); } catch (e) { - assert.strictEqual(e.code, 'MODULE_NOT_FOUND'); + assert.strictEqual(e.code, 'ERR_MODULE_NOT_FOUND'); return { format: 'builtin', url: 'fs' }; } - assert.fail(`Module resolution for ${specifier} should be throw MODULE_NOT_FOUND`); + assert.fail(`Module resolution for ${specifier} should be throw ERR_MODULE_NOT_FOUND`); } diff --git a/test/fixtures/es-module-loaders/syntax-error-import.mjs b/test/fixtures/es-module-loaders/syntax-error-import.mjs index 9cad68c7ce..3a6bc5effc 100644 --- a/test/fixtures/es-module-loaders/syntax-error-import.mjs +++ b/test/fixtures/es-module-loaders/syntax-error-import.mjs @@ -1 +1 @@ -import { foo, notfound } from './module-named-exports'; +import { foo, notfound } from './module-named-exports.mjs'; diff --git a/test/fixtures/es-module-loaders/throw-undefined.mjs b/test/fixtures/es-module-loaders/throw-undefined.mjs index f062276767..0349ae112d 100644 --- a/test/fixtures/es-module-loaders/throw-undefined.mjs +++ b/test/fixtures/es-module-loaders/throw-undefined.mjs @@ -1,3 +1,4 @@ 'use strict'; +/* eslint-disable node-core/required-modules */ throw undefined; diff --git a/test/fixtures/es-module-specifiers/index.mjs b/test/fixtures/es-module-specifiers/index.mjs new file mode 100644 index 0000000000..2be7048513 --- /dev/null +++ b/test/fixtures/es-module-specifiers/index.mjs @@ -0,0 +1,10 @@ +import explicit from 'explicit-main'; +import implicit from 'implicit-main'; +import implicitModule from 'implicit-main-type-module'; + +function getImplicitCommonjs () { + return import('implicit-main-type-commonjs'); +} + +export {explicit, implicit, implicitModule, getImplicitCommonjs}; +export default 'success'; diff --git a/test/fixtures/es-module-specifiers/node_modules/explicit-main/entry.mjs b/test/fixtures/es-module-specifiers/node_modules/explicit-main/entry.mjs new file mode 100644 index 0000000000..914e3a97d5 --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/explicit-main/entry.mjs @@ -0,0 +1 @@ +export default 'esm'; diff --git a/test/fixtures/es-module-specifiers/node_modules/explicit-main/package.json b/test/fixtures/es-module-specifiers/node_modules/explicit-main/package.json new file mode 100644 index 0000000000..e9457582ac --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/explicit-main/package.json @@ -0,0 +1,3 @@ +{ + "main": "entry.mjs" +}
\ No newline at end of file diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-commonjs/entry.mjs b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-commonjs/entry.mjs new file mode 100644 index 0000000000..914e3a97d5 --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-commonjs/entry.mjs @@ -0,0 +1 @@ +export default 'esm'; diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-commonjs/package.json b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-commonjs/package.json new file mode 100644 index 0000000000..9093a7cc14 --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-commonjs/package.json @@ -0,0 +1,4 @@ +{ + "main": "entry", + "type": "commonjs" +} diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js new file mode 100644 index 0000000000..5d7af588fd --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.js @@ -0,0 +1 @@ +export default 'nope'; diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.mjs b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.mjs new file mode 100644 index 0000000000..914e3a97d5 --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/entry.mjs @@ -0,0 +1 @@ +export default 'esm'; diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/package.json b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/package.json new file mode 100644 index 0000000000..5710280bad --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main-type-module/package.json @@ -0,0 +1,4 @@ +{ + "main": "entry", + "type": "module" +} diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main/entry.js b/test/fixtures/es-module-specifiers/node_modules/implicit-main/entry.js new file mode 100644 index 0000000000..b2825bd3c9 --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main/entry.js @@ -0,0 +1 @@ +module.exports = 'cjs'; diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main/entry.mjs b/test/fixtures/es-module-specifiers/node_modules/implicit-main/entry.mjs new file mode 100644 index 0000000000..914e3a97d5 --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main/entry.mjs @@ -0,0 +1 @@ +export default 'esm'; diff --git a/test/fixtures/es-module-specifiers/node_modules/implicit-main/package.json b/test/fixtures/es-module-specifiers/node_modules/implicit-main/package.json new file mode 100644 index 0000000000..5c07cf41bb --- /dev/null +++ b/test/fixtures/es-module-specifiers/node_modules/implicit-main/package.json @@ -0,0 +1,3 @@ +{ + "main": "entry" +} diff --git a/test/fixtures/es-module-specifiers/package-type-commonjs/a.js b/test/fixtures/es-module-specifiers/package-type-commonjs/a.js new file mode 100644 index 0000000000..2e7700bc63 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-commonjs/a.js @@ -0,0 +1 @@ +module.exports = 'a'; diff --git a/test/fixtures/es-module-specifiers/package-type-commonjs/b.mjs b/test/fixtures/es-module-specifiers/package-type-commonjs/b.mjs new file mode 100644 index 0000000000..137b8ce642 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-commonjs/b.mjs @@ -0,0 +1 @@ +export const b = 'b'; diff --git a/test/fixtures/es-module-specifiers/package-type-commonjs/c.cjs b/test/fixtures/es-module-specifiers/package-type-commonjs/c.cjs new file mode 100644 index 0000000000..2d5312952f --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-commonjs/c.cjs @@ -0,0 +1,5 @@ +module.exports = { + one: 1, + two: 2, + three: 3 +}; diff --git a/test/fixtures/es-module-specifiers/package-type-commonjs/index.mjs b/test/fixtures/es-module-specifiers/package-type-commonjs/index.mjs new file mode 100644 index 0000000000..ef2b30b19b --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-commonjs/index.mjs @@ -0,0 +1,21 @@ +// js file that is common.js +import a from './a.js'; +// ESM with named export +import {b} from './b.mjs'; +// import 'c.cjs'; +import cjs from './c.cjs'; +// proves cross boundary fun bits +import jsAsEsm from '../package-type-module/a.js'; + +// named export from core +import {strictEqual, deepStrictEqual} from 'assert'; + +strictEqual(a, jsAsEsm); +strictEqual(b, 'b'); +deepStrictEqual(cjs, { + one: 1, + two: 2, + three: 3 +}); + +export default 'commonjs'; diff --git a/test/fixtures/es-module-specifiers/package-type-commonjs/package.json b/test/fixtures/es-module-specifiers/package-type-commonjs/package.json new file mode 100644 index 0000000000..5bbefffbab --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/test/fixtures/es-module-specifiers/package-type-module/a.js b/test/fixtures/es-module-specifiers/package-type-module/a.js new file mode 100644 index 0000000000..90bd54cd7f --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-module/a.js @@ -0,0 +1 @@ +export default 'a' diff --git a/test/fixtures/es-module-specifiers/package-type-module/b.mjs b/test/fixtures/es-module-specifiers/package-type-module/b.mjs new file mode 100644 index 0000000000..137b8ce642 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-module/b.mjs @@ -0,0 +1 @@ +export const b = 'b'; diff --git a/test/fixtures/es-module-specifiers/package-type-module/c.cjs b/test/fixtures/es-module-specifiers/package-type-module/c.cjs new file mode 100644 index 0000000000..2d5312952f --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-module/c.cjs @@ -0,0 +1,5 @@ +module.exports = { + one: 1, + two: 2, + three: 3 +}; diff --git a/test/fixtures/es-module-specifiers/package-type-module/index.js b/test/fixtures/es-module-specifiers/package-type-module/index.js new file mode 100644 index 0000000000..a8baacb7c9 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-module/index.js @@ -0,0 +1,21 @@ +// ESM with only default +import a from './a.js'; +// ESM with named export +import {b} from './b.mjs'; +// import 'c.cjs'; +import cjs from './c.cjs'; +// import across boundaries +import jsAsCjs from '../package-type-commonjs/a.js' + +// named export from core +import {strictEqual, deepStrictEqual} from 'assert'; + +strictEqual(a, jsAsCjs); +strictEqual(b, 'b'); +deepStrictEqual(cjs, { + one: 1, + two: 2, + three: 3 +}); + +export default 'module'; diff --git a/test/fixtures/es-module-specifiers/package-type-module/package.json b/test/fixtures/es-module-specifiers/package-type-module/package.json new file mode 100644 index 0000000000..3dbc1ca591 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package-type-module/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/fixtures/es-module-specifiers/package.json b/test/fixtures/es-module-specifiers/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/test/fixtures/es-module-specifiers/package.json @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/test/fixtures/es-modules/cjs-file.cjs b/test/fixtures/es-modules/cjs-file.cjs new file mode 100644 index 0000000000..3d0637686e --- /dev/null +++ b/test/fixtures/es-modules/cjs-file.cjs @@ -0,0 +1 @@ +console.log('.cjs file'); diff --git a/test/fixtures/es-modules/json-cache/another.cjs b/test/fixtures/es-modules/json-cache/another.cjs new file mode 100644 index 0000000000..8c8e9f1c0f --- /dev/null +++ b/test/fixtures/es-modules/json-cache/another.cjs @@ -0,0 +1,7 @@ +const test = require('./test.json'); + +module.exports = { + ...test +}; + +test.one = 'it comes'; diff --git a/test/fixtures/es-modules/json-cache/mod.cjs b/test/fixtures/es-modules/json-cache/mod.cjs new file mode 100644 index 0000000000..047cfb24a4 --- /dev/null +++ b/test/fixtures/es-modules/json-cache/mod.cjs @@ -0,0 +1,7 @@ +const test = require('./test.json'); + +module.exports = { + ...test +}; + +test.one = 'zalgo'; diff --git a/test/fixtures/es-modules/json-cache/test.json b/test/fixtures/es-modules/json-cache/test.json new file mode 100644 index 0000000000..120cbb2840 --- /dev/null +++ b/test/fixtures/es-modules/json-cache/test.json @@ -0,0 +1,5 @@ +{ + "one": 1, + "two": 2, + "three": 3 +} diff --git a/test/fixtures/es-modules/json.json b/test/fixtures/es-modules/json.json deleted file mode 100644 index 8288d42e2b..0000000000 --- a/test/fixtures/es-modules/json.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "val": 42 -} diff --git a/test/fixtures/es-modules/loop.mjs b/test/fixtures/es-modules/loop.mjs index 1b5cab10ed..3d2ddd2eb7 100644 --- a/test/fixtures/es-modules/loop.mjs +++ b/test/fixtures/es-modules/loop.mjs @@ -1,4 +1,4 @@ -import { message } from './message'; +import { message } from './message.mjs'; var t = 1; var k = 1; diff --git a/test/fixtures/es-modules/mjs-file.mjs b/test/fixtures/es-modules/mjs-file.mjs new file mode 100644 index 0000000000..489d4ab570 --- /dev/null +++ b/test/fixtures/es-modules/mjs-file.mjs @@ -0,0 +1 @@ +console.log('.mjs file'); diff --git a/test/fixtures/es-modules/noext-esm b/test/fixtures/es-modules/noext-esm new file mode 100644 index 0000000000..251d6e538a --- /dev/null +++ b/test/fixtures/es-modules/noext-esm @@ -0,0 +1,2 @@ +export default 'module'; +console.log('executed'); diff --git a/test/fixtures/es-modules/package-type-commonjs/index.js b/test/fixtures/es-modules/package-type-commonjs/index.js new file mode 100644 index 0000000000..009431d851 --- /dev/null +++ b/test/fixtures/es-modules/package-type-commonjs/index.js @@ -0,0 +1,3 @@ +const identifier = 'package-type-commonjs'; +console.log(identifier); +module.exports = identifier; diff --git a/test/fixtures/es-modules/package-type-commonjs/package.json b/test/fixtures/es-modules/package-type-commonjs/package.json new file mode 100644 index 0000000000..4aaa4a2388 --- /dev/null +++ b/test/fixtures/es-modules/package-type-commonjs/package.json @@ -0,0 +1,4 @@ +{ + "type": "commonjs", + "main": "index.js" +} diff --git a/test/fixtures/es-modules/package-type-module/index.js b/test/fixtures/es-modules/package-type-module/index.js new file mode 100644 index 0000000000..12aba970ef --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/index.js @@ -0,0 +1,3 @@ +const identifier = 'package-type-module'; +console.log(identifier); +export default identifier; diff --git a/test/fixtures/es-modules/package-type-module/package.json b/test/fixtures/es-modules/package-type-module/package.json new file mode 100644 index 0000000000..07aec65d5a --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "main": "index.js" +} diff --git a/test/fixtures/es-modules/package-without-type/index.js b/test/fixtures/es-modules/package-without-type/index.js new file mode 100644 index 0000000000..a547216cb0 --- /dev/null +++ b/test/fixtures/es-modules/package-without-type/index.js @@ -0,0 +1,3 @@ +const identifier = 'package-without-type'; +console.log(identifier); +module.exports = identifier; diff --git a/test/fixtures/es-modules/package-without-type/package.json b/test/fixtures/es-modules/package-without-type/package.json new file mode 100644 index 0000000000..14ab704d8f --- /dev/null +++ b/test/fixtures/es-modules/package-without-type/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/test/fixtures/es-modules/pjson-main/main.js b/test/fixtures/es-modules/pjson-main/main.js deleted file mode 100644 index dfdd47b877..0000000000 --- a/test/fixtures/es-modules/pjson-main/main.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = 'main'; diff --git a/test/fixtures/es-modules/pjson-main/main.mjs b/test/fixtures/es-modules/pjson-main/main.mjs new file mode 100644 index 0000000000..9eb0aade18 --- /dev/null +++ b/test/fixtures/es-modules/pjson-main/main.mjs @@ -0,0 +1 @@ +export const main = 'main' diff --git a/test/fixtures/es-modules/pjson-main/package.json b/test/fixtures/es-modules/pjson-main/package.json index c13b8cf6ac..ea9b784692 100644 --- a/test/fixtures/es-modules/pjson-main/package.json +++ b/test/fixtures/es-modules/pjson-main/package.json @@ -1,3 +1,3 @@ { - "main": "main.js" + "main": "main.mjs" } diff --git a/test/fixtures/es-modules/test-esm-double-encoding-native%20.js b/test/fixtures/es-modules/test-esm-double-encoding-native%20.mjs index ea1caa81be..a3bfe972e5 100644 --- a/test/fixtures/es-modules/test-esm-double-encoding-native%20.js +++ b/test/fixtures/es-modules/test-esm-double-encoding-native%20.mjs @@ -3,4 +3,4 @@ // Trivial test to assert we can load files with `%` in their pathname. // Imported by `test-esm-double-encoding.mjs`. -module.exports = 42; +export default 42; diff --git a/test/fixtures/experimental.json b/test/fixtures/experimental.json new file mode 100644 index 0000000000..12611d2385 --- /dev/null +++ b/test/fixtures/experimental.json @@ -0,0 +1,3 @@ +{ + "ofLife": 42 +} diff --git a/test/fixtures/syntax/bad_syntax.mjs b/test/fixtures/syntax/bad_syntax.mjs new file mode 100644 index 0000000000..c2cd118b23 --- /dev/null +++ b/test/fixtures/syntax/bad_syntax.mjs @@ -0,0 +1 @@ +var foo bar; diff --git a/test/message/esm_display_syntax_error.out b/test/message/esm_display_syntax_error.out index 1c68ecb952..5e82a1e1ee 100644 --- a/test/message/esm_display_syntax_error.out +++ b/test/message/esm_display_syntax_error.out @@ -2,6 +2,7 @@ file:///*/test/message/esm_display_syntax_error.mjs:3 await async () => 0; ^^^^^ + SyntaxError: Unexpected reserved word - at internal/modules/esm/translators.js:*:* + at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*) at async link (internal/modules/esm/module_job.js:*:*) diff --git a/test/message/esm_display_syntax_error_import.mjs b/test/message/esm_display_syntax_error_import.mjs index 87cedf1d4e..12d10270e9 100644 --- a/test/message/esm_display_syntax_error_import.mjs +++ b/test/message/esm_display_syntax_error_import.mjs @@ -1,7 +1,7 @@ // Flags: --experimental-modules -/* eslint-disable no-unused-vars */ -import '../common'; +/* eslint-disable no-unused-vars, node-core/required-modules */ +import '../common/index.mjs'; import { foo, notfound -} from '../fixtures/es-module-loaders/module-named-exports'; +} from '../fixtures/es-module-loaders/module-named-exports.mjs'; diff --git a/test/message/esm_display_syntax_error_import.out b/test/message/esm_display_syntax_error_import.out index edbbde9f2d..a3601d6cb4 100644 --- a/test/message/esm_display_syntax_error_import.out +++ b/test/message/esm_display_syntax_error_import.out @@ -2,7 +2,7 @@ file:///*/test/message/esm_display_syntax_error_import.mjs:6 notfound ^^^^^^^^ -SyntaxError: The requested module '../fixtures/es-module-loaders/module-named-exports' does not provide an export named 'notfound' +SyntaxError: The requested module '../fixtures/es-module-loaders/module-named-exports.mjs' does not provide an export named 'notfound' at ModuleJob._instantiate (internal/modules/esm/module_job.js:*:*) at async ModuleJob.run (internal/modules/esm/module_job.js:*:*) at async Loader.import (internal/modules/esm/loader.js:*:*) diff --git a/test/message/esm_display_syntax_error_import_module.mjs b/test/message/esm_display_syntax_error_import_module.mjs index 32c0edb350..a53bbbcd19 100644 --- a/test/message/esm_display_syntax_error_import_module.mjs +++ b/test/message/esm_display_syntax_error_import_module.mjs @@ -1,3 +1,4 @@ // Flags: --experimental-modules -import '../common'; -import '../fixtures/es-module-loaders/syntax-error-import'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; +import '../fixtures/es-module-loaders/syntax-error-import.mjs'; diff --git a/test/message/esm_display_syntax_error_import_module.out b/test/message/esm_display_syntax_error_import_module.out index 0512a9ac77..0daaeff5b9 100644 --- a/test/message/esm_display_syntax_error_import_module.out +++ b/test/message/esm_display_syntax_error_import_module.out @@ -1,8 +1,8 @@ (node:*) ExperimentalWarning: The ESM module loader is experimental. file:///*/test/fixtures/es-module-loaders/syntax-error-import.mjs:1 -import { foo, notfound } from './module-named-exports'; +import { foo, notfound } from './module-named-exports.mjs'; ^^^^^^^^ -SyntaxError: The requested module './module-named-exports' does not provide an export named 'notfound' +SyntaxError: The requested module './module-named-exports.mjs' does not provide an export named 'notfound' at ModuleJob._instantiate (internal/modules/esm/module_job.js:*:*) at async ModuleJob.run (internal/modules/esm/module_job.js:*:*) at async Loader.import (internal/modules/esm/loader.js:*:*) diff --git a/test/message/esm_display_syntax_error_module.mjs b/test/message/esm_display_syntax_error_module.mjs index e74b70bec8..5905d2a954 100644 --- a/test/message/esm_display_syntax_error_module.mjs +++ b/test/message/esm_display_syntax_error_module.mjs @@ -1,3 +1,4 @@ // Flags: --experimental-modules -import '../common'; -import '../fixtures/es-module-loaders/syntax-error'; +/* eslint-disable node-core/required-modules */ +import '../common/index.mjs'; +import '../fixtures/es-module-loaders/syntax-error.mjs'; diff --git a/test/message/esm_display_syntax_error_module.out b/test/message/esm_display_syntax_error_module.out index 4e4cbf2ea3..a1498f72c9 100644 --- a/test/message/esm_display_syntax_error_module.out +++ b/test/message/esm_display_syntax_error_module.out @@ -2,5 +2,6 @@ file:///*/test/fixtures/es-module-loaders/syntax-error.mjs:2 await async () => 0; ^^^^^ + SyntaxError: Unexpected reserved word - at internal/modules/esm/translators.js:*:* + at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*)
\ No newline at end of file diff --git a/test/parallel/test-cli-syntax-piped-bad.js b/test/parallel/test-cli-syntax-piped-bad.js index 4fb24b24f3..6d6f800a40 100644 --- a/test/parallel/test-cli-syntax-piped-bad.js +++ b/test/parallel/test-cli-syntax-piped-bad.js @@ -8,24 +8,45 @@ const node = process.execPath; // Test both sets of arguments that check syntax const syntaxArgs = [ - ['-c'], - ['--check'] + '-c', + '--check' ]; // Match on the name of the `Error` but not the message as it is different // depending on the JavaScript engine. -const syntaxErrorRE = /^SyntaxError: \b/m; +const syntaxErrorRE = /^SyntaxError: Unexpected identifier\b/m; // Should throw if code piped from stdin with --check has bad syntax // loop each possible option, `-c` or `--check` -syntaxArgs.forEach(function(args) { +syntaxArgs.forEach(function(arg) { const stdin = 'var foo bar;'; - const c = spawnSync(node, args, { encoding: 'utf8', input: stdin }); + const c = spawnSync(node, [arg], { encoding: 'utf8', input: stdin }); // stderr should include '[stdin]' as the filename assert(c.stderr.startsWith('[stdin]'), `${c.stderr} starts with ${stdin}`); - // No stdout or stderr should be produced + // No stdout should be produced + assert.strictEqual(c.stdout, ''); + + // stderr should have a syntax error message + assert(syntaxErrorRE.test(c.stderr), `${syntaxErrorRE} === ${c.stderr}`); + + assert.strictEqual(c.status, 1); +}); + +// Check --entry-type=module +syntaxArgs.forEach(function(arg) { + const stdin = 'export var p = 5; var foo bar;'; + const c = spawnSync( + node, + ['--experimental-modules', '--entry-type=module', '--no-warnings', arg], + { encoding: 'utf8', input: stdin } + ); + + // stderr should include '[stdin]' as the filename + assert(c.stderr.startsWith('[stdin]'), `${c.stderr} starts with ${stdin}`); + + // No stdout should be produced assert.strictEqual(c.stdout, ''); // stderr should have a syntax error message diff --git a/test/parallel/test-cli-syntax-piped-good.js b/test/parallel/test-cli-syntax-piped-good.js index cdadf449d8..b2b02172cb 100644 --- a/test/parallel/test-cli-syntax-piped-good.js +++ b/test/parallel/test-cli-syntax-piped-good.js @@ -8,15 +8,31 @@ const node = process.execPath; // Test both sets of arguments that check syntax const syntaxArgs = [ - ['-c'], - ['--check'] + '-c', + '--check' ]; // Should not execute code piped from stdin with --check. // Loop each possible option, `-c` or `--check`. -syntaxArgs.forEach(function(args) { +syntaxArgs.forEach(function(arg) { const stdin = 'throw new Error("should not get run");'; - const c = spawnSync(node, args, { encoding: 'utf8', input: stdin }); + const c = spawnSync(node, [arg], { encoding: 'utf8', input: stdin }); + + // No stdout or stderr should be produced + assert.strictEqual(c.stdout, ''); + assert.strictEqual(c.stderr, ''); + + assert.strictEqual(c.status, 0); +}); + +// Check --entry-type=module +syntaxArgs.forEach(function(arg) { + const stdin = 'export var p = 5; throw new Error("should not get run");'; + const c = spawnSync( + node, + ['--experimental-modules', '--no-warnings', '--entry-type=module', arg], + { encoding: 'utf8', input: stdin } + ); // No stdout or stderr should be produced assert.strictEqual(c.stdout, ''); diff --git a/test/parallel/test-loaders-unknown-builtin-module.mjs b/test/parallel/test-loaders-unknown-builtin-module.mjs index db3cfa3582..5f47f191f5 100644 --- a/test/parallel/test-loaders-unknown-builtin-module.mjs +++ b/test/parallel/test-loaders-unknown-builtin-module.mjs @@ -1,5 +1,6 @@ // Flags: --experimental-modules --loader ./test/fixtures/es-module-loaders/loader-unknown-builtin-module.mjs -import { expectsError, mustCall } from '../common'; +/* eslint-disable node-core/required-modules */ +import { expectsError, mustCall } from '../common/index.mjs'; import assert from 'assert'; const unknownBuiltinModule = 'unknown-builtin-module'; diff --git a/test/parallel/test-module-main-extension-lookup.js b/test/parallel/test-module-main-extension-lookup.js index 3d20316647..9e7eab295e 100644 --- a/test/parallel/test-module-main-extension-lookup.js +++ b/test/parallel/test-module-main-extension-lookup.js @@ -6,6 +6,6 @@ const { execFileSync } = require('child_process'); const node = process.argv[0]; execFileSync(node, ['--experimental-modules', - fixtures.path('es-modules', 'test-esm-ok')]); + fixtures.path('es-modules', 'test-esm-ok.mjs')]); execFileSync(node, ['--experimental-modules', fixtures.path('es-modules', 'noext')]); |