From 4667b07cd2d6eb0295d6cd1f40163ef14ce538b0 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Thu, 13 Apr 2023 09:35:17 +0200 Subject: [PATCH] esm: move hook execution to separate thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/44710 Reviewed-By: Yagiz Nizipli Reviewed-By: Geoffrey Booth Co-authored-by: Antoine du Hamel Co-authored-by: Geoffrey Booth Co-authored-by: Michaƫl Zasso --- doc/api/esm.md | 39 +- lib/internal/main/worker_thread.js | 89 +++-- lib/internal/modules/esm/hooks.js | 349 ++++++++++++------ .../modules/esm/initialize_import_meta.js | 51 ++- lib/internal/modules/esm/loader.js | 212 +++++++---- lib/internal/modules/esm/module_job.js | 7 +- lib/internal/modules/esm/resolve.js | 23 +- lib/internal/modules/esm/shared_constants.js | 25 ++ lib/internal/modules/esm/utils.js | 69 +++- lib/internal/modules/esm/worker.js | 210 +++++++++++ lib/internal/process/esm_loader.js | 133 ++----- lib/internal/worker.js | 34 +- src/node_worker.cc | 12 +- .../test-esm-import-meta-resolve.mjs | 56 ++- test/es-module/test-esm-loader-modulemap.js | 4 +- test/es-module/test-esm-loader-search.js | 4 +- .../test-esm-loader-with-syntax-error.mjs | 2 +- test/es-module/test-esm-resolve-type.mjs | 20 +- .../es-module-loaders/hooks-input.mjs | 15 +- .../es-module-loaders/loader-edge-cases.mjs | 6 +- .../loader-load-foo-or-42.mjs | 2 +- .../loader-load-incomplete.mjs | 2 +- .../loader-load-passthru.mjs | 7 +- ...loader-load-receiving-modified-context.mjs | 5 +- .../es-module-loaders/loader-log-args.mjs | 15 +- .../es-module-loaders/loader-resolve-42.mjs | 9 +- .../es-module-loaders/loader-resolve-foo.mjs | 7 +- .../loader-resolve-incomplete.mjs | 2 +- .../loader-resolve-next-modified.mjs | 2 +- .../loader-resolve-passthru.mjs | 7 +- ...der-resolve-receiving-modified-context.mjs | 5 +- .../loader-resolve-shortcircuit.mjs | 2 +- .../loader-resolve-strip-xxx.mjs | 8 +- .../loader-resolve-strip-yyy.mjs | 5 +- .../import.meta.never-resolve.mjs | 2 +- .../es-modules/import-resolve-exports.mjs | 10 +- test/fixtures/es-modules/runmain.mjs | 4 +- 37 files changed, 997 insertions(+), 457 deletions(-) create mode 100644 lib/internal/modules/esm/shared_constants.js create mode 100644 lib/internal/modules/esm/worker.js diff --git a/doc/api/esm.md b/doc/api/esm.md index 6293779131e4e0..884c3e83c9e684 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -7,6 +7,9 @@ +> **Caveat** This can result in synchronous file-system operations, which +> can impact performance similarly to `require.resolve`. ```js -const dependencyAsset = await import.meta.resolve('component-lib/asset.css'); +const dependencyAsset = import.meta.resolve('component-lib/asset.css'); ``` `import.meta.resolve` also accepts a second argument which is the parent module -from which to resolve from: - - +from which to resolve: ```js -await import.meta.resolve('./dep', import.meta.url); +import.meta.resolve('./dep', import.meta.url); ``` -This function is asynchronous because the ES module resolver in Node.js is -allowed to be asynchronous. - ## Interoperability with CommonJS ### `import` statements @@ -730,6 +733,11 @@ A hook that returns without calling `next()` _and_ without returning `shortCircuit: true` also triggers an exception. These errors are to help prevent unintentional breaks in the chain. +Hooks are run in a separate thread, isolated from the main. That means it is a +different [realm](https://tc39.es/ecma262/#realm). The hooks thread may be +terminated by the main thread at any time, so do not depend on asynchronous +operations to (like `console.log`) complete. + #### `resolve(specifier, context, nextResolve)`