Skip to content
This repository has been archived by the owner on Apr 16, 2020. It is now read-only.

Commit

Permalink
esm: Remove --loader.
Browse files Browse the repository at this point in the history
PR-URL: #6
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Myles Borins <mylesborins@google.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
  • Loading branch information
jdalton authored and MylesBorins committed Nov 8, 2018
1 parent 2715685 commit 1173502
Show file tree
Hide file tree
Showing 40 changed files with 2 additions and 454 deletions.
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ module.exports = {
files: [
'doc/api/esm.md',
'*.mjs',
'test/es-module/test-esm-example-loader.js',
],
parserOptions: { sourceType: 'module' },
},
Expand Down
9 changes: 0 additions & 9 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,6 @@ default) is not firewall-protected.**

See the [debugging security implications][] section for more information.

### `--loader=file`
<!-- YAML
added: v9.0.0
-->

Specify the `file` of the custom [experimental ECMAScript Module][] loader.

### `--napi-modules`
<!-- YAML
added: v7.10.0
Expand Down Expand Up @@ -583,7 +576,6 @@ Node.js options that are allowed are:
- `--inspect`
- `--inspect-brk`
- `--inspect-port`
- `--loader`
- `--napi-modules`
- `--no-deprecation`
- `--no-force-async-hooks-checks`
Expand Down Expand Up @@ -762,6 +754,5 @@ greater than `4` (its current default value). For more information, see the
[debugger]: debugger.html
[debugging security implications]: https://nodejs.org/en/docs/guides/debugging-getting-started/#security-implications
[emit_warning]: process.html#process_process_emitwarning_warning_type_code_ctor
[experimental ECMAScript Module]: esm.html#esm_loader_hooks
[libuv threadpool documentation]: http://docs.libuv.org/en/latest/threadpool.html
[remote code execution]: https://www.owasp.org/index.php/Code_Injection
119 changes: 0 additions & 119 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,125 +146,6 @@ fs.readFileSync = () => Buffer.from('Hello, ESM');
fs.readFileSync === readFileSync;
```
## Loader hooks
<!-- type=misc -->
To customize the default module resolution, loader hooks can optionally be
provided via a `--loader ./loader-name.mjs` argument to Node.js.
When hooks are used they only apply to ES module loading and not to any
CommonJS modules loaded.
### Resolve hook
The resolve hook returns the resolved file URL and module format for a
given module specifier and parent file URL:
```js
const baseURL = new URL('file://');
baseURL.pathname = `${process.cwd()}/`;

export async function resolve(specifier,
parentModuleURL = baseURL,
defaultResolver) {
return {
url: new URL(specifier, parentModuleURL).href,
format: 'esm'
};
}
```
The `parentModuleURL` is provided as `undefined` when performing main Node.js
load itself.
The default Node.js ES module resolution function is provided as a third
argument to the resolver for easy compatibility workflows.
In addition to returning the resolved file URL value, the resolve hook also
returns a `format` property specifying the module format of the resolved
module. This can be one of the following:
| `format` | Description |
| --- | --- |
| `'esm'` | Load a standard JavaScript module |
| `'builtin'` | Load a node builtin CommonJS module |
| `'dynamic'` | Use a [dynamic instantiate hook][] |
For example, a dummy loader to load JavaScript restricted to browser resolution
rules with only JS file extension and Node.js builtin modules support could
be written:
```js
import path from 'path';
import process from 'process';
import Module from 'module';

const builtins = Module.builtinModules;
const JS_EXTENSIONS = new Set(['.js', '.mjs']);

const baseURL = new URL('file://');
baseURL.pathname = `${process.cwd()}/`;

export function resolve(specifier, parentModuleURL = baseURL, defaultResolve) {
if (builtins.includes(specifier)) {
return {
url: specifier,
format: 'builtin'
};
}
if (/^\.{0,2}[/]/.test(specifier) !== true && !specifier.startsWith('file:')) {
// For node_modules support:
// return defaultResolve(specifier, parentModuleURL);
throw new Error(
`imports must begin with '/', './', or '../'; '${specifier}' does not`);
}
const resolved = new URL(specifier, parentModuleURL);
const ext = path.extname(resolved.pathname);
if (!JS_EXTENSIONS.has(ext)) {
throw new Error(
`Cannot load file with non-JavaScript file extension ${ext}.`);
}
return {
url: resolved.href,
format: 'esm'
};
}
```
With this loader, running:
```console
NODE_OPTIONS='--experimental-modules --loader ./custom-loader.mjs' node x.js
```
would load the module `x.js` as an ES module with relative resolution support
(with `node_modules` loading skipped in this example).
### Dynamic instantiate hook
To create a custom dynamic module that doesn't correspond to one of the
existing `format` interpretations, the `dynamicInstantiate` hook can be used.
This hook is called only for modules that return `format: 'dynamic'` from
the `resolve` hook.
```js
export async function dynamicInstantiate(url) {
return {
exports: ['customExportName'],
execute: (exports) => {
// get and set functions provided for pre-allocated export names
exports.customExportName.set('value');
}
};
}
```
With the list of module exports provided upfront, the `execute` function will
then be called at the exact point of module evaluation order for that module
in the import tree.
[Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md
[dynamic instantiate hook]: #esm_dynamic_instantiate_hook
[`module.createRequireFromPath()`]: modules.html#modules_module_createrequirefrompath_filename
[ESM Minimal Kernel]: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md
3 changes: 1 addition & 2 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ const { getOptionValue } = require('internal/options');
const preserveSymlinks = getOptionValue('--preserve-symlinks');
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
const experimentalModules = getOptionValue('--experimental-modules');
const hasLoader = getOptionValue('--loader');

const {
ERR_INVALID_ARG_TYPE,
Expand Down Expand Up @@ -766,7 +765,7 @@ Module.runMain = function() {
const ext = path.extname(base);
const isESM = ext === '.mjs';

if (experimentalModules && (isESM || hasLoader)) {
if (experimentalModules && isESM) {
if (asyncESM === undefined) lazyLoadESM();
asyncESM.loaderPromise.then((loader) => {
return loader.import(pathToFileURL(process.argv[1]).pathname);
Expand Down
11 changes: 1 addition & 10 deletions lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const {
callbackMap,
} = internalBinding('module_wrap');

const { pathToFileURL } = require('internal/url');
const Loader = require('internal/modules/esm/loader');
const {
wrapToModuleMap,
Expand Down Expand Up @@ -46,16 +45,8 @@ exports.loaderPromise = new Promise((resolve, reject) => {
exports.ESMLoader = undefined;

exports.setup = function() {
let ESMLoader = new Loader();
const ESMLoader = new Loader();
const loaderPromise = (async () => {
const userLoader = require('internal/options').getOptionValue('--loader');
if (userLoader) {
const hooks = await ESMLoader.import(
userLoader, pathToFileURL(`${process.cwd()}/`).href);
ESMLoader = new Loader();
ESMLoader.hook(hooks);
exports.ESMLoader = ESMLoader;
}
return ESMLoader;
})();
loaderResolve(loaderPromise);
Expand Down
4 changes: 0 additions & 4 deletions src/node_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ static void Initialize(Local<Object> target,

if (env->options()->experimental_modules) {
READONLY_BOOLEAN_PROPERTY("experimentalModules");
const std::string& userland_loader = env->options()->userland_loader;
if (!userland_loader.empty()) {
READONLY_STRING_PROPERTY(target, "userLoader", userland_loader);
}
}

if (env->options()->experimental_vm_modules)
Expand Down
9 changes: 0 additions & 9 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ void PerIsolateOptions::CheckOptions(std::vector<std::string>* errors) {
}

void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) {
if (!userland_loader.empty() && !experimental_modules) {
errors->push_back("--loader requires --experimental-modules be enabled");
}

if (syntax_check_only && has_eval_string) {
errors->push_back("either --check or --eval can be used, not both");
}
Expand Down Expand Up @@ -102,11 +98,6 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
&EnvironmentOptions::experimental_worker,
kAllowedInEnvironment);
AddOption("--expose-internals", "", &EnvironmentOptions::expose_internals);
AddOption("--loader",
"(with --experimental-modules) use the specified file as a "
"custom loader",
&EnvironmentOptions::userland_loader,
kAllowedInEnvironment);
AddOption("--no-deprecation",
"silence deprecation warnings",
&EnvironmentOptions::no_deprecation,
Expand Down
1 change: 0 additions & 1 deletion src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ class EnvironmentOptions : public Options {
bool trace_deprecation = false;
bool trace_sync_io = false;
bool trace_warnings = false;
std::string userland_loader;

bool syntax_check_only = false;
bool has_eval_string = false;
Expand Down
6 changes: 0 additions & 6 deletions test/es-module/test-esm-example-loader.js

This file was deleted.

5 changes: 0 additions & 5 deletions test/es-module/test-esm-loader-dependency.mjs

This file was deleted.

12 changes: 0 additions & 12 deletions test/es-module/test-esm-loader-invalid-format.mjs

This file was deleted.

14 changes: 0 additions & 14 deletions test/es-module/test-esm-loader-invalid-url.mjs

This file was deleted.

This file was deleted.

9 changes: 0 additions & 9 deletions test/es-module/test-esm-named-exports.mjs

This file was deleted.

3 changes: 0 additions & 3 deletions test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs

This file was deleted.

3 changes: 0 additions & 3 deletions test/es-module/test-esm-preserve-symlinks-not-found.mjs

This file was deleted.

8 changes: 0 additions & 8 deletions test/es-module/test-esm-resolve-hook.mjs

This file was deleted.

11 changes: 0 additions & 11 deletions test/es-module/test-esm-shared-loader-dep.mjs

This file was deleted.

16 changes: 0 additions & 16 deletions test/es-module/test-esm-throw-undefined.mjs

This file was deleted.

29 changes: 0 additions & 29 deletions test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs

This file was deleted.

Loading

0 comments on commit 1173502

Please sign in to comment.