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 c0d2098

Browse filesBrowse files
GeoffreyBoothdanielleadams
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 3af44c6 commit c0d2098
Copy full SHA for c0d2098

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
@@ -58,9 +58,16 @@ const {
5858
ERR_NETWORK_IMPORT_DISALLOWED,
5959
ERR_UNSUPPORTED_ESM_URL_SCHEME,
6060
} = require('internal/errors').codes;
61-
const { Module: CJSModule } = require('internal/modules/cjs/loader');
6261

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

7582
const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);
7683

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

9186
function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) {
@@ -154,7 +149,6 @@ function getConditionsSet(conditions) {
154149
}
155150

156151
const realpathCache = new SafeMap();
157-
const packageJSONCache = new SafeMap(); /* string -> PackageConfig */
158152

159153
/**
160154
* @param {string | URL} path
@@ -163,99 +157,6 @@ const packageJSONCache = new SafeMap(); /* string -> PackageConfig */
163157
const tryStatSync =
164158
(path) => statSync(path, { throwIfNoEntry: false }) ?? new Stats();
165159

166-
/**
167-
* @param {string} path
168-
* @param {string} specifier
169-
* @param {string | URL | undefined} base
170-
* @returns {PackageConfig}
171-
*/
172-
function getPackageConfig(path, specifier, base) {
173-
const existing = packageJSONCache.get(path);
174-
if (existing !== undefined) {
175-
return existing;
176-
}
177-
const source = packageJsonReader.read(path).string;
178-
if (source === undefined) {
179-
const packageConfig = {
180-
pjsonPath: path,
181-
exists: false,
182-
main: undefined,
183-
name: undefined,
184-
type: 'none',
185-
exports: undefined,
186-
imports: undefined,
187-
};
188-
packageJSONCache.set(path, packageConfig);
189-
return packageConfig;
190-
}
191-
192-
let packageJSON;
193-
try {
194-
packageJSON = JSONParse(source);
195-
} catch (error) {
196-
throw new ERR_INVALID_PACKAGE_CONFIG(
197-
path,
198-
(base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier),
199-
error.message
200-
);
201-
}
202-
203-
let { imports, main, name, type } = packageJSON;
204-
const { exports } = packageJSON;
205-
if (typeof imports !== 'object' || imports === null) imports = undefined;
206-
if (typeof main !== 'string') main = undefined;
207-
if (typeof name !== 'string') name = undefined;
208-
// Ignore unknown types for forwards compatibility
209-
if (type !== 'module' && type !== 'commonjs') type = 'none';
210-
211-
const packageConfig = {
212-
pjsonPath: path,
213-
exists: true,
214-
main,
215-
name,
216-
type,
217-
exports,
218-
imports,
219-
};
220-
packageJSONCache.set(path, packageConfig);
221-
return packageConfig;
222-
}
223-
224-
/**
225-
* @param {URL | string} resolved
226-
* @returns {PackageConfig}
227-
*/
228-
function getPackageScopeConfig(resolved) {
229-
let packageJSONUrl = new URL('./package.json', resolved);
230-
while (true) {
231-
const packageJSONPath = packageJSONUrl.pathname;
232-
if (StringPrototypeEndsWith(packageJSONPath, 'node_modules/package.json'))
233-
break;
234-
const packageConfig = getPackageConfig(fileURLToPath(packageJSONUrl),
235-
resolved);
236-
if (packageConfig.exists) return packageConfig;
237-
238-
const lastPackageJSONUrl = packageJSONUrl;
239-
packageJSONUrl = new URL('../package.json', packageJSONUrl);
240-
241-
// Terminates at root where ../package.json equals ../../package.json
242-
// (can't just check "/package.json" for Windows support).
243-
if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) break;
244-
}
245-
const packageJSONPath = fileURLToPath(packageJSONUrl);
246-
const packageConfig = {
247-
pjsonPath: packageJSONPath,
248-
exists: false,
249-
main: undefined,
250-
name: undefined,
251-
type: 'none',
252-
exports: undefined,
253-
imports: undefined,
254-
};
255-
packageJSONCache.set(packageJSONPath, packageConfig);
256-
return packageConfig;
257-
}
258-
259160
/**
260161
* @param {string | URL} url
261162
* @returns {boolean}
@@ -609,7 +510,7 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath,
609510

610511
/**
611512
*
612-
* @param {Exports} exports
513+
* @param {import('internal/modules/esm/package_config.js').Exports} exports
613514
* @param {URL} packageJSONUrl
614515
* @param {string | URL | undefined} base
615516
* @returns {boolean}
@@ -799,7 +700,7 @@ function packageImportsResolve(name, base, conditions) {
799700

800701
/**
801702
* @param {URL} url
802-
* @returns {PackageType}
703+
* @returns {import('internal/modules/esm/package_config.js').PackageType}
803704
*/
804705
function getPackageType(url) {
805706
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
@@ -85,6 +85,7 @@ const expectedModules = new Set([
8585
'NativeModule internal/modules/esm/loader',
8686
'NativeModule internal/modules/esm/module_job',
8787
'NativeModule internal/modules/esm/module_map',
88+
'NativeModule internal/modules/esm/package_config',
8889
'NativeModule internal/modules/esm/resolve',
8990
'NativeModule internal/modules/esm/translators',
9091
'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.