Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ec7bf32

Browse filesBrowse files
GeoffreyBoothjuanarbol
authored andcommitted
esm: move package config helpers
PR-URL: #43967 Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent ec1645b commit ec7bf32
Copy full SHA for ec7bf32

File tree

Expand file treeCollapse file tree

3 files changed

+153
-109
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+153
-109
lines changed
Open diff view settings
Collapse file
+142Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
'use strict';
2+
3+
const {
4+
JSONParse,
5+
SafeMap,
6+
StringPrototypeEndsWith,
7+
} = primordials;
8+
const { URL, fileURLToPath } = require('internal/url');
9+
const {
10+
ERR_INVALID_PACKAGE_CONFIG,
11+
} = require('internal/errors').codes;
12+
13+
const packageJsonReader = require('internal/modules/package_json_reader');
14+
15+
16+
/**
17+
* @typedef {string | string[] | Record<string, unknown>} Exports
18+
* @typedef {'module' | 'commonjs'} PackageType
19+
* @typedef {{
20+
* pjsonPath: string,
21+
* exports?: ExportConfig,
22+
* name?: string,
23+
* main?: string,
24+
* type?: PackageType,
25+
* }} PackageConfig
26+
*/
27+
28+
/** @type {Map<string, PackageConfig>} */
29+
const packageJSONCache = new SafeMap();
30+
31+
32+
/**
33+
* @param {string} path
34+
* @param {string} specifier
35+
* @param {string | URL | undefined} base
36+
* @returns {PackageConfig}
37+
*/
38+
function getPackageConfig(path, specifier, base) {
39+
const existing = packageJSONCache.get(path);
40+
if (existing !== undefined) {
41+
return existing;
42+
}
43+
const source = packageJsonReader.read(path).string;
44+
if (source === undefined) {
45+
const packageConfig = {
46+
pjsonPath: path,
47+
exists: false,
48+
main: undefined,
49+
name: undefined,
50+
type: 'none',
51+
exports: undefined,
52+
imports: undefined,
53+
};
54+
packageJSONCache.set(path, packageConfig);
55+
return packageConfig;
56+
}
57+
58+
let packageJSON;
59+
try {
60+
packageJSON = JSONParse(source);
61+
} catch (error) {
62+
throw new ERR_INVALID_PACKAGE_CONFIG(
63+
path,
64+
(base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier),
65+
error.message
66+
);
67+
}
68+
69+
let { imports, main, name, type } = packageJSON;
70+
const { exports } = packageJSON;
71+
if (typeof imports !== 'object' || imports === null) {
72+
imports = undefined;
73+
}
74+
if (typeof main !== 'string') {
75+
main = undefined;
76+
}
77+
if (typeof name !== 'string') {
78+
name = undefined;
79+
}
80+
// Ignore unknown types for forwards compatibility
81+
if (type !== 'module' && type !== 'commonjs') {
82+
type = 'none';
83+
}
84+
85+
const packageConfig = {
86+
pjsonPath: path,
87+
exists: true,
88+
main,
89+
name,
90+
type,
91+
exports,
92+
imports,
93+
};
94+
packageJSONCache.set(path, packageConfig);
95+
return packageConfig;
96+
}
97+
98+
99+
/**
100+
* @param {URL | string} resolved
101+
* @returns {PackageConfig}
102+
*/
103+
function getPackageScopeConfig(resolved) {
104+
let packageJSONUrl = new URL('./package.json', resolved);
105+
while (true) {
106+
const packageJSONPath = packageJSONUrl.pathname;
107+
if (StringPrototypeEndsWith(packageJSONPath, 'node_modules/package.json')) {
108+
break;
109+
}
110+
const packageConfig = getPackageConfig(fileURLToPath(packageJSONUrl), resolved);
111+
if (packageConfig.exists) {
112+
return packageConfig;
113+
}
114+
115+
const lastPackageJSONUrl = packageJSONUrl;
116+
packageJSONUrl = new URL('../package.json', packageJSONUrl);
117+
118+
// Terminates at root where ../package.json equals ../../package.json
119+
// (can't just check "/package.json" for Windows support).
120+
if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) {
121+
break;
122+
}
123+
}
124+
const packageJSONPath = fileURLToPath(packageJSONUrl);
125+
const packageConfig = {
126+
pjsonPath: packageJSONPath,
127+
exists: false,
128+
main: undefined,
129+
name: undefined,
130+
type: 'none',
131+
exports: undefined,
132+
imports: undefined,
133+
};
134+
packageJSONCache.set(packageJSONPath, packageConfig);
135+
return packageConfig;
136+
}
137+
138+
139+
module.exports = {
140+
getPackageConfig,
141+
getPackageScopeConfig,
142+
};
Collapse file

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

Copy file name to clipboardExpand all lines: lib/internal/modules/esm/resolve.js
+10-109Lines changed: 10 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,16 @@ const {
5959
ERR_NETWORK_IMPORT_DISALLOWED,
6060
ERR_UNSUPPORTED_ESM_URL_SCHEME,
6161
} = require('internal/errors').codes;
62-
const { Module: CJSModule } = require('internal/modules/cjs/loader');
6362

63+
const { Module: CJSModule } = require('internal/modules/cjs/loader');
6464
const packageJsonReader = require('internal/modules/package_json_reader');
65+
const { getPackageConfig, getPackageScopeConfig } = require('internal/modules/esm/package_config');
66+
67+
/**
68+
* @typedef {import('internal/modules/esm/package_config.js').PackageConfig} PackageConfig
69+
*/
70+
71+
6572
const userConditions = getOptionValue('--conditions');
6673
const noAddons = getOptionValue('--no-addons');
6774
const addonConditions = noAddons ? [] : ['node-addons'];
@@ -75,18 +82,6 @@ const DEFAULT_CONDITIONS = ObjectFreeze([
7582

7683
const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);
7784

78-
/**
79-
* @typedef {string | string[] | Record<string, unknown>} Exports
80-
* @typedef {'module' | 'commonjs'} PackageType
81-
* @typedef {{
82-
* pjsonPath: string,
83-
* exports?: ExportConfig,
84-
* name?: string,
85-
* main?: string,
86-
* type?: PackageType,
87-
* }} PackageConfig
88-
*/
89-
9085
const emittedPackageWarnings = new SafeSet();
9186

9287
/**
@@ -179,7 +174,6 @@ function getConditionsSet(conditions) {
179174
}
180175

181176
const realpathCache = new SafeMap();
182-
const packageJSONCache = new SafeMap(); /* string -> PackageConfig */
183177

184178
/**
185179
* @param {string | URL} path
@@ -188,99 +182,6 @@ const packageJSONCache = new SafeMap(); /* string -> PackageConfig */
188182
const tryStatSync =
189183
(path) => statSync(path, { throwIfNoEntry: false }) ?? new Stats();
190184

191-
/**
192-
* @param {string} path
193-
* @param {string} specifier
194-
* @param {string | URL | undefined} base
195-
* @returns {PackageConfig}
196-
*/
197-
function getPackageConfig(path, specifier, base) {
198-
const existing = packageJSONCache.get(path);
199-
if (existing !== undefined) {
200-
return existing;
201-
}
202-
const source = packageJsonReader.read(path).string;
203-
if (source === undefined) {
204-
const packageConfig = {
205-
pjsonPath: path,
206-
exists: false,
207-
main: undefined,
208-
name: undefined,
209-
type: 'none',
210-
exports: undefined,
211-
imports: undefined,
212-
};
213-
packageJSONCache.set(path, packageConfig);
214-
return packageConfig;
215-
}
216-
217-
let packageJSON;
218-
try {
219-
packageJSON = JSONParse(source);
220-
} catch (error) {
221-
throw new ERR_INVALID_PACKAGE_CONFIG(
222-
path,
223-
(base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier),
224-
error.message
225-
);
226-
}
227-
228-
let { imports, main, name, type } = packageJSON;
229-
const { exports } = packageJSON;
230-
if (typeof imports !== 'object' || imports === null) imports = undefined;
231-
if (typeof main !== 'string') main = undefined;
232-
if (typeof name !== 'string') name = undefined;
233-
// Ignore unknown types for forwards compatibility
234-
if (type !== 'module' && type !== 'commonjs') type = 'none';
235-
236-
const packageConfig = {
237-
pjsonPath: path,
238-
exists: true,
239-
main,
240-
name,
241-
type,
242-
exports,
243-
imports,
244-
};
245-
packageJSONCache.set(path, packageConfig);
246-
return packageConfig;
247-
}
248-
249-
/**
250-
* @param {URL | string} resolved
251-
* @returns {PackageConfig}
252-
*/
253-
function getPackageScopeConfig(resolved) {
254-
let packageJSONUrl = new URL('./package.json', resolved);
255-
while (true) {
256-
const packageJSONPath = packageJSONUrl.pathname;
257-
if (StringPrototypeEndsWith(packageJSONPath, 'node_modules/package.json'))
258-
break;
259-
const packageConfig = getPackageConfig(fileURLToPath(packageJSONUrl),
260-
resolved);
261-
if (packageConfig.exists) return packageConfig;
262-
263-
const lastPackageJSONUrl = packageJSONUrl;
264-
packageJSONUrl = new URL('../package.json', packageJSONUrl);
265-
266-
// Terminates at root where ../package.json equals ../../package.json
267-
// (can't just check "/package.json" for Windows support).
268-
if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) break;
269-
}
270-
const packageJSONPath = fileURLToPath(packageJSONUrl);
271-
const packageConfig = {
272-
pjsonPath: packageJSONPath,
273-
exists: false,
274-
main: undefined,
275-
name: undefined,
276-
type: 'none',
277-
exports: undefined,
278-
imports: undefined,
279-
};
280-
packageJSONCache.set(packageJSONPath, packageConfig);
281-
return packageConfig;
282-
}
283-
284185
/**
285186
* @param {string | URL} url
286187
* @returns {boolean}
@@ -634,7 +535,7 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
634535

635536
/**
636537
*
637-
* @param {Exports} exports
538+
* @param {import('internal/modules/esm/package_config.js').Exports} exports
638539
* @param {URL} packageJSONUrl
639540
* @param {string | URL | undefined} base
640541
* @returns {boolean}
@@ -838,7 +739,7 @@ function packageImportsResolve(name, base, conditions) {
838739

839740
/**
840741
* @param {URL} url
841-
* @returns {PackageType}
742+
* @returns {import('internal/modules/esm/package_config.js').PackageType}
842743
*/
843744
function getPackageType(url) {
844745
const packageConfig = getPackageScopeConfig(url);
Collapse file

‎test/parallel/test-bootstrap-modules.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-bootstrap-modules.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const expectedModules = new Set([
8484
'NativeModule internal/modules/esm/loader',
8585
'NativeModule internal/modules/esm/module_job',
8686
'NativeModule internal/modules/esm/module_map',
87+
'NativeModule internal/modules/esm/package_config',
8788
'NativeModule internal/modules/esm/resolve',
8889
'NativeModule internal/modules/esm/translators',
8990
'NativeModule internal/modules/package_json_reader',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.