mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.2 KiB
104 lines
3.2 KiB
'use strict';
|
|
|
|
const { URL } = require('url');
|
|
const internalCJSModule = require('internal/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 {
|
|
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();
|
|
|
|
class ModuleRequest {
|
|
constructor(url) {
|
|
this.url = url;
|
|
}
|
|
}
|
|
Object.setPrototypeOf(ModuleRequest.prototype, null);
|
|
|
|
// Strategy for loading a standard JavaScript module
|
|
class StandardModuleRequest extends ModuleRequest {
|
|
async createModule() {
|
|
const source = `${await asyncReadFile(this.url)}`;
|
|
debug(`Loading StandardModule ${this.url}`);
|
|
return new ModuleWrap(internalCJSModule.stripShebang(source),
|
|
`${this.url}`);
|
|
}
|
|
}
|
|
|
|
// Strategy for loading a node-style CommonJS module
|
|
class CJSModuleRequest extends ModuleRequest {
|
|
async createModule() {
|
|
const ctx = createDynamicModule(['default'], this.url, (reflect) => {
|
|
debug(`Loading CJSModule ${this.url.pathname}`);
|
|
const CJSModule = require('module');
|
|
const pathname = internalURLModule.getPathFromURL(this.url);
|
|
CJSModule._load(pathname);
|
|
});
|
|
this.finish = (module) => {
|
|
ctx.reflect.exports.default.set(module.exports);
|
|
};
|
|
return ctx.module;
|
|
}
|
|
}
|
|
|
|
// Strategy for loading a node builtin CommonJS module that isn't
|
|
// through normal resolution
|
|
class NativeModuleRequest extends CJSModuleRequest {
|
|
async createModule() {
|
|
const ctx = createDynamicModule(['default'], this.url, (reflect) => {
|
|
debug(`Loading NativeModule ${this.url.pathname}`);
|
|
const exports = require(this.url.pathname);
|
|
reflect.exports.default.set(exports);
|
|
});
|
|
return ctx.module;
|
|
}
|
|
}
|
|
|
|
const normalizeBaseURL = (baseURLOrString) => {
|
|
if (baseURLOrString instanceof URL) return baseURLOrString;
|
|
if (typeof baseURLOrString === 'string') return new URL(baseURLOrString);
|
|
return undefined;
|
|
};
|
|
|
|
const resolveRequestUrl = (baseURLOrString, specifier) => {
|
|
if (NativeModule.nonInternalExists(specifier)) {
|
|
return new NativeModuleRequest(new URL(`node:${specifier}`));
|
|
}
|
|
|
|
const baseURL = normalizeBaseURL(baseURLOrString);
|
|
let url = search(specifier, baseURL);
|
|
|
|
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);
|
|
if (ext === '.mjs') {
|
|
return new StandardModuleRequest(url);
|
|
}
|
|
|
|
return new CJSModuleRequest(url);
|
|
};
|
|
module.exports = resolveRequestUrl;
|
|
|