mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 00:20:08 +01:00
esm: do not interpret "main" as a URL
As documented, its value is a path. PR-URL: https://github.com/nodejs/node/pull/55003 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
parent
fbc6fcb018
commit
fb852798dc
|
|
@ -22,6 +22,7 @@ const {
|
||||||
StringPrototypeStartsWith,
|
StringPrototypeStartsWith,
|
||||||
encodeURIComponent,
|
encodeURIComponent,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
const assert = require('internal/assert');
|
||||||
const internalFS = require('internal/fs/utils');
|
const internalFS = require('internal/fs/utils');
|
||||||
const { BuiltinModule } = require('internal/bootstrap/realm');
|
const { BuiltinModule } = require('internal/bootstrap/realm');
|
||||||
const { realpathSync } = require('fs');
|
const { realpathSync } = require('fs');
|
||||||
|
|
@ -117,18 +118,17 @@ function emitInvalidSegmentDeprecation(target, request, match, pjsonUrl, interna
|
||||||
* Emits a deprecation warning if the given URL is a module and
|
* Emits a deprecation warning if the given URL is a module and
|
||||||
* the package.json file does not define a "main" or "exports" field.
|
* the package.json file does not define a "main" or "exports" field.
|
||||||
* @param {URL} url - The URL of the module being resolved.
|
* @param {URL} url - The URL of the module being resolved.
|
||||||
* @param {URL} packageJSONUrl - The URL of the package.json file for the module.
|
* @param {string} path - The path of the module being resolved.
|
||||||
|
* @param {string} pkgPath - The path of the parent dir of the package.json file for the module.
|
||||||
* @param {string | URL} [base] - The base URL for the module being resolved.
|
* @param {string | URL} [base] - The base URL for the module being resolved.
|
||||||
* @param {string} [main] - The "main" field from the package.json file.
|
* @param {string} [main] - The "main" field from the package.json file.
|
||||||
*/
|
*/
|
||||||
function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
|
function emitLegacyIndexDeprecation(url, path, pkgPath, base, main) {
|
||||||
if (process.noDeprecation) {
|
if (process.noDeprecation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const format = defaultGetFormatWithoutErrors(url);
|
const format = defaultGetFormatWithoutErrors(url);
|
||||||
if (format !== 'module') { return; }
|
if (format !== 'module') { return; }
|
||||||
const path = fileURLToPath(url);
|
|
||||||
const pkgPath = fileURLToPath(new URL('.', packageJSONUrl));
|
|
||||||
const basePath = fileURLToPath(base);
|
const basePath = fileURLToPath(base);
|
||||||
if (!main) {
|
if (!main) {
|
||||||
process.emitWarning(
|
process.emitWarning(
|
||||||
|
|
@ -196,20 +196,19 @@ const legacyMainResolveExtensionsIndexes = {
|
||||||
* @returns {URL}
|
* @returns {URL}
|
||||||
*/
|
*/
|
||||||
function legacyMainResolve(packageJSONUrl, packageConfig, base) {
|
function legacyMainResolve(packageJSONUrl, packageConfig, base) {
|
||||||
const packageJsonUrlString = packageJSONUrl.href;
|
assert(isURL(packageJSONUrl));
|
||||||
|
const pkgPath = fileURLToPath(new URL('.', packageJSONUrl));
|
||||||
if (typeof packageJsonUrlString !== 'string') {
|
|
||||||
throw new ERR_INVALID_ARG_TYPE('packageJSONUrl', ['URL'], packageJSONUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseStringified = isURL(base) ? base.href : base;
|
const baseStringified = isURL(base) ? base.href : base;
|
||||||
|
|
||||||
const resolvedOption = FSLegacyMainResolve(packageJsonUrlString, packageConfig.main, baseStringified);
|
const resolvedOption = FSLegacyMainResolve(pkgPath, packageConfig.main, baseStringified);
|
||||||
|
|
||||||
const baseUrl = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ? `./${packageConfig.main}` : '';
|
const maybeMain = resolvedOption <= legacyMainResolveExtensionsIndexes.kResolvedByMainIndexNode ?
|
||||||
const resolvedUrl = new URL(baseUrl + legacyMainResolveExtensions[resolvedOption], packageJSONUrl);
|
packageConfig.main || './' : '';
|
||||||
|
const resolvedPath = resolve(pkgPath, maybeMain + legacyMainResolveExtensions[resolvedOption]);
|
||||||
|
const resolvedUrl = pathToFileURL(resolvedPath);
|
||||||
|
|
||||||
emitLegacyIndexDeprecation(resolvedUrl, packageJSONUrl, base, packageConfig.main);
|
emitLegacyIndexDeprecation(resolvedUrl, resolvedPath, pkgPath, base, packageConfig.main);
|
||||||
|
|
||||||
return resolvedUrl;
|
return resolvedUrl;
|
||||||
}
|
}
|
||||||
|
|
@ -790,8 +789,8 @@ function packageResolve(specifier, base, conditions) {
|
||||||
// ResolveSelf
|
// ResolveSelf
|
||||||
const packageConfig = packageJsonReader.getPackageScopeConfig(base);
|
const packageConfig = packageJsonReader.getPackageScopeConfig(base);
|
||||||
if (packageConfig.exists) {
|
if (packageConfig.exists) {
|
||||||
const packageJSONUrl = pathToFileURL(packageConfig.pjsonPath);
|
|
||||||
if (packageConfig.exports != null && packageConfig.name === packageName) {
|
if (packageConfig.exports != null && packageConfig.name === packageName) {
|
||||||
|
const packageJSONUrl = pathToFileURL(packageConfig.pjsonPath);
|
||||||
return packageExportsResolve(
|
return packageExportsResolve(
|
||||||
packageJSONUrl, packageSubpath, packageConfig, base, conditions);
|
packageJSONUrl, packageSubpath, packageConfig, base, conditions);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3331,37 +3331,18 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
auto isolate = env->isolate();
|
auto isolate = env->isolate();
|
||||||
|
|
||||||
Utf8Value utf8_package_json_url(isolate, args[0]);
|
auto utf8_package_path = Utf8Value(isolate, args[0]).ToString();
|
||||||
auto package_json_url =
|
|
||||||
ada::parse<ada::url_aggregator>(utf8_package_json_url.ToStringView());
|
|
||||||
|
|
||||||
if (!package_json_url) {
|
|
||||||
THROW_ERR_INVALID_URL(isolate, "Invalid URL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string package_initial_file = "";
|
std::string package_initial_file = "";
|
||||||
|
|
||||||
ada::result<ada::url_aggregator> file_path_url;
|
|
||||||
std::optional<std::string> initial_file_path;
|
std::optional<std::string> initial_file_path;
|
||||||
std::string file_path;
|
std::string file_path;
|
||||||
|
|
||||||
if (args.Length() >= 2 && args[1]->IsString()) {
|
if (args.Length() >= 2 && args[1]->IsString()) {
|
||||||
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
|
auto package_config_main = Utf8Value(isolate, args[1]).ToString();
|
||||||
|
|
||||||
file_path_url = ada::parse<ada::url_aggregator>(
|
initial_file_path =
|
||||||
std::string("./") + package_config_main, &package_json_url.value());
|
PathResolve(env, {utf8_package_path, package_config_main});
|
||||||
|
|
||||||
if (!file_path_url) {
|
|
||||||
THROW_ERR_INVALID_URL(isolate, "Invalid URL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initial_file_path = node::url::FileURLToPath(env, *file_path_url);
|
|
||||||
if (!initial_file_path.has_value()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FromNamespacedPath(&initial_file_path.value());
|
FromNamespacedPath(&initial_file_path.value());
|
||||||
|
|
||||||
package_initial_file = *initial_file_path;
|
package_initial_file = *initial_file_path;
|
||||||
|
|
@ -3392,15 +3373,7 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo<Value>& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file_path_url =
|
initial_file_path = PathResolve(env, {utf8_package_path, "./index"});
|
||||||
ada::parse<ada::url_aggregator>("./index", &package_json_url.value());
|
|
||||||
|
|
||||||
if (!file_path_url) {
|
|
||||||
THROW_ERR_INVALID_URL(isolate, "Invalid URL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initial_file_path = node::url::FileURLToPath(env, *file_path_url);
|
|
||||||
if (!initial_file_path.has_value()) {
|
if (!initial_file_path.has_value()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ describe('legacyMainResolve', () => {
|
||||||
{},
|
{},
|
||||||
''
|
''
|
||||||
),
|
),
|
||||||
{ message: /instance of URL/, code: 'ERR_INVALID_ARG_TYPE' },
|
{ code: 'ERR_INTERNAL_ASSERTION' },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -166,4 +166,12 @@ describe('legacyMainResolve', () => {
|
||||||
{ message: /"base" argument must be/, code: 'ERR_INVALID_ARG_TYPE' },
|
{ message: /"base" argument must be/, code: 'ERR_INVALID_ARG_TYPE' },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should interpret main as a path, not a URL', () => {
|
||||||
|
const packageJsonUrl = fixtures.fileURL('/es-modules/legacy-main-resolver/package.json');
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
legacyMainResolve(packageJsonUrl, { main: '../folder%25with percentage#/' }, packageJsonUrl),
|
||||||
|
fixtures.fileURL('/es-modules/folder%25with percentage#/index.js'),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user