module: refactor loader
PR-URL: https://github.com/nodejs/node/pull/16874 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
This commit is contained in:
parent
85739b6c5b
commit
921fb84687
@ -1,9 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
ModuleWrap,
|
||||
setImportModuleDynamicallyCallback
|
||||
} = internalBinding('module_wrap');
|
||||
const { ModuleWrap } = internalBinding('module_wrap');
|
||||
const debug = require('util').debuglog('esm');
|
||||
const ArrayJoin = Function.call.bind(Array.prototype.join);
|
||||
const ArrayMap = Function.call.bind(Array.prototype.map);
|
||||
@ -60,8 +57,4 @@ const createDynamicModule = (exports, url = '', evaluate) => {
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createDynamicModule,
|
||||
setImportModuleDynamicallyCallback,
|
||||
ModuleWrap
|
||||
};
|
||||
module.exports = createDynamicModule;
|
84
lib/internal/loader/DefaultResolve.js
Normal file
84
lib/internal/loader/DefaultResolve.js
Normal file
@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const { URL } = require('url');
|
||||
const CJSmodule = require('module');
|
||||
const internalURLModule = require('internal/url');
|
||||
const internalFS = require('internal/fs');
|
||||
const NativeModule = require('native_module');
|
||||
const { extname } = require('path');
|
||||
const { realpathSync } = require('fs');
|
||||
const preserveSymlinks = !!process.binding('config').preserveSymlinks;
|
||||
const errors = require('internal/errors');
|
||||
const { resolve: moduleWrapResolve } = internalBinding('module_wrap');
|
||||
const StringStartsWith = Function.call.bind(String.prototype.startsWith);
|
||||
|
||||
const realpathCache = new Map();
|
||||
|
||||
function search(target, base) {
|
||||
if (base === undefined) {
|
||||
// We cannot search without a base.
|
||||
throw new errors.Error('ERR_MISSING_MODULE', target);
|
||||
}
|
||||
try {
|
||||
return moduleWrapResolve(target, base);
|
||||
} catch (e) {
|
||||
e.stack; // cause V8 to generate stack before rethrow
|
||||
let error = e;
|
||||
try {
|
||||
const questionedBase = new URL(base);
|
||||
const tmpMod = new CJSmodule(questionedBase.pathname, null);
|
||||
tmpMod.paths = CJSmodule._nodeModulePaths(
|
||||
new URL('./', questionedBase).pathname);
|
||||
const found = CJSmodule._resolveFilename(target, tmpMod);
|
||||
error = new errors.Error('ERR_MODULE_RESOLUTION_LEGACY', target,
|
||||
base, found);
|
||||
} catch (problemChecking) {
|
||||
// ignore
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const extensionFormatMap = {
|
||||
__proto__: null,
|
||||
'.mjs': 'esm',
|
||||
'.json': 'json',
|
||||
'.node': 'addon',
|
||||
'.js': 'commonjs'
|
||||
};
|
||||
|
||||
function resolve(specifier, parentURL) {
|
||||
if (NativeModule.nonInternalExists(specifier)) {
|
||||
return {
|
||||
url: specifier,
|
||||
format: 'builtin'
|
||||
};
|
||||
}
|
||||
|
||||
let url;
|
||||
try {
|
||||
url = search(specifier, parentURL);
|
||||
} catch (e) {
|
||||
if (typeof e.message === 'string' &&
|
||||
StringStartsWith(e.message, 'Cannot find module'))
|
||||
e.code = 'MODULE_NOT_FOUND';
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (!preserveSymlinks) {
|
||||
const real = realpathSync(internalURLModule.getPathFromURL(url), {
|
||||
[internalFS.realpathCacheKey]: realpathCache
|
||||
});
|
||||
const old = url;
|
||||
url = internalURLModule.getURLFromFilePath(real);
|
||||
url.search = old.search;
|
||||
url.hash = old.hash;
|
||||
}
|
||||
|
||||
const ext = extname(url.pathname);
|
||||
return { url: `${url}`, format: extensionFormatMap[ext] || ext };
|
||||
}
|
||||
|
||||
module.exports = resolve;
|
||||
// exported for tests
|
||||
module.exports.search = search;
|
@ -2,16 +2,16 @@
|
||||
|
||||
const path = require('path');
|
||||
const { getURLFromFilePath, URL } = require('internal/url');
|
||||
|
||||
const {
|
||||
createDynamicModule,
|
||||
setImportModuleDynamicallyCallback
|
||||
} = require('internal/loader/ModuleWrap');
|
||||
const errors = require('internal/errors');
|
||||
|
||||
const ModuleMap = require('internal/loader/ModuleMap');
|
||||
const ModuleJob = require('internal/loader/ModuleJob');
|
||||
const ModuleRequest = require('internal/loader/ModuleRequest');
|
||||
const errors = require('internal/errors');
|
||||
const defaultResolve = require('internal/loader/DefaultResolve');
|
||||
const createDynamicModule = require('internal/loader/CreateDynamicModule');
|
||||
const translators = require('internal/loader/Translators');
|
||||
const { setImportModuleDynamicallyCallback } = internalBinding('module_wrap');
|
||||
const FunctionBind = Function.call.bind(Function.prototype.bind);
|
||||
|
||||
const debug = require('util').debuglog('esm');
|
||||
|
||||
// Returns a file URL for the current working directory.
|
||||
@ -40,105 +40,101 @@ function normalizeReferrerURL(referrer) {
|
||||
* the main module and everything in its dependency graph. */
|
||||
class Loader {
|
||||
constructor(base = getURLStringForCwd()) {
|
||||
if (typeof base !== 'string') {
|
||||
if (typeof base !== 'string')
|
||||
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'base', 'string');
|
||||
}
|
||||
|
||||
this.moduleMap = new ModuleMap();
|
||||
this.base = base;
|
||||
|
||||
// methods which translate input code or other information
|
||||
// into es modules
|
||||
this.translators = translators;
|
||||
|
||||
// registry of loaded modules, akin to `require.cache`
|
||||
this.moduleMap = new ModuleMap();
|
||||
|
||||
// The resolver has the signature
|
||||
// (specifier : string, parentURL : string, defaultResolve)
|
||||
// -> Promise<{ url : string,
|
||||
// format: anything in Loader.validFormats }>
|
||||
// -> Promise<{ url : string, format: string }>
|
||||
// where defaultResolve is ModuleRequest.resolve (having the same
|
||||
// signature itself).
|
||||
// If `.format` on the returned value is 'dynamic', .dynamicInstantiate
|
||||
// will be used as described below.
|
||||
this.resolver = ModuleRequest.resolve;
|
||||
// This hook is only called when resolve(...).format is 'dynamic' and has
|
||||
// the signature
|
||||
this._resolve = defaultResolve;
|
||||
// This hook is only called when resolve(...).format is 'dynamic' and
|
||||
// has the signature
|
||||
// (url : string) -> Promise<{ exports: { ... }, execute: function }>
|
||||
// Where `exports` is an object whose property names define the exported
|
||||
// names of the generated module. `execute` is a function that receives
|
||||
// an object with the same keys as `exports`, whose values are get/set
|
||||
// functions for the actual exported values.
|
||||
this.dynamicInstantiate = undefined;
|
||||
this._dynamicInstantiate = undefined;
|
||||
}
|
||||
|
||||
hook({ resolve = ModuleRequest.resolve, dynamicInstantiate }) {
|
||||
// Use .bind() to avoid giving access to the Loader instance when it is
|
||||
// called as this.resolver(...);
|
||||
this.resolver = resolve.bind(null);
|
||||
this.dynamicInstantiate = dynamicInstantiate;
|
||||
}
|
||||
|
||||
// Typechecking wrapper around .resolver().
|
||||
async resolve(specifier, parentURL = this.base) {
|
||||
if (typeof parentURL !== 'string') {
|
||||
throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
|
||||
'parentURL', 'string');
|
||||
}
|
||||
if (typeof parentURL !== 'string')
|
||||
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'parentURL', 'string');
|
||||
|
||||
const { url, format } = await this.resolver(specifier, parentURL,
|
||||
ModuleRequest.resolve);
|
||||
const { url, format } =
|
||||
await this._resolve(specifier, parentURL, defaultResolve);
|
||||
|
||||
if (!Loader.validFormats.includes(format)) {
|
||||
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'format',
|
||||
Loader.validFormats);
|
||||
}
|
||||
|
||||
if (typeof url !== 'string') {
|
||||
if (typeof url !== 'string')
|
||||
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'url', 'string');
|
||||
}
|
||||
|
||||
if (format === 'builtin') {
|
||||
if (typeof format !== 'string')
|
||||
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'format', 'string');
|
||||
|
||||
if (format === 'builtin')
|
||||
return { url: `node:${url}`, format };
|
||||
}
|
||||
|
||||
if (format !== 'dynamic') {
|
||||
if (!ModuleRequest.loaders.has(format)) {
|
||||
throw new errors.Error('ERR_UNKNOWN_MODULE_FORMAT', format);
|
||||
}
|
||||
if (!url.startsWith('file:')) {
|
||||
throw new errors.Error('ERR_INVALID_PROTOCOL', url, 'file:');
|
||||
}
|
||||
}
|
||||
if (format !== 'dynamic' && !url.startsWith('file:'))
|
||||
throw new errors.Error('ERR_INVALID_PROTOCOL', url, 'file:');
|
||||
|
||||
return { url, format };
|
||||
}
|
||||
|
||||
// May create a new ModuleJob instance if one did not already exist.
|
||||
async import(specifier, parent = this.base) {
|
||||
const job = await this.getModuleJob(specifier, parent);
|
||||
const module = await job.run();
|
||||
return module.namespace();
|
||||
}
|
||||
|
||||
hook({ resolve, dynamicInstantiate }) {
|
||||
// Use .bind() to avoid giving access to the Loader instance when called.
|
||||
if (resolve !== undefined)
|
||||
this._resolve = FunctionBind(resolve, null);
|
||||
if (dynamicInstantiate !== undefined)
|
||||
this._dynamicInstantiate = FunctionBind(dynamicInstantiate, null);
|
||||
}
|
||||
|
||||
async getModuleJob(specifier, parentURL = this.base) {
|
||||
const { url, format } = await this.resolve(specifier, parentURL);
|
||||
let job = this.moduleMap.get(url);
|
||||
if (job === undefined) {
|
||||
let loaderInstance;
|
||||
if (format === 'dynamic') {
|
||||
const { dynamicInstantiate } = this;
|
||||
if (typeof dynamicInstantiate !== 'function') {
|
||||
throw new errors.Error('ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK');
|
||||
}
|
||||
if (job !== undefined)
|
||||
return job;
|
||||
|
||||
loaderInstance = async (url) => {
|
||||
const { exports, execute } = await dynamicInstantiate(url);
|
||||
return createDynamicModule(exports, url, (reflect) => {
|
||||
debug(`Loading custom loader ${url}`);
|
||||
execute(reflect.exports);
|
||||
});
|
||||
};
|
||||
} else {
|
||||
loaderInstance = ModuleRequest.loaders.get(format);
|
||||
}
|
||||
job = new ModuleJob(this, url, loaderInstance);
|
||||
this.moduleMap.set(url, job);
|
||||
let loaderInstance;
|
||||
if (format === 'dynamic') {
|
||||
if (typeof this._dynamicInstantiate !== 'function')
|
||||
throw new errors.Error('ERR_MISSING_DYNAMIC_INTSTANTIATE_HOOK');
|
||||
|
||||
loaderInstance = async (url) => {
|
||||
debug(`Translating dynamic ${url}`);
|
||||
const { exports, execute } = await this._dynamicInstantiate(url);
|
||||
return createDynamicModule(exports, url, (reflect) => {
|
||||
debug(`Loading dynamic ${url}`);
|
||||
execute(reflect.exports);
|
||||
});
|
||||
};
|
||||
} else {
|
||||
if (!translators.has(format))
|
||||
throw new errors.RangeError('ERR_UNKNOWN_MODULE_FORMAT', format);
|
||||
|
||||
loaderInstance = translators.get(format);
|
||||
}
|
||||
return job;
|
||||
}
|
||||
|
||||
async import(specifier, parentURL = this.base) {
|
||||
const job = await this.getModuleJob(specifier, parentURL);
|
||||
const module = await job.run();
|
||||
return module.namespace();
|
||||
job = new ModuleJob(this, url, loaderInstance);
|
||||
this.moduleMap.set(url, job);
|
||||
return job;
|
||||
}
|
||||
|
||||
static registerImportDynamicallyCallback(loader) {
|
||||
@ -147,6 +143,6 @@ class Loader {
|
||||
});
|
||||
}
|
||||
}
|
||||
Loader.validFormats = ['esm', 'cjs', 'builtin', 'addon', 'json', 'dynamic'];
|
||||
|
||||
Object.setPrototypeOf(Loader.prototype, null);
|
||||
module.exports = Loader;
|
||||
|
@ -1,138 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const internalCJSModule = require('internal/module');
|
||||
const CJSModule = require('module');
|
||||
const internalURLModule = require('internal/url');
|
||||
const internalFS = require('internal/fs');
|
||||
const NativeModule = require('native_module');
|
||||
const { extname, _makeLong } = require('path');
|
||||
const { URL } = require('url');
|
||||
const { realpathSync } = require('fs');
|
||||
const preserveSymlinks = !!process.binding('config').preserveSymlinks;
|
||||
const {
|
||||
ModuleWrap,
|
||||
createDynamicModule
|
||||
} = require('internal/loader/ModuleWrap');
|
||||
const errors = require('internal/errors');
|
||||
|
||||
const search = require('internal/loader/search');
|
||||
const asyncReadFile = require('util').promisify(require('fs').readFile);
|
||||
const debug = require('util').debuglog('esm');
|
||||
|
||||
const realpathCache = new Map();
|
||||
|
||||
const loaders = new Map();
|
||||
exports.loaders = loaders;
|
||||
|
||||
// Strategy for loading a standard JavaScript module
|
||||
loaders.set('esm', async (url) => {
|
||||
const source = `${await asyncReadFile(new URL(url))}`;
|
||||
debug(`Loading StandardModule ${url}`);
|
||||
return {
|
||||
module: new ModuleWrap(internalCJSModule.stripShebang(source), url),
|
||||
reflect: undefined
|
||||
};
|
||||
});
|
||||
|
||||
// Strategy for loading a node-style CommonJS module
|
||||
const isWindows = process.platform === 'win32';
|
||||
const winSepRegEx = /\//g;
|
||||
loaders.set('cjs', async (url) => {
|
||||
const pathname = internalURLModule.getPathFromURL(new URL(url));
|
||||
const module = CJSModule._cache[
|
||||
isWindows ? pathname.replace(winSepRegEx, '\\') : pathname];
|
||||
if (module && module.loaded) {
|
||||
const ctx = createDynamicModule(['default'], url, undefined);
|
||||
ctx.reflect.exports.default.set(module.exports);
|
||||
return ctx;
|
||||
}
|
||||
return createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading CJSModule ${url}`);
|
||||
CJSModule._load(pathname);
|
||||
});
|
||||
});
|
||||
|
||||
// Strategy for loading a node builtin CommonJS module that isn't
|
||||
// through normal resolution
|
||||
loaders.set('builtin', async (url) => {
|
||||
return createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading BuiltinModule ${url}`);
|
||||
const exports = NativeModule.require(url.substr(5));
|
||||
reflect.exports.default.set(exports);
|
||||
});
|
||||
});
|
||||
|
||||
loaders.set('addon', async (url) => {
|
||||
const ctx = createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading NativeModule ${url}`);
|
||||
const module = { exports: {} };
|
||||
const pathname = internalURLModule.getPathFromURL(new URL(url));
|
||||
process.dlopen(module, _makeLong(pathname));
|
||||
reflect.exports.default.set(module.exports);
|
||||
});
|
||||
return ctx;
|
||||
});
|
||||
|
||||
loaders.set('json', async (url) => {
|
||||
return createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading JSONModule ${url}`);
|
||||
const pathname = internalURLModule.getPathFromURL(new URL(url));
|
||||
const content = fs.readFileSync(pathname, 'utf8');
|
||||
try {
|
||||
const exports = JSON.parse(internalCJSModule.stripBOM(content));
|
||||
reflect.exports.default.set(exports);
|
||||
} catch (err) {
|
||||
err.message = pathname + ': ' + err.message;
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
exports.resolve = (specifier, parentURL) => {
|
||||
if (NativeModule.nonInternalExists(specifier)) {
|
||||
return {
|
||||
url: specifier,
|
||||
format: 'builtin'
|
||||
};
|
||||
}
|
||||
|
||||
let url;
|
||||
try {
|
||||
url = search(specifier, parentURL);
|
||||
} catch (e) {
|
||||
if (e.message && e.message.startsWith('Cannot find module'))
|
||||
e.code = 'MODULE_NOT_FOUND';
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (url.protocol !== 'file:') {
|
||||
throw new errors.Error('ERR_INVALID_PROTOCOL',
|
||||
url.protocol, 'file:');
|
||||
}
|
||||
|
||||
if (!preserveSymlinks) {
|
||||
const real = realpathSync(internalURLModule.getPathFromURL(url), {
|
||||
[internalFS.realpathCacheKey]: realpathCache
|
||||
});
|
||||
const old = url;
|
||||
url = internalURLModule.getURLFromFilePath(real);
|
||||
url.search = old.search;
|
||||
url.hash = old.hash;
|
||||
}
|
||||
|
||||
const ext = extname(url.pathname);
|
||||
switch (ext) {
|
||||
case '.mjs':
|
||||
return { url: `${url}`, format: 'esm' };
|
||||
case '.json':
|
||||
return { url: `${url}`, format: 'json' };
|
||||
case '.node':
|
||||
return { url: `${url}`, format: 'addon' };
|
||||
case '.js':
|
||||
return { url: `${url}`, format: 'cjs' };
|
||||
default:
|
||||
throw new errors.Error('ERR_UNKNOWN_FILE_EXTENSION',
|
||||
internalURLModule.getPathFromURL(url));
|
||||
}
|
||||
};
|
92
lib/internal/loader/Translators.js
Normal file
92
lib/internal/loader/Translators.js
Normal file
@ -0,0 +1,92 @@
|
||||
'use strict';
|
||||
|
||||
const { ModuleWrap } = internalBinding('module_wrap');
|
||||
const NativeModule = require('native_module');
|
||||
const internalCJSModule = require('internal/module');
|
||||
const CJSModule = require('module');
|
||||
const internalURLModule = require('internal/url');
|
||||
const createDynamicModule = require('internal/loader/CreateDynamicModule');
|
||||
const fs = require('fs');
|
||||
const { _makeLong } = require('path');
|
||||
const { SafeMap } = require('internal/safe_globals');
|
||||
const { URL } = require('url');
|
||||
const debug = require('util').debuglog('esm');
|
||||
const readFileAsync = require('util').promisify(fs.readFile);
|
||||
const readFileSync = fs.readFileSync;
|
||||
const StringReplace = Function.call.bind(String.prototype.replace);
|
||||
const JsonParse = JSON.parse;
|
||||
|
||||
const translators = new SafeMap();
|
||||
module.exports = translators;
|
||||
|
||||
// Stragety for loading a standard JavaScript module
|
||||
translators.set('esm', async (url) => {
|
||||
const source = `${await readFileAsync(new URL(url))}`;
|
||||
debug(`Translating StandardModule ${url}`);
|
||||
return {
|
||||
module: new ModuleWrap(internalCJSModule.stripShebang(source), url),
|
||||
reflect: undefined
|
||||
};
|
||||
});
|
||||
|
||||
// Strategy for loading a node-style CommonJS module
|
||||
const isWindows = process.platform === 'win32';
|
||||
const winSepRegEx = /\//g;
|
||||
translators.set('commonjs', async (url) => {
|
||||
debug(`Translating CJSModule ${url}`);
|
||||
const pathname = internalURLModule.getPathFromURL(new URL(url));
|
||||
const module = CJSModule._cache[
|
||||
isWindows ? StringReplace(pathname, winSepRegEx, '\\') : pathname];
|
||||
if (module && module.loaded) {
|
||||
const ctx = createDynamicModule(['default'], url);
|
||||
ctx.reflect.exports.default.set(module.exports);
|
||||
return ctx;
|
||||
}
|
||||
return createDynamicModule(['default'], url, () => {
|
||||
debug(`Loading CJSModule ${url}`);
|
||||
// we don't care about the return val of _load here because Module#load
|
||||
// will handle it for us by checking the loader registry and filling the
|
||||
// exports like above
|
||||
CJSModule._load(pathname);
|
||||
});
|
||||
});
|
||||
|
||||
// Strategy for loading a node builtin CommonJS module that isn't
|
||||
// through normal resolution
|
||||
translators.set('builtin', async (url) => {
|
||||
debug(`Translating BuiltinModule ${url}`);
|
||||
return createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading BuiltinModule ${url}`);
|
||||
const exports = NativeModule.require(url.slice(5));
|
||||
reflect.exports.default.set(exports);
|
||||
});
|
||||
});
|
||||
|
||||
// Stragety for loading a node native module
|
||||
translators.set('addon', async (url) => {
|
||||
debug(`Translating NativeModule ${url}`);
|
||||
return createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading NativeModule ${url}`);
|
||||
const module = { exports: {} };
|
||||
const pathname = internalURLModule.getPathFromURL(new URL(url));
|
||||
process.dlopen(module, _makeLong(pathname));
|
||||
reflect.exports.default.set(module.exports);
|
||||
});
|
||||
});
|
||||
|
||||
// Stragety for loading a JSON file
|
||||
translators.set('json', async (url) => {
|
||||
debug(`Translating JSONModule ${url}`);
|
||||
return createDynamicModule(['default'], url, (reflect) => {
|
||||
debug(`Loading JSONModule ${url}`);
|
||||
const pathname = internalURLModule.getPathFromURL(new URL(url));
|
||||
const content = readFileSync(pathname, 'utf8');
|
||||
try {
|
||||
const exports = JsonParse(internalCJSModule.stripBOM(content));
|
||||
reflect.exports.default.set(exports);
|
||||
} catch (err) {
|
||||
err.message = pathname + ': ' + err.message;
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { URL } = require('url');
|
||||
const CJSmodule = require('module');
|
||||
const errors = require('internal/errors');
|
||||
const { resolve } = internalBinding('module_wrap');
|
||||
|
||||
module.exports = (target, base) => {
|
||||
if (base === undefined) {
|
||||
// We cannot search without a base.
|
||||
throw new errors.Error('ERR_MISSING_MODULE', target);
|
||||
}
|
||||
try {
|
||||
return resolve(target, base);
|
||||
} catch (e) {
|
||||
e.stack; // cause V8 to generate stack before rethrow
|
||||
let error = e;
|
||||
try {
|
||||
const questionedBase = new URL(base);
|
||||
const tmpMod = new CJSmodule(questionedBase.pathname, null);
|
||||
tmpMod.paths = CJSmodule._nodeModulePaths(
|
||||
new URL('./', questionedBase).pathname);
|
||||
const found = CJSmodule._resolveFilename(target, tmpMod);
|
||||
error = new errors.Error('ERR_MODULE_RESOLUTION_LEGACY', target,
|
||||
base, found);
|
||||
} catch (problemChecking) {
|
||||
// ignore
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
@ -45,7 +45,7 @@ module.exports = Module;
|
||||
// these are below module.exports for the circular reference
|
||||
const Loader = require('internal/loader/Loader');
|
||||
const ModuleJob = require('internal/loader/ModuleJob');
|
||||
const { createDynamicModule } = require('internal/loader/ModuleWrap');
|
||||
const createDynamicModule = require('internal/loader/CreateDynamicModule');
|
||||
let ESMLoader;
|
||||
|
||||
function stat(filename) {
|
||||
|
8
node.gyp
8
node.gyp
@ -101,11 +101,11 @@
|
||||
'lib/internal/inspector_async_hook.js',
|
||||
'lib/internal/linkedlist.js',
|
||||
'lib/internal/loader/Loader.js',
|
||||
'lib/internal/loader/ModuleMap.js',
|
||||
'lib/internal/loader/CreateDynamicModule.js',
|
||||
'lib/internal/loader/DefaultResolve.js',
|
||||
'lib/internal/loader/ModuleJob.js',
|
||||
'lib/internal/loader/ModuleWrap.js',
|
||||
'lib/internal/loader/ModuleRequest.js',
|
||||
'lib/internal/loader/search.js',
|
||||
'lib/internal/loader/ModuleMap.js',
|
||||
'lib/internal/loader/Translators.js',
|
||||
'lib/internal/safe_globals.js',
|
||||
'lib/internal/net.js',
|
||||
'lib/internal/module.js',
|
||||
|
@ -10,7 +10,7 @@ const { URL } = require('url');
|
||||
const Loader = require('internal/loader/Loader');
|
||||
const ModuleMap = require('internal/loader/ModuleMap');
|
||||
const ModuleJob = require('internal/loader/ModuleJob');
|
||||
const { createDynamicModule } = require('internal/loader/ModuleWrap');
|
||||
const createDynamicModule = require('internal/loader/CreateDynamicModule');
|
||||
|
||||
const stubModuleUrl = new URL('file://tmp/test');
|
||||
const stubModule = createDynamicModule(['default'], stubModuleUrl);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
const common = require('../common');
|
||||
|
||||
const search = require('internal/loader/search');
|
||||
const { search } = require('internal/loader/DefaultResolve');
|
||||
const errors = require('internal/errors');
|
||||
|
||||
common.expectsError(
|
||||
|
@ -3,19 +3,9 @@ import module from 'module';
|
||||
const builtins = new Set(
|
||||
Object.keys(process.binding('natives')).filter(str =>
|
||||
/^(?!(?:internal|node|v8)\/)/.test(str))
|
||||
)
|
||||
);
|
||||
|
||||
export function resolve (specifier, base, defaultResolver) {
|
||||
if (builtins.has(specifier)) {
|
||||
return {
|
||||
url: `node:${specifier}`,
|
||||
format: 'dynamic'
|
||||
};
|
||||
}
|
||||
return defaultResolver(specifier, base);
|
||||
}
|
||||
|
||||
export async function dynamicInstantiate (url) {
|
||||
export function dynamicInstantiate(url) {
|
||||
const builtinInstance = module._load(url.substr(5));
|
||||
const builtinExports = ['default', ...Object.keys(builtinInstance)];
|
||||
return {
|
||||
@ -27,3 +17,13 @@ export async function dynamicInstantiate (url) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function resolve(specifier, base, defaultResolver) {
|
||||
if (builtins.has(specifier)) {
|
||||
return {
|
||||
url: `node:${specifier}`,
|
||||
format: 'dynamic'
|
||||
};
|
||||
}
|
||||
return defaultResolver(specifier, base);
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ file:///*/test/message/esm_display_syntax_error.mjs:3
|
||||
await async () => 0;
|
||||
^^^^^
|
||||
SyntaxError: Unexpected reserved word
|
||||
at loaders.set (internal/loader/ModuleRequest.js:*:*)
|
||||
at translators.set (internal/loader/Translators.js:*:*)
|
||||
at <anonymous>
|
||||
|
@ -3,5 +3,5 @@ file:///*/test/fixtures/es-module-loaders/syntax-error.mjs:2
|
||||
await async () => 0;
|
||||
^^^^^
|
||||
SyntaxError: Unexpected reserved word
|
||||
at loaders.set (internal/loader/ModuleRequest.js:*:*)
|
||||
at translators.set (internal/loader/Translators.js:*:*)
|
||||
at <anonymous>
|
||||
|
@ -5,7 +5,7 @@ const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const ModuleMap = require('internal/loader/ModuleMap');
|
||||
|
||||
// ModuleMap.get, ModuleMap.has and ModuleMap.set should only accept string
|
||||
// ModuleMap.get, ModuleMap.has and ModuleMap.set should only accept string
|
||||
// values as url argument.
|
||||
{
|
||||
const errorReg = common.expectsError({
|
||||
|
Loading…
x
Reference in New Issue
Block a user