Skip to content
This repository was archived by the owner on Apr 16, 2020. It is now read-only.

Commit a5f3284

Browse files
committed
folder main reversion, error unification
1 parent 1a021ec commit a5f3284

File tree

9 files changed

+75
-140
lines changed

9 files changed

+75
-140
lines changed

doc/api/errors.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,26 +1369,19 @@ a `dynamicInstantiate` hook.
13691369
A `MessagePort` was found in the object passed to a `postMessage()` call,
13701370
but not provided in the `transferList` for that call.
13711371

1372-
<a id="ERR_MISSING_MODULE"></a>
1373-
### ERR_MISSING_MODULE
1374-
1375-
> Stability: 1 - Experimental
1376-
1377-
An [ES6 module][] could not be resolved.
1378-
13791372
<a id="ERR_MISSING_PLATFORM_FOR_WORKER"></a>
13801373
### ERR_MISSING_PLATFORM_FOR_WORKER
13811374

13821375
The V8 platform used by this instance of Node.js does not support creating
13831376
Workers. This is caused by lack of embedder support for Workers. In particular,
13841377
this error will not occur with standard builds of Node.js.
13851378

1386-
<a id="ERR_MODULE_RESOLUTION_LEGACY"></a>
1387-
### ERR_MODULE_RESOLUTION_LEGACY
1379+
<a id="ERR_MODULE_NOT_FOUND"></a>
1380+
### ERR_MODULE_NOT_FOUND
13881381

13891382
> Stability: 1 - Experimental
13901383
1391-
A failure occurred resolving imports in an [ES6 module][].
1384+
An [ESM module][] could not be resolved.
13921385

13931386
<a id="ERR_MULTIPLE_CALLBACK"></a>
13941387
### ERR_MULTIPLE_CALLBACK

doc/api/esm.md

Lines changed: 24 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ The resolver has the following properties:
152152
* Support for builtin module loading
153153
* Relative and absolute URL resolution
154154
* No default extensions
155+
* No folder mains
155156
* Bare specifier package resolution lookup through node_modules
156157
* Avoids the package fallback which breaks package isolation. This is the
157158
problem that an import to `x/y.js` will keep checking subsequent node_modules
@@ -174,59 +175,43 @@ Relative and absolute resolution without directory or extension resolution
174175
(URL resolution):
175176
176177
* ESM_RESOLVE("./a.asdf", "file:///parent/path") -> "file:///parent/a.asdf"
177-
* ESMRESOLVE("/a", "file:///parent/path") -> "file:///a"
178-
* ESMRESOLVE("file:///a", "file:///parent/path") -> "file:///a"
178+
* ESM_RESOLVE("/a", "file:///parent/path") -> "file:///a"
179+
* ESM_RESOLVE("file:///a", "file:///parent/path") -> "file:///a"
179180
180181
Package resolution:
181182
182-
1. ESMRESOLVE("pkg/x", "file:///path/to/project") ->
183+
1. ESM_RESOLVE("pkg/x", "file:///path/to/project") ->
183184
"file:///path/to/nodemodules/pkg/x" (if it exists)
184-
1. ESMRESOLVE("pkg/x", "file:///path/to/project") ->
185+
1. ESM_RESOLVE("pkg/x", "file:///path/to/project") ->
185186
Not Found otherwise, even if "file:///path/nodemodules/pkg/x" exists.
186187
187-
Main resolution:
188-
189-
1. ESMRESOLVE("pkg", "file:///path/to/project") ->
190-
"file:///path/to/project/nodemodules/pkg/index.mjs" (if it exists)
191-
1. ESMRESOLVE("pkg", "file:///path/to/project") -> Not Found otherwise,
192-
even if "file:///path/to/nodemodules/pkg/index.mjs" exists.
193-
1. ESMRESOLVE("file:///path/to/project") ->
194-
"file:///path/to/project/index.mjs" (if it exists)
195-
1. ESMRESOLVE("file:///path/to/project") ->
196-
Not Found, if "file:///path/to/project/index.mjs" does not exist.
197-
198188
### Resolver Algorithm
199189
200190
The algorithm to resolve an ES module specifier is provided through
201191
_ESM_RESOLVE_:
202192
203193
**ESM_RESOLVE**(_specifier_, _parentURL_)
194+
> 1. Let _resolvedURL_ be _undefined_.
204195
> 1. If _specifier_ is a valid URL then,
205-
> 1. Let _resolvedURL_ be the result of parsing and reserializing
196+
> 1. Set _resolvedURL_ to the result of parsing and reserializing
206197
> _specifier_ as a URL.
207-
> 1. Return the result of **PATH_RESOLVE**(_resolvedURL_).
208-
> 1. If _specifier_ starts with _"/"_, _"./"_ or _"../"_ then,
209-
> 1. Let _resolvedURL_ be the URL resolution of _specifier_ to _parentURL_.
210-
> 1. Return the result of **PATH_RESOLVE**(_resolvedURL_).
211-
> 1. Note: _specifier_ is now a bare specifier.
212-
> 1. Return the result of **PACKAGE_RESOLVE**(_specifier_, _parentURL_).
213-
214-
**PATH_RESOLVE**(_resolvedURL_)
215-
> 1. If the file at _resolvedURL_ exists then,
216-
> 1. Return _resolvedURL_.
217-
> 1. Let _packageMainURL_ be the result of
218-
> **PACKAGE_MAIN_RESOLVE**(_resolvedURL_).
219-
> 1. If _packageMainURL_ is not _undefined_ then,
220-
> 1. Return _packageMainURL_.
221-
> 1. Throw a _Module Not Found_ error.
198+
> 1. Otherwise, if _specifier_ starts with _"/"_, _"./"_ or _"../"_ then,
199+
> 1. Set _resolvedURL_ to the URL resolution of _specifier_ to _parentURL_.
200+
> 1. Otherwise,
201+
> 1. Note: _specifier_ is now a bare specifier.
202+
> 1. Set _resolvedURL_ the result of
203+
> **PACKAGE_RESOLVE**(_specifier_, _parentURL_).
204+
> 1. If the file at _resolvedURL_ does not exist then,
205+
> 1. Throw a _Module Not Found_ error.
206+
> 1. Return _resolvedURL_.
222207
223208
**PACKAGE_RESOLVE**(_packageSpecifier_, _parentURL_)
224209
> 1. Assert: _packageSpecifier_ is a bare specifier.
225-
> 1. If _packageSpecifier_ is an empty string then,
226-
> 1. Throw a _Module Not Found_ error.
227210
> 1. Let _packageName_ be _undefined_.
228211
> 1. Let _packagePath_ be _undefined_.
229212
> 1. If _packageSpecifier_ does not start with _"@"_ then,
213+
> 1. If _packageSpecifier_ is an empty string then,
214+
> 1. Throw a _Invalid Package Name_ error.
230215
> 1. Set _packageName_ to the substring of _packageSpecifier_ until the
231216
> first _"/"_ separator or the end of the string.
232217
> 1. If _packageSpecifier_ starts with _"@"_ then,
@@ -239,7 +224,7 @@ _ESM_RESOLVE_:
239224
> 1. Assert: _packageName_ is a valid package name or scoped package name.
240225
> 1. Assert: _packagePath_ is either empty, or a path without a leading
241226
> separator.
242-
> 1. Note: Further package name encoding validations can be added here.
227+
> 1. Note: Further package name validations can be added here.
243228
> 1. If _packagePath_ is empty and _packageName_ is a Node.js builtin
244229
> module then,
245230
> 1. Return _"node:${packageName}"_.
@@ -254,23 +239,15 @@ _ESM_RESOLVE_:
254239
> 1. Continue the next loop iteration.
255240
> 1. If _packagePath_ is empty then,
256241
> 1. Let _url_ be the result of **PACKAGE_MAIN_RESOLVE**(_packageURL_).
257-
> 1. If _url_ is not _undefined_ then,
258-
> 1. Return _url_.
242+
> 1. If _url_ is _undefined_ then,
243+
> 1. Throw a _Module Not Found_ error.
244+
> 1. Return _url_.
259245
> 1. Otherwise,
260-
> 1. Let _url_ be equal to the URL resolution of _packagePath_ in
261-
> _packageURL_.
262-
> 1. If the file at _url_ exists then,
263-
> 1. Return _url_.
264-
> 1. Otherwise, if _url_ is a directory then,
265-
> 1. Let _url_ be the result of **PACKAGE_MAIN_RESOLVE**(_url_).
266-
> 1. If _url_ is not _undefined_ then,
267-
> 1. Return _url_.
268-
> 1. Throw a _Module Not Found_ error.
246+
> 1. Return the URL resolution of _packagePath_ in _packageURL_.
269247
> 1. Throw a _Module Not Found_ error.
270248
271249
**PACKAGE_MAIN_RESOLVE**(_packageURL_)
272-
> 1. If the file at _"${packageURL}/index.mjs"_ exists then,
273-
> 1. Return _"${packageURL}/index.mjs"_.
250+
> 1. Note: Main resolution to be implemented here.
274251
> 1. Return _undefined_.
275252
276253

lib/internal/errors.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -762,11 +762,13 @@ E('ERR_MISSING_ARGS',
762762
E('ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK',
763763
'The ES Module loader may not return a format of \'dynamic\' when no ' +
764764
'dynamicInstantiate function was provided', Error);
765-
E('ERR_MISSING_MODULE', 'Cannot find module %s', Error);
766-
E('ERR_MODULE_RESOLUTION_LEGACY',
767-
'Cannot find module \'%s\' imported from %s.' +
768-
' Legacy behavior in require() would have found it at %s',
769-
Error);
765+
E('ERR_MODULE_NOT_FOUND', (module, base, legacyResolution) => {
766+
let msg = `Cannot find module '${module}' imported from ${base}.`;
767+
if (legacyResolution)
768+
msg += ' Legacy behavior in require() would have found it at ' +
769+
legacyResolution;
770+
return msg;
771+
}, Error);
770772
E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times', Error);
771773
E('ERR_NAPI_CONS_FUNCTION', 'Constructor must be a function', TypeError);
772774
E('ERR_NAPI_INVALID_DATAVIEW_ARGS',
@@ -859,7 +861,8 @@ E('ERR_UNKNOWN_CREDENTIAL', '%s identifier does not exist: %s', Error);
859861
E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError);
860862

861863
// This should probably be a `TypeError`.
862-
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: %s', Error);
864+
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: \'%s\' imported ' +
865+
'from %s', Error);
863866
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
864867
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
865868
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type', Error);

lib/internal/modules/esm/default_resolve.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ const { realpathSync } = require('fs');
99
const preserveSymlinks = !!process.binding('config').preserveSymlinks;
1010
const preserveSymlinksMain = !!process.binding('config').preserveSymlinksMain;
1111
const {
12-
ERR_MISSING_MODULE,
13-
ERR_MODULE_RESOLUTION_LEGACY,
12+
ERR_MODULE_NOT_FOUND,
1413
ERR_UNKNOWN_FILE_EXTENSION
1514
} = require('internal/errors').codes;
1615
const { resolve: moduleWrapResolve } = internalBinding('module_wrap');
@@ -19,10 +18,6 @@ const { pathToFileURL, fileURLToPath } = require('internal/url');
1918
const realpathCache = new Map();
2019

2120
function search(target, base) {
22-
if (base === undefined) {
23-
// We cannot search without a base.
24-
throw new ERR_MISSING_MODULE(target);
25-
}
2621
try {
2722
return moduleWrapResolve(target, base);
2823
} catch (e) {
@@ -34,8 +29,7 @@ function search(target, base) {
3429
tmpMod.paths = CJSmodule._nodeModulePaths(
3530
new URL('./', questionedBase).pathname);
3631
const found = CJSmodule._resolveFilename(target, tmpMod);
37-
error = new ERR_MODULE_RESOLUTION_LEGACY(target,
38-
fileURLToPath(base), found);
32+
error = new ERR_MODULE_NOT_FOUND(target, fileURLToPath(base), found);
3933
} catch {
4034
// ignore
4135
}
@@ -78,12 +72,11 @@ function resolve(specifier, parentURL) {
7872
if (isMain)
7973
format = 'cjs';
8074
else
81-
throw new ERR_UNKNOWN_FILE_EXTENSION(url.pathname);
75+
throw new ERR_UNKNOWN_FILE_EXTENSION(url.pathname,
76+
fileURLToPath(parentURL));
8277
}
8378

8479
return { url: `${url}`, format };
8580
}
8681

8782
module.exports = resolve;
88-
// exported for tests
89-
module.exports.search = search;

src/module_wrap.cc

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -486,26 +486,21 @@ DescriptorType CheckDescriptor(const std::string& path) {
486486
}
487487

488488
inline Maybe<URL> PackageMainResolve(const URL& search) {
489-
std::string path = search.path();
490-
std::string last_segment = path.substr(path.find_last_of('/') + 1);
491-
URL main_url = URL("./" + last_segment + "/index.mjs", search);
492-
if (CheckDescriptor(main_url.ToFilePath()) == FILE)
493-
return Just(main_url);
494489
return Nothing<URL>();
495490
}
496491

497492
Maybe<URL> PackageResolve(Environment* env,
498493
const std::string& specifier,
499494
const URL& base) {
500-
if (specifier.length() == 0) return Nothing<URL>();
501495
size_t sep_index = specifier.find('/');
496+
if (specifier[0] == '@' && sep_index == std::string::npos ||
497+
specifier.length() == 0) {
498+
std::string msg = "Invalid package name '" + specifier +
499+
"' imported from " + base.ToFilePath();
500+
node::THROW_ERR_INVALID_PACKAGE_NAME(env, msg.c_str());
501+
return Nothing<URL>();
502+
}
502503
if (specifier[0] == '@') {
503-
if (sep_index == std::string::npos) {
504-
std::string msg = "Invalid package name '" + specifier +
505-
"' imported from " + base.ToFilePath();
506-
node::THROW_ERR_INVALID_PACKAGE_NAME(env, msg.c_str());
507-
return Nothing<URL>();
508-
}
509504
sep_index = specifier.find('/', sep_index + 1);
510505
}
511506
std::string pkg_name = specifier.substr(0,
@@ -527,24 +522,21 @@ Maybe<URL> PackageResolve(Environment* env,
527522
} else {
528523
url = pkg_url;
529524
}
525+
DescriptorType check;
530526
if (pkg_path.length()) {
531527
DescriptorType check = CheckDescriptor(url.ToFilePath());
532-
if (check == FILE) {
533-
return Just(url);
534-
} else if (check == DIRECTORY) {
535-
Maybe<URL> main_url = PackageMainResolve(url);
536-
if (!main_url.IsNothing()) return main_url;
537-
}
528+
if (check == FILE) return Just(url);
529+
if (check == NONE) check = CheckDescriptor(pkg_url.ToFilePath());
538530
} else {
539531
Maybe<URL> main_url = PackageMainResolve(url);
540532
if (!main_url.IsNothing()) return main_url;
533+
check = CheckDescriptor(pkg_url.ToFilePath());
541534
}
542535
// throw not found if we did match a package directory
543-
DescriptorType check = CheckDescriptor(pkg_url.ToFilePath());
544536
if (check == DIRECTORY) {
545537
std::string msg = "Cannot find module '" + url.ToFilePath() +
546538
"' imported from " + base.ToFilePath();
547-
node::THROW_ERR_MISSING_MODULE(env, msg.c_str());
539+
node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
548540
return Nothing<URL>();
549541
}
550542
last_path = parent.path();
@@ -554,38 +546,32 @@ Maybe<URL> PackageResolve(Environment* env,
554546
return Nothing<URL>();
555547
}
556548

557-
Maybe<URL> PathResolve(Environment* env,
558-
const URL& url,
559-
const URL& base) {
560-
std::string path = url.ToFilePath();
561-
DescriptorType check = CheckDescriptor(path);
562-
if (check == FILE) return Just(url);
563-
564-
if (check == DIRECTORY) {
565-
Maybe<URL> url_main = PackageMainResolve(url);
566-
if (!url_main.IsNothing()) return url_main;
567-
}
568-
569-
std::string msg = "Cannot find module '" + path +
570-
"' imported from " + base.ToFilePath();
571-
node::THROW_ERR_MISSING_MODULE(env, msg.c_str());
572-
return Nothing<URL>();
573-
}
574-
575549
} // anonymous namespace
576550

577551
Maybe<URL> Resolve(Environment* env,
578552
const std::string& specifier,
579553
const URL& base) {
580-
URL pure_url(specifier);
581-
if (!(pure_url.flags() & URL_FLAGS_FAILED)) {
582-
return PathResolve(env, pure_url, base);
583-
}
554+
// Order swapped from spec for minor perf gain.
555+
// Ok since relative URLs cannot parse as URLs.
556+
URL resolved;
584557
if (ShouldBeTreatedAsRelativeOrAbsolutePath(specifier)) {
585-
URL resolved(specifier, base);
586-
return PathResolve(env, resolved, base);
558+
resolved = URL(specifier, base);
559+
} else {
560+
URL pure_url(specifier);
561+
if (!(pure_url.flags() & URL_FLAGS_FAILED)) {
562+
resolved = pure_url;
563+
} else {
564+
return PackageResolve(env, specifier, base);
565+
}
566+
}
567+
DescriptorType check = CheckDescriptor(resolved.ToFilePath());
568+
if (check != FILE) {
569+
std::string msg = "Cannot find module '" + resolved.ToFilePath() +
570+
"' imported from " + base.ToFilePath();
571+
node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
572+
return Nothing<URL>();
587573
}
588-
return PackageResolve(env, specifier, base);
574+
return Just(resolved);
589575
}
590576

591577
void ModuleWrap::Resolve(const FunctionCallbackInfo<Value>& args) {
@@ -616,7 +602,7 @@ void ModuleWrap::Resolve(const FunctionCallbackInfo<Value>& args) {
616602
(result.FromJust().flags() & URL_FLAGS_FAILED)) {
617603
std::string msg = "Cannot find module '" + specifier_std +
618604
"' imported from " + url.ToFilePath();
619-
node::THROW_ERR_MISSING_MODULE(env, msg.c_str());
605+
node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
620606
try_catch.ReThrow();
621607
return;
622608
}

src/node_errors.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ namespace node {
3333
V(ERR_MEMORY_ALLOCATION_FAILED, Error) \
3434
V(ERR_MISSING_ARGS, TypeError) \
3535
V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST, TypeError) \
36-
V(ERR_MISSING_MODULE, Error) \
3736
V(ERR_MISSING_PLATFORM_FOR_WORKER, Error) \
37+
V(ERR_MODULE_NOT_FOUND, Error) \
3838
V(ERR_OUT_OF_RANGE, RangeError) \
3939
V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error) \
4040
V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error) \

test/es-module/test-esm-dynamic-import.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function expectErrorProperty(result, propertyKey, value) {
1919
}
2020

2121
function expectMissingModuleError(result) {
22-
expectErrorProperty(result, 'code', 'MODULE_NOT_FOUND');
22+
expectErrorProperty(result, 'code', 'ERR_MODULE_NOT_FOUND');
2323
}
2424

2525
function expectInvalidUrlError(result) {

test/es-module/test-esm-loader-search.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)