Skip to content

Commit

Permalink
feat(esm): leverage loaders when resolving subsequent loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
arcanis committed Jul 11, 2022
1 parent 7d13f5e commit a72c577
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 6 deletions.
3 changes: 3 additions & 0 deletions dev_fixtures_do_not_merge/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import symbol from 'yyy/lib.mjs';

console.log(`main`, symbol);
3 changes: 3 additions & 0 deletions dev_fixtures_do_not_merge/lib.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
console.log(`lib`);

export default 42;
4 changes: 4 additions & 0 deletions dev_fixtures_do_not_merge/loader-a.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export async function resolve(specifier, context, defaultResolve) {
console.log(`loader-a`, {specifier});
return defaultResolve(specifier.replace(/^xxx\//, `./`));
}
4 changes: 4 additions & 0 deletions dev_fixtures_do_not_merge/loader-b.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export async function resolve(specifier, context, defaultResolve) {
console.log(`loader-b`, {specifier});
return defaultResolve(specifier.replace(/^yyy\//, `./`));
}
20 changes: 14 additions & 6 deletions lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
const {
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
} = require('internal/errors').codes;
const console = require('console');
const { ESMLoader } = require('internal/modules/esm/loader');
const {
hasUncaughtExceptionCaptureCallback,
Expand Down Expand Up @@ -60,17 +61,24 @@ async function initializeLoader() {
cwd = 'file:///';
}

const keyedExportsList = [];

// A separate loader instance is necessary to avoid cross-contamination
// between internal Node.js and userland. For example, a module with internal
// state (such as a counter) should be independent.
const internalEsmLoader = new ESMLoader();

// Importation must be handled by internal loader to avoid poluting userland
const keyedExportsList = await internalEsmLoader.import(
customLoaders,
pathToFileURL(cwd).href,
ObjectCreate(null),
);
for (const customLoader of customLoaders) {
// Importation must be handled by internal loader to avoid poluting userland
const keyedExportsSublist = await internalEsmLoader.import(
[customLoader],
pathToFileURL(cwd).href,
ObjectCreate(null),
);

await internalEsmLoader.addCustomLoaders(keyedExportsSublist);
keyedExportsList.push(...keyedExportsSublist);
}

// Hooks must then be added to external/public loader
// (so they're triggered in userland)
Expand Down

0 comments on commit a72c577

Please sign in to comment.