Skip to content

Commit

Permalink
esm: add --experimental-import flag
Browse files Browse the repository at this point in the history
  • Loading branch information
MoLow committed Jul 22, 2022
1 parent 0484022 commit 06de59d
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 14 deletions.
13 changes: 13 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,17 @@ added:

Expose the [Web Crypto API][] on the global scope.

### `--experimental-import module`

<!-- YAML
added: REPLACEME
-->

Preload the specified module at startup.

Follows [ECMAScript modules][] resolution
rules.

### `--experimental-import-meta-resolve`

<!-- YAML
Expand Down Expand Up @@ -1653,6 +1664,7 @@ Node.js options that are allowed are:
* `--enable-source-maps`
* `--experimental-abortcontroller`
* `--experimental-global-webcrypto`
* `--experimental-import`
* `--experimental-import-meta-resolve`
* `--experimental-json-modules`
* `--experimental-loader`
Expand Down Expand Up @@ -2078,6 +2090,7 @@ done
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
[CommonJS]: modules.md
[ECMAScript module loader]: esm.md#loaders
[ECMAScript modules]: esm.md#modules-ecmascript-modules
[Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
[Modules loaders]: packages.md#modules-loaders
[OSSL_PROVIDER-legacy]: https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
Expand Down
7 changes: 6 additions & 1 deletion lib/internal/modules/run_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ function shouldUseESMLoader(mainPath) {
* (or an empty list when none have been registered).
*/
const userLoaders = getOptionValue('--experimental-loader');
if (userLoaders.length > 0)
/**
* @type {string[]} userImports A list of preloaded modules registered by the user
* (or an empty list when none have been registered).
*/
const userImports = getOptionValue('--experimental-import');
if (userLoaders.length > 0 || userImports.length > 0)
return true;
const esModuleSpecifierResolution =
getOptionValue('--experimental-specifier-resolution');
Expand Down
29 changes: 20 additions & 9 deletions lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const {
ArrayIsArray,
ObjectCreate,
} = primordials;

Expand Down Expand Up @@ -56,8 +57,24 @@ async function initializeLoader() {

const { getOptionValue } = require('internal/options');
const customLoaders = getOptionValue('--experimental-loader');
const preloadModules = getOptionValue('--experimental-import');
const keyedExportsList = await loadInternalModules(customLoaders);

if (customLoaders.length === 0) return;
// Hooks must then be added to external/public loader
// (so they're triggered in userland)
await esmLoader.addCustomLoaders(keyedExportsList);

// Preload after loaders are added so they can be used
if (preloadModules && preloadModules.length > 0) {
await loadInternalModules(preloadModules);
}

isESMInitialized = true;
}

async function loadInternalModules(requests) {
if (!ArrayIsArray(requests) || requests.length === 0)
return;

let cwd;
try {
Expand All @@ -72,17 +89,11 @@ async function initializeLoader() {
const internalEsmLoader = new ESMLoader();

// Importation must be handled by internal loader to avoid poluting userland
const keyedExportsList = await internalEsmLoader.import(
customLoaders,
return internalEsmLoader.import(
requests,
pathToFileURL(cwd).href,
ObjectCreate(null),
);

// Hooks must then be added to external/public loader
// (so they're triggered in userland)
await esmLoader.addCustomLoaders(keyedExportsList);

isESMInitialized = true;
}

exports.loadESM = async function loadESM(callback) {
Expand Down
10 changes: 7 additions & 3 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,15 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
AddAlias("--print <arg>", "-pe");
AddAlias("-pe", { "--print", "--eval" });
AddAlias("-p", "--print");
AddOption("--require",
"module to preload (option can be repeated)",
&EnvironmentOptions::preload_modules,
AddOption("--require",
"cjs module to preload (option can be repeated)",
&EnvironmentOptions::preload_cjs_modules,
kAllowedInEnvironment);
AddAlias("-r", "--require");
AddOption("--experimental-import",
"esm module to preload (option can be repeated)",
&EnvironmentOptions::preload_esm_modules,
kAllowedInEnvironment);
AddOption("--interactive",
"always enter the REPL even if stdin does not appear "
"to be a terminal",
Expand Down
4 changes: 3 additions & 1 deletion src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ class EnvironmentOptions : public Options {
bool tls_max_v1_3 = false;
std::string tls_keylog;

std::vector<std::string> preload_modules;
std::vector<std::string> preload_cjs_modules;

std::vector<std::string> preload_esm_modules;

std::vector<std::string> user_argv;

Expand Down

0 comments on commit 06de59d

Please sign in to comment.