Skip to content

Commit

Permalink
fix: Support resolving module.register dependencies (#429)
Browse files Browse the repository at this point in the history
Closes #428

[`module.register(specifier[, parentURL][,
options])`](https://nodejs.org/api/module.html#moduleregisterspecifier-parenturl-options)

---------

Co-authored-by: Steven <steven@ceriously.com>
Co-authored-by: Sean Massa <EndangeredMassa@gmail.com>
  • Loading branch information
3 people authored Sep 3, 2024
1 parent 70775df commit 37b3c16
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 3 deletions.
69 changes: 66 additions & 3 deletions src/analyze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const acorn = Parser.extend(
);

import os from 'os';
import url from 'url';
import { handleWrappers } from './utils/wrappers';
import resolveFrom from 'resolve-from';
import {
Expand Down Expand Up @@ -94,6 +95,10 @@ const fsExtraSymbols = {
readJsonSync: FS_FN,
readJSONSync: FS_FN,
};
const MODULE_FN = Symbol();
const moduleSymbols = {
register: MODULE_FN,
};
const staticModules = Object.assign(Object.create(null), {
bindings: {
default: BINDINGS,
Expand All @@ -111,6 +116,10 @@ const staticModules = Object.assign(Object.create(null), {
default: fsSymbols,
...fsSymbols,
},
module: {
default: moduleSymbols,
...moduleSymbols,
},
'fs-extra': {
default: fsExtraSymbols,
...fsExtraSymbols,
Expand All @@ -131,6 +140,10 @@ const staticModules = Object.assign(Object.create(null), {
default: os,
...os,
},
url: {
default: url,
...url,
},
'@mapbox/node-pre-gyp': {
default: mapboxPregyp,
...mapboxPregyp,
Expand Down Expand Up @@ -530,15 +543,19 @@ export default async function analyze(
let computed = await computePureStaticValue(expression, true);
if (!computed) return;

function add(value: string) {
(isImport ? imports : deps).add(value);
}

if ('value' in computed && typeof computed.value === 'string') {
if (!computed.wildcards) (isImport ? imports : deps).add(computed.value);
if (!computed.wildcards) add(computed.value);
else if (computed.wildcards.length >= 1)
emitWildcardRequire(computed.value);
} else {
if ('then' in computed && typeof computed.then === 'string')
(isImport ? imports : deps).add(computed.then);
add(computed.then);
if ('else' in computed && typeof computed.else === 'string')
(isImport ? imports : deps).add(computed.else);
add(computed.else);
}
}

Expand Down Expand Up @@ -876,6 +893,52 @@ export default async function analyze(
pjsonPath = path.resolve(pjsonPath, '../../package.json');
if (pjsonPath !== rootPjson) assets.add(pjsonPath);
break;
case MODULE_FN:
if (
node.arguments.length &&
// TODO: We only cater for the case where the first argument is a string
node.arguments[0].type === 'Literal'
) {
const pathOrSpecifier = node.arguments[0].value;
// It's a relative URL
if (pathOrSpecifier.startsWith('.')) {
// Compute the parentURL if it's statically analyzable
const computedParentURL =
node.arguments.length > 1
? await computePureStaticValue(node.arguments[1])
: undefined;

if (computedParentURL && 'value' in computedParentURL) {
const parentURL =
computedParentURL.value instanceof URL
? computedParentURL.value.href
: typeof computedParentURL.value === 'string'
? computedParentURL.value
: computedParentURL.value.parentURL;

// Resolve the srcURL from the parentURL
const srcURL = new URL(pathOrSpecifier, parentURL).href;

const currentDirURL = importMetaUrl.slice(
0,
importMetaUrl.lastIndexOf('/'),
);

// Resolve the srcPath relative to the current file
const srcPath = path.relative(currentDirURL, srcURL);
// Make it a proper relative path
const relativeSrcPath = srcPath.startsWith('.')
? srcPath
: './' + srcPath;

imports.add(relativeSrcPath);
}
} else {
// It's a bare specifier, so just add into the imports
imports.add(pathOrSpecifier);
}
}
break;
}
}
} else if (
Expand Down
1 change: 1 addition & 0 deletions test/unit/module-register/hook.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('hook.mjs');
1 change: 1 addition & 0 deletions test/unit/module-register/hook2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('hook2.mjs');
1 change: 1 addition & 0 deletions test/unit/module-register/hook3.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('hook3.mjs');
8 changes: 8 additions & 0 deletions test/unit/module-register/input-esm.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { register } from 'module';

// Load relative to the current file
register('./hook.mjs', import.meta.url);
// Load from a bare specifier
register('test-pkg');
// Load with parentURL in options object
register('./hook.mjs', { parentURL: import.meta.url });
10 changes: 10 additions & 0 deletions test/unit/module-register/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const { register } = require('module');
const { pathToFileURL } = require('url');

import('./input-esm.mjs')

// Load relative to the current file
register('./hook2.mjs', pathToFileURL(__filename));
// Load relative to the current working directory
register('./test/unit/module-register/hook3.mjs', pathToFileURL('./'));

1 change: 1 addition & 0 deletions test/unit/module-register/node_modules/test-pkg/index.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions test/unit/module-register/node_modules/test-pkg/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions test/unit/module-register/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
"package.json",
"test/unit/module-register/hook.mjs",
"test/unit/module-register/hook2.mjs",
"test/unit/module-register/hook3.mjs",
"test/unit/module-register/input-esm.mjs",
"test/unit/module-register/input.js",
"test/unit/module-register/node_modules/test-pkg/index.mjs",
"test/unit/module-register/node_modules/test-pkg/package.json"
]

0 comments on commit 37b3c16

Please sign in to comment.