Skip to content

Commit 3e9012a

Browse files
addaleaxMylesBorins
authored andcommitted
esm: port loader code to JS
There is no reason for this to be in C++. Using JavaScript means that the code is more accessible to more developers, which is important for any Node.js feature. This also simplifies the code significantly in some areas. On the technical side, this potentially also enables making some of the file system operations that are involved asynchronous. PR-URL: #32201 Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com>
1 parent fa1fa31 commit 3e9012a

9 files changed

Lines changed: 657 additions & 1020 deletions

File tree

‎lib/internal/errors.js‎

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,29 +1074,50 @@ E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s', TypeError);
10741074
E('ERR_INVALID_HANDLE_TYPE','This handle type cannot be sent',TypeError);
10751075
E('ERR_INVALID_HTTP_TOKEN','%s must be a valid HTTP token ["%s"]',TypeError);
10761076
E('ERR_INVALID_IP_ADDRESS','Invalid IP address: %s',TypeError);
1077-
E('ERR_INVALID_MODULE_SPECIFIER',(pkgPath,subpath)=>{
1078-
assert(subpath!=='.');
1079-
return`Package subpath '${subpath}' is not a valid module request for the `+
1080-
`"exports" resolution of ${pkgPath}${sep}package.json`;
1077+
E('ERR_INVALID_MODULE_SPECIFIER',(pkgPath,subpath,base=undefined)=>{
1078+
if(subpath===undefined){
1079+
return`Invalid package name '${pkgPath}' imported from ${base}`;
1080+
}elseif(base===undefined){
1081+
assert(subpath!=='.');
1082+
return`Package subpath '${subpath}' is not a valid module request for `+
1083+
`the "exports" resolution of ${pkgPath}${sep}package.json`;
1084+
}else{
1085+
return`Package subpath '${subpath}' is not a valid module request for `+
1086+
`the "exports" resolution of ${pkgPath} imported from ${base}`;
1087+
}
10811088
},TypeError);
10821089
E('ERR_INVALID_OPT_VALUE',(name,value)=>
10831090
`The value "${String(value)}" is invalid for option "${name}"`,
10841091
TypeError,
10851092
RangeError);
10861093
E('ERR_INVALID_OPT_VALUE_ENCODING',
10871094
'The value "%s" is invalid for option "encoding"',TypeError);
1088-
E('ERR_INVALID_PACKAGE_CONFIG',
1089-
`Invalid package config %s${sep}package.json, %s`,Error);
1090-
E('ERR_INVALID_PACKAGE_TARGET',(pkgPath,key,subpath,target)=>{
1091-
if(key==='.'){
1092-
return`Invalid "exports" main target ${JSONStringify(target)} defined `+
1095+
E('ERR_INVALID_PACKAGE_CONFIG',(path,message,hasMessage=true)=>{
1096+
if(hasMessage)
1097+
return`Invalid package config ${path}${sep}package.json, ${message}`;
1098+
else
1099+
return`Invalid JSON in ${path} imported from ${message}`;
1100+
},Error);
1101+
E('ERR_INVALID_PACKAGE_TARGET',
1102+
(pkgPath,key,subpath,target,base=undefined)=>{
1103+
if(key===null){
1104+
if(subpath!==''){
1105+
return`Invalid "exports" target ${JSONStringify(target)} defined `+
1106+
`for '${subpath}' in the package config ${pkgPath} imported from `+
1107+
base;
1108+
}else{
1109+
return`Invalid "exports" main target ${target} defined in the `+
1110+
`package config ${pkgPath} imported from ${base}.`;
1111+
}
1112+
}elseif(key==='.'){
1113+
return`Invalid "exports" main target ${JSONStringify(target)} defined `+
10931114
`in the package config ${pkgPath}${sep}package.json`;
1094-
}else{
1095-
return`Invalid "exports" target ${JSONStringify(target)} defined for '${
1096-
StringPrototypeSlice(key,0,-subpath.length||key.length)}' in the `+
1115+
}else{
1116+
return`Invalid "exports" target ${JSONStringify(target)} defined for '${
1117+
StringPrototypeSlice(key,0,-subpath.length||key.length)}' in the `+
10971118
`package config ${pkgPath}${sep}package.json`;
1098-
}
1099-
},Error);
1119+
}
1120+
},Error);
11001121
E('ERR_INVALID_PERFORMANCE_MARK',
11011122
'The "%s" performance mark has not been set',Error);
11021123
E('ERR_INVALID_PROTOCOL',
@@ -1207,6 +1228,9 @@ E('ERR_MISSING_DYNAMIC_INSTANTIATE_HOOK',
12071228
'The ES Module loader may not return a format of \'dynamic\' when no '+
12081229
'dynamicInstantiate function was provided',Error);
12091230
E('ERR_MISSING_OPTION','%s is required',TypeError);
1231+
E('ERR_MODULE_NOT_FOUND',(path,base,type='package')=>{
1232+
return`Cannot find ${type} '${path}' imported from ${base}`;
1233+
},Error);
12101234
E('ERR_MULTIPLE_CALLBACK','Callback called multiple times',Error);
12111235
E('ERR_NAPI_CONS_FUNCTION','Constructor must be a function',TypeError);
12121236
E('ERR_NAPI_INVALID_DATAVIEW_ARGS',
@@ -1241,12 +1265,15 @@ E('ERR_OUT_OF_RANGE',
12411265
msg+=` It must be ${range}. Received ${received}`;
12421266
returnmsg;
12431267
},RangeError);
1244-
E('ERR_PACKAGE_PATH_NOT_EXPORTED',(pkgPath,subpath)=>{
1268+
E('ERR_PACKAGE_PATH_NOT_EXPORTED',(pkgPath,subpath,base=undefined)=>{
12451269
if(subpath==='.'){
12461270
return`No "exports" main resolved in ${pkgPath}${sep}package.json`;
1247-
}else{
1271+
}elseif(base===undefined){
12481272
return`Package subpath '${subpath}' is not defined by "exports" in ${
12491273
pkgPath}${sep}package.json`;
1274+
}else{
1275+
return`Package subpath '${subpath}' is not defined by "exports" in ${
1276+
pkgPath} imported from ${base}`;
12501277
}
12511278
},Error);
12521279
E('ERR_REQUIRE_ESM',

‎lib/internal/modules/esm/get_format.js‎

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
'use strict';
2-
2+
const{ StringPrototypeStartsWith }=primordials;
33
const{ extname }=require('path');
44
const{ getOptionValue }=require('internal/options');
55

66
constexperimentalJsonModules=getOptionValue('--experimental-json-modules');
77
constexperimentalSpeciferResolution=
88
getOptionValue('--experimental-specifier-resolution');
99
constexperimentalWasmModules=getOptionValue('--experimental-wasm-modules');
10-
const{ getPackageType }=internalBinding('module_wrap');
10+
const{ getPackageType }=require('internal/modules/esm/resolve');
1111
const{URL, fileURLToPath }=require('internal/url');
1212
const{ERR_UNKNOWN_FILE_EXTENSION}=require('internal/errors').codes;
1313

14-
// const TYPE_NONE = 0;
15-
// const TYPE_COMMONJS = 1;
16-
constTYPE_MODULE=2;
17-
1814
constextensionFormatMap={
1915
'__proto__': null,
2016
'.cjs': 'commonjs',
@@ -37,8 +33,8 @@ if (experimentalWasmModules)
3733
if(experimentalJsonModules)
3834
extensionFormatMap['.json']=legacyExtensionFormatMap['.json']='json';
3935

40-
functiondefaultGetFormat(url,context,defaultGetFormat){
41-
if(url.startsWith('nodejs:')){
36+
functiondefaultGetFormat(url,context,defaultGetFormatUnused){
37+
if(StringPrototypeStartsWith(url,'nodejs:')){
4238
return{format: 'builtin'};
4339
}
4440
constparsed=newURL(url);
@@ -55,8 +51,7 @@ function defaultGetFormat(url, context, defaultGetFormat) {
5551
constext=extname(parsed.pathname);
5652
letformat;
5753
if(ext==='.js'){
58-
format=getPackageType(parsed.href)===TYPE_MODULE ?
59-
'module' : 'commonjs';
54+
format=getPackageType(parsed.href)==='module' ? 'module' : 'commonjs';
6055
}else{
6156
format=extensionFormatMap[ext];
6257
}

0 commit comments

Comments
 (0)