0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-29 23:16:30 +01:00
nodejs/test/es-module/test-esm-dynamic-import.js
Myles Borins ba3d55a3b8
module: enable dynamic import flag for esmodules
currently if you want to use dynamic import you must use both the
`--experimental-modules` and the `--harmony-dynamic-imports` flags.
Chrome is currently shipping dynamic import unflagged, the flag
only remains in V8 to guard embedders who have not set the appropriate
callback from throwing an unhandled rejection when the feature is used.

As such it is reasonable to enable the flag by default for
`--experimental-modules`

PR-URL: https://github.com/nodejs/node/pull/18387
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
2018-01-31 16:05:23 -08:00

114 lines
3.8 KiB
JavaScript

// Flags: --experimental-modules
'use strict';
const common = require('../common');
const assert = require('assert');
const { URL } = require('url');
const vm = require('vm');
common.crashOnUnhandledRejection();
const relativePath = './test-esm-ok.mjs';
const absolutePath = require.resolve('./test-esm-ok.mjs');
const targetURL = new URL('file:///');
targetURL.pathname = absolutePath;
function expectErrorProperty(result, propertyKey, value) {
Promise.resolve(result)
.catch(common.mustCall(error => {
assert.strictEqual(error[propertyKey], value);
}));
}
function expectMissingModuleError(result) {
expectErrorProperty(result, 'code', 'MODULE_NOT_FOUND');
}
function expectInvalidUrlError(result) {
expectErrorProperty(result, 'code', 'ERR_INVALID_URL');
}
function expectInvalidReferrerError(result) {
expectErrorProperty(result, 'code', 'ERR_INVALID_URL');
}
function expectInvalidProtocolError(result) {
expectErrorProperty(result, 'code', 'ERR_INVALID_PROTOCOL');
}
function expectInvalidContextError(result) {
expectErrorProperty(result,
'message', 'import() called outside of main context');
}
function expectOkNamespace(result) {
Promise.resolve(result)
.then(common.mustCall(ns => {
// Can't deepStrictEqual because ns isn't a normal object
assert.deepEqual(ns, { default: true });
}));
}
function expectFsNamespace(result) {
Promise.resolve(result)
.then(common.mustCall(ns => {
assert.strictEqual(typeof ns.default.writeFile, 'function');
}));
}
// For direct use of import expressions inside of CJS or ES modules, including
// via eval, all kinds of specifiers should work without issue.
(function testScriptOrModuleImport() {
// Importing another file, both direct & via eval
// expectOkNamespace(import(relativePath));
expectOkNamespace(eval.call(null, `import("${relativePath}")`));
expectOkNamespace(eval(`import("${relativePath}")`));
expectOkNamespace(eval.call(null, `import("${targetURL}")`));
// Importing a built-in, both direct & via eval
expectFsNamespace(import("fs"));
expectFsNamespace(eval('import("fs")'));
expectFsNamespace(eval.call(null, 'import("fs")'));
expectMissingModuleError(import("./not-an-existing-module.mjs"));
// TODO(jkrems): Right now this doesn't hit a protocol error because the
// module resolution step already rejects it. These arguably should be
// protocol errors.
expectMissingModuleError(import("node:fs"));
expectMissingModuleError(import('http://example.com/foo.js'));
})();
// vm.runInThisContext:
// * Supports built-ins, always
// * Supports imports if the script has a known defined origin
(function testRunInThisContext() {
// Succeeds because it's got an valid base url
expectFsNamespace(vm.runInThisContext(`import("fs")`, {
filename: __filename,
}));
expectOkNamespace(vm.runInThisContext(`import("${relativePath}")`, {
filename: __filename,
}));
// Rejects because it's got an invalid referrer URL.
// TODO(jkrems): Arguably the first two (built-in + absolute URL) could work
// with some additional effort.
expectInvalidReferrerError(vm.runInThisContext('import("fs")'));
expectInvalidReferrerError(vm.runInThisContext(`import("${targetURL}")`));
expectInvalidReferrerError(vm.runInThisContext(`import("${relativePath}")`));
})();
// vm.runInNewContext is currently completely unsupported, pending well-defined
// semantics for per-context/realm module maps in node.
(function testRunInNewContext() {
// Rejects because it's running in the wrong context
expectInvalidContextError(
vm.runInNewContext(`import("${targetURL}")`, undefined, {
filename: __filename,
})
);
// Rejects because it's running in the wrong context
expectInvalidContextError(vm.runInNewContext(`import("fs")`, undefined, {
filename: __filename,
}));
})();