Skip to content

Commit f801dcf

Browse files
committed
Consider .json files internal if they originate from within an esm module
1 parent 0aef38e commit f801dcf

File tree

5 files changed

+99
-46
lines changed

5 files changed

+99
-46
lines changed

.config/rollup.base.config.mjs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,19 @@ import rangesIntersect from 'semver/ranges/intersects.js'
1010
import { readPackageUpSync } from 'read-package-up'
1111
import { purgePolyfills } from 'unplugin-purge-polyfills'
1212

13-
import { readPackageJsonSync } from '../scripts/utils/fs.js'
13+
import { findUpSync } from '../scripts/utils/fs.js'
1414
import {
1515
getPackageName,
1616
getPackageNameEnd,
1717
isEsmId,
1818
normalizeId,
1919
isPackageName,
2020
isBuiltin,
21+
readPackageJsonSync,
2122
resolveId
2223
} from '../scripts/utils/packages.js'
2324
import { escapeRegExp } from '../scripts/utils/regexps.js'
25+
import { normalizePath } from '../scripts/utils/path.js'
2426
import socketModifyPlugin from '../scripts/rollup/socket-modify-plugin.js'
2527

2628
const __dirname = fileURLToPath(new URL('.', import.meta.url))
@@ -30,6 +32,7 @@ const ts = require('rollup-plugin-ts')
3032

3133
const ENTRY_SUFFIX = '?commonjs-entry'
3234
const EXTERNAL_SUFFIX = '?commonjs-external'
35+
const SLASH_NODE_MODULES_SLASH = '/node_modules/'
3336

3437
const builtinAliases = builtinModules.reduce((o, n) => {
3538
o[n] = `node:${n}`
@@ -72,18 +75,33 @@ export default (extendConfig = {}) => {
7275
if (id.endsWith('.cjs')) {
7376
return true
7477
}
75-
if (
76-
id.endsWith('.json') ||
77-
id.endsWith('.mjs') ||
78-
id.endsWith('.mts') ||
79-
id.endsWith('.ts') ||
80-
!isPackageName(id)
81-
) {
78+
if (id.endsWith('.mjs') || id.endsWith('.mts') || id.endsWith('.ts')) {
8279
return false
8380
}
84-
const name = getPackageName(id)
8581
const parentId = parentId_ ? resolveId(parentId_) : undefined
8682
const resolvedId = resolveId(id, parentId)
83+
if (resolvedId.endsWith('.json')) {
84+
let currNmIndex = resolvedId.indexOf(SLASH_NODE_MODULES_SLASH)
85+
while (currNmIndex !== -1) {
86+
const nextNmIndex = resolvedId.indexOf(
87+
SLASH_NODE_MODULES_SLASH,
88+
currNmIndex + 1
89+
)
90+
const currPkgName = resolvedId.slice(
91+
currNmIndex + SLASH_NODE_MODULES_SLASH.length,
92+
nextNmIndex === -1 ? resolvedId.length : nextNmIndex
93+
)
94+
if (isEsmId(currPkgName, parentId)) {
95+
return false
96+
}
97+
currNmIndex = nextNmIndex
98+
}
99+
return true
100+
}
101+
if (!isPackageName(id)) {
102+
return false
103+
}
104+
const name = getPackageName(id)
87105
if (isEsmId(resolvedId, parentId)) {
88106
const parentPkg = parentId
89107
? readPackageUpSync({ cwd: path.dirname(parentId) })?.packageJson
@@ -171,7 +189,7 @@ export default (extendConfig = {}) => {
171189
replace: ''
172190
}),
173191
// Fix incorrectly set "spinners" binding caused by a transpilation bug
174-
// https://github.com/sindresorhus/ora/blob/main/index.js#L416C2-L416C50
192+
// https://github.com/sindresorhus/ora/blob/v8.1.0/index.js#L415
175193
// export {default as spinners} from 'cli-spinners'
176194
socketModifyPlugin({
177195
find: /(?<=ora[^.]+\.spinners\s*=\s*)[$\w]+/g,

.config/rollup.dist.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { chmodSync, readFileSync, writeFileSync } from 'node:fs'
22
import path from 'node:path'
33
import { fileURLToPath } from 'node:url'
44

5-
import { readJsonSync, readPackageJsonSync } from '../scripts/utils/fs.js'
5+
import { readJsonSync } from '../scripts/utils/fs.js'
66
import { formatObject, hasKeys } from '../scripts/utils/objects.js'
7+
import { readPackageJsonSync } from '../scripts/utils/packages.js'
78
import { toSortedObject } from '../scripts/utils/sorts.js'
89

910
import baseConfig from './rollup.base.config.mjs'

scripts/utils/fs.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
'use strict'
22

3-
const { readFileSync } = require('node:fs')
3+
const fs = require('node:fs')
44
const path = require('node:path')
55

6-
const { normalizePackageJson } = require('./packages')
7-
8-
const PACKAGE_JSON = 'package.json'
9-
10-
function readJsonSync(filepath) {
11-
return JSON.parse(readFileSync(filepath, 'utf8'))
6+
function findUpSync(name, { cwd = process.cwd() }) {
7+
let dir = path.resolve(cwd)
8+
const { root } = path.parse(dir)
9+
const names = [name].flat()
10+
while (dir && dir !== root) {
11+
for (const name of names) {
12+
const filePath = path.join(dir, name)
13+
try {
14+
const stats = fs.statSync(filePath)
15+
if (stats.isFile()) {
16+
return filePath
17+
}
18+
} catch {}
19+
}
20+
dir = path.dirname(dir)
21+
}
22+
return undefined
1223
}
1324

14-
function readPackageJsonSync(filepath_) {
15-
const filepath = filepath_.endsWith(PACKAGE_JSON)
16-
? filepath_
17-
: path.join(filepath_, PACKAGE_JSON)
18-
return normalizePackageJson(JSON.parse(readFileSync(filepath, 'utf8')))
25+
function readJsonSync(filepath) {
26+
return JSON.parse(fs.readFileSync(filepath, 'utf8'))
1927
}
2028

2129
module.exports = {
22-
readJsonSync,
23-
readPackageJsonSync
30+
findUpSync,
31+
readJsonSync
2432
}

scripts/utils/packages.js

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
const fs = require('node:fs')
44
const Module = require('node:module')
5+
const path = require('node:path')
56
const vm = require('node:vm')
67

78
const normalizePackageData = require('normalize-package-data')
89
const validatePackageName = require('validate-npm-package-name')
910

10-
const { normalizePath } = require('./path')
11+
const { normalizePath, isRelative } = require('./path')
12+
const { findUpSync } = require('./fs')
1113

1214
const { createRequire, isBuiltin } = Module
1315

16+
const PACKAGE_JSON = 'package.json'
17+
1418
const cjsPluginPrefixRegExp = /^\x00/
1519
const cjsPluginSuffixRegExp =
1620
/\?commonjs-(?:entry|es-import|exports|external|module|proxy|wrapped)$/
@@ -38,12 +42,12 @@ function resolveId(id_, req = require) {
3842
}
3943
if (req !== require) {
4044
try {
41-
resolvedId = req.resolve(id)
45+
resolvedId = normalizePath(req.resolve(id))
4246
} catch {}
4347
}
4448
if (resolvedId === undefined) {
4549
try {
46-
resolvedId = require.resolve(id)
50+
resolvedId = normalizePath(require.resolve(id))
4751
} catch {}
4852
}
4953
if (resolvedId === undefined) {
@@ -56,27 +60,16 @@ function resolveId(id_, req = require) {
5660
return fs.existsSync(tsId) ? tsId : resolvedId
5761
}
5862

59-
const memoizeIsPackageName = new Map()
60-
6163
function isPackageName(id) {
62-
const memResult = memoizeIsPackageName.get(id)
63-
if (memResult !== undefined) return memResult
64-
const result = validatePackageName(id).validForOldPackages
65-
memoizeIsPackageName.set(id, result)
66-
return result
64+
return validatePackageName(id).validForOldPackages
6765
}
6866

69-
const memoizeIsEsmId = new Map()
70-
7167
function isEsmId(id_, parentId_) {
7268
if (isBuiltin(id_)) {
7369
return false
7470
}
7571
const parentId = parentId_ ? resolveId(parentId_) : undefined
7672
const resolvedId = resolveId(id_, parentId)
77-
const memKey = `${resolvedId}|${parentId}`
78-
const memResult = memoizeIsEsmId.get(memKey)
79-
if (memResult !== undefined) return memResult
8073
let result = false
8174
if (resolvedId.endsWith('.mjs')) {
8275
result = true
@@ -85,15 +78,28 @@ function isEsmId(id_, parentId_) {
8578
!resolvedId.endsWith('.json') &&
8679
!resolvedId.endsWith('.ts')
8780
) {
88-
try {
89-
new vm.Script(fs.readFileSync(resolvedId, 'utf8'))
90-
} catch (e) {
91-
if (e instanceof SyntaxError) {
92-
result = true
81+
let filepath
82+
if (path.isAbsolute(resolvedId)) {
83+
filepath = resolvedId
84+
} else if (parentId && isRelative(resolvedId)) {
85+
filepath = path.join(path.dirname(parentId), resolvedId)
86+
}
87+
if (filepath) {
88+
const pkgJsonPath = findUpSync('package.json', {
89+
cwd: path.dirname(resolvedId)
90+
})
91+
if (pkgJsonPath && require(pkgJsonPath)?.type === 'module') {
92+
return true
93+
}
94+
try {
95+
new vm.Script(fs.readFileSync(resolvedId, 'utf8'))
96+
} catch (e) {
97+
if (e instanceof SyntaxError) {
98+
result = true
99+
}
93100
}
94101
}
95102
}
96-
memoizeIsEsmId.set(memKey, result)
97103
return result
98104
}
99105

@@ -108,6 +114,13 @@ function normalizePackageJson(pkgJson) {
108114
return pkgJson
109115
}
110116

117+
function readPackageJsonSync(filepath_) {
118+
const filepath = filepath_.endsWith(PACKAGE_JSON)
119+
? filepath_
120+
: path.join(filepath_, PACKAGE_JSON)
121+
return normalizePackageJson(JSON.parse(fs.readFileSync(filepath, 'utf8')))
122+
}
123+
111124
module.exports = {
112125
isBuiltin,
113126
isEsmId,
@@ -116,5 +129,6 @@ module.exports = {
116129
getPackageNameEnd,
117130
normalizeId,
118131
normalizePackageJson,
132+
readPackageJsonSync,
119133
resolveId
120134
}

scripts/utils/path.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ const { search } = require('./strings')
44

55
const slashRegExp = /[/\\]/
66

7+
function isRelative(filepath) {
8+
if (typeof filepath === 'string' && filepath.charCodeAt(0) === 46 /*'.'*/) {
9+
if (filepath.length === 1) {
10+
return true
11+
}
12+
const code1 = filepath.charCodeAt(1)
13+
return code1 === 47 /*'/'*/ || code1 === 92 /*'\\'*/
14+
}
15+
return false
16+
}
17+
718
function normalizePath(filePath) {
819
const { length } = filePath
920
if (length < 2) {
@@ -72,5 +83,6 @@ function normalizePath(filePath) {
7283
}
7384

7485
module.exports = {
86+
isRelative,
7587
normalizePath
7688
}

0 commit comments

Comments
 (0)