Skip to content

Commit

Permalink
Update to latest copy-paste of node's ESM resolve implementation (#1167)
Browse files Browse the repository at this point in the history
* add raw/* copy of latest node's latest esm resolve.js for convenient diffing

* auto-applied patch; needs manual application of rejected hunks

* Merge latest dist-raw from node v15.3.0

* replace optional chaining operator with legacy replacement compatible with node 13

* fix broken import

* fix botched merge

* More copy-pasting from node's source code; add test coverage for reading package.json exports field
  • Loading branch information
cspotcode committed Dec 1, 2020
1 parent c11aa8a commit c4a6a02
Show file tree
Hide file tree
Showing 21 changed files with 1,530 additions and 283 deletions.
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,4 +1,5 @@
node_modules/
/node_modules/
/tests/node_modules/
.nyc_output/
coverage/
.DS_Store
Expand Down
30 changes: 8 additions & 22 deletions dist-raw/node-cjs-loader-utils.js
Expand Up @@ -3,12 +3,13 @@
// Each function and variable below must have a comment linking to the source in node's github repo.

const path = require('path');
const fs = require('fs');
const packageJsonReader = require('./node-package-json-reader');
const {JSONParse} = require('./node-primordials');

module.exports.assertScriptCanLoadAsCJSImpl = assertScriptCanLoadAsCJSImpl;

// copied from Module._extensions['.js']
// https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L1211-L1217
// https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/cjs/loader.js#L1113-L1120
function assertScriptCanLoadAsCJSImpl(filename) {
const pkg = readPackageScope(filename);
// Function require shouldn't be used in ES modules.
Expand Down Expand Up @@ -41,31 +42,27 @@ function readPackageScope(checkPath) {
// Copied from https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L249
const packageJsonCache = new Map();

// Copied from https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/modules/cjs/loader.js#L251-L283
// Copied from https://github.com/nodejs/node/blob/v15.3.0/lib/internal/modules/cjs/loader.js#L275-L304
function readPackage(requestPath) {
const jsonPath = path.resolve(requestPath, 'package.json');

const existing = packageJsonCache.get(jsonPath);
if (existing !== undefined) return existing;

const json = internalModuleReadJSON(path.toNamespacedPath(jsonPath));
const result = packageJsonReader.read(jsonPath);
const json = result.containsKeys === false ? '{}' : result.string;
if (json === undefined) {
packageJsonCache.set(jsonPath, false);
return false;
}

// TODO Related to `--experimental-policy`? Disabling for now
// if (manifest) {
// const jsonURL = pathToFileURL(jsonPath);
// manifest.assertIntegrity(jsonURL, json);
// }

try {
const parsed = JSON.parse(json);
const parsed = JSONParse(json);
const filtered = {
name: parsed.name,
main: parsed.main,
exports: parsed.exports,
imports: parsed.imports,
type: parsed.type
};
packageJsonCache.set(jsonPath, filtered);
Expand All @@ -77,17 +74,6 @@ function readPackage(requestPath) {
}
}

// In node's core, this is implemented in C
// https://github.com/nodejs/node/blob/e9f293750760d59243020d0376edf242c9a26b67/src/node_file.cc#L845-L939
function internalModuleReadJSON(path) {
try {
return fs.readFileSync(path, 'utf8')
} catch (e) {
if (e.code === 'ENOENT') return undefined
throw e
}
}

// Native ERR_REQUIRE_ESM Error is declared here:
// https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L1294-L1313
// Error class factory is implemented here:
Expand Down
21 changes: 21 additions & 0 deletions dist-raw/node-errors.js
@@ -0,0 +1,21 @@
exports.codes = {
ERR_INPUT_TYPE_NOT_ALLOWED: createErrorCtor('ERR_INPUT_TYPE_NOT_ALLOWED'),
ERR_INVALID_ARG_VALUE: createErrorCtor('ERR_INVALID_ARG_VALUE'),
ERR_INVALID_MODULE_SPECIFIER: createErrorCtor('ERR_INVALID_MODULE_SPECIFIER'),
ERR_INVALID_PACKAGE_CONFIG: createErrorCtor('ERR_INVALID_PACKAGE_CONFIG'),
ERR_INVALID_PACKAGE_TARGET: createErrorCtor('ERR_INVALID_PACKAGE_TARGET'),
ERR_MANIFEST_DEPENDENCY_MISSING: createErrorCtor('ERR_MANIFEST_DEPENDENCY_MISSING'),
ERR_MODULE_NOT_FOUND: createErrorCtor('ERR_MODULE_NOT_FOUND'),
ERR_PACKAGE_IMPORT_NOT_DEFINED: createErrorCtor('ERR_PACKAGE_IMPORT_NOT_DEFINED'),
ERR_PACKAGE_PATH_NOT_EXPORTED: createErrorCtor('ERR_PACKAGE_PATH_NOT_EXPORTED'),
ERR_UNSUPPORTED_DIR_IMPORT: createErrorCtor('ERR_UNSUPPORTED_DIR_IMPORT'),
ERR_UNSUPPORTED_ESM_URL_SCHEME: createErrorCtor('ERR_UNSUPPORTED_ESM_URL_SCHEME'),
}

function createErrorCtor(name) {
return class CustomError extends Error {
constructor(...args) {
super([name, ...args].join(' '))
}
}
}

0 comments on commit c4a6a02

Please sign in to comment.