diff options
author | Daniele Belardi <dwon.dnl@gmail.com> | 2020-07-16 10:27:53 +0300 |
---|---|---|
committer | Guy Bedford <guybedford@gmail.com> | 2020-07-23 17:50:01 +0300 |
commit | ec2ffd6b9d255e19818b6949d2f7dc7ac70faee9 (patch) | |
tree | 8518bccb2e89ade8c3d19f16ba30af0bd46a2ad1 /lib/internal/modules | |
parent | 6d5c33525ac5962ae95e6a2883b2bbf78ac935e6 (diff) |
module: self referential modules in repl or `-r`
Load self referential modules from the repl and using the preload flag
`-r`. In both cases the base path used for resolution is the current
`process.cwd()`. Also fixes an internal cycle bug in the REPL exports
resolution.
PR-URL: https://github.com/nodejs/node/pull/32261
Fixes: https://github.com/nodejs/node/issues/31595
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
Diffstat (limited to 'lib/internal/modules')
-rw-r--r-- | lib/internal/modules/cjs/loader.js | 34 | ||||
-rw-r--r-- | lib/internal/modules/esm/loader.js | 3 | ||||
-rw-r--r-- | lib/internal/modules/esm/resolve.js | 3 |
3 files changed, 32 insertions, 8 deletions
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index eba9a54641b..de24f6c409c 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -29,6 +29,7 @@ module.exports = { const { ArrayIsArray, + ArrayPrototypeJoin, Error, JSONParse, Map, @@ -422,7 +423,23 @@ function findLongestRegisteredExtension(filename) { return '.js'; } +function trySelfParentPath(parent) { + if (!parent) return false; + + if (parent.filename) { + return parent.filename; + } else if (parent.id === '<repl>' || parent.id === 'internal/preload') { + try { + return process.cwd() + path.sep; + } catch { + return false; + } + } +} + function trySelf(parentPath, request) { + if (!parentPath) return false; + const { data: pkg, path: basePath } = readPackageScope(parentPath) || {}; if (!pkg || pkg.exports === undefined) return false; if (typeof pkg.name !== 'string') return false; @@ -1053,13 +1070,16 @@ Module._resolveFilename = function(request, parent, isMain, options) { } } } - const filename = trySelf(parent.filename, request); - if (filename) { - const cacheKey = request + '\x00' + - (paths.length === 1 ? paths[0] : paths.join('\x00')); - Module._pathCache[cacheKey] = filename; - return filename; - } + } + + // Try module self resoultion first + const parentPath = trySelfParentPath(parent); + const selfResolved = trySelf(parentPath, request); + if (selfResolved) { + const cacheKey = request + '\x00' + + (paths.length === 1 ? paths[0] : ArrayPrototypeJoin(paths, '\x00')); + Module._pathCache[cacheKey] = selfResolved; + return selfResolved; } // Look up the filename first, since that's the cache key. diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index de08845a820..37191f65bf0 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -1,5 +1,8 @@ 'use strict'; +// This is needed to avoid cycles in esm/resolve <-> cjs/loader +require('internal/modules/cjs/loader'); + const { FunctionPrototypeBind, ObjectSetPrototypeOf, diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 16ca78880c7..7ea59f30c68 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -32,7 +32,6 @@ const { } = require('fs'); const { getOptionValue } = require('internal/options'); const { sep, relative } = require('path'); -const { Module: CJSModule } = require('internal/modules/cjs/loader'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); const typeFlag = getOptionValue('--input-type'); @@ -49,11 +48,13 @@ const { ERR_UNSUPPORTED_DIR_IMPORT, ERR_UNSUPPORTED_ESM_URL_SCHEME, } = require('internal/errors').codes; +const { Module: CJSModule } = require('internal/modules/cjs/loader'); const packageJsonReader = require('internal/modules/package_json_reader'); const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import']); const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); + function getConditionsSet(conditions) { if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { if (!ArrayIsArray(conditions)) { |