Skip to content

Commit 5266a57

Browse files
committed
Share common dist/constants.js between builds
1 parent 3fe9c77 commit 5266a57

File tree

8 files changed

+129
-118
lines changed

8 files changed

+129
-118
lines changed

.config/rollup.base.config.mjs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const customResolver = nodeResolve({
6666
})
6767

6868
const requireAssignmentsRegExp =
69-
/(?<=\s*=\s*)require\(["'].+?["']\)(?=;?\r?\n)/g
69+
/(?<=\s*=\s*)require\(["'](?!node:|@socket(?:registry|security)\/|\.).+?["']\)(?=;?\r?\n)/g
7070
const checkRequireAssignmentRegExp = new RegExp(
7171
requireAssignmentsRegExp.source,
7272
''
@@ -216,13 +216,6 @@ export default function baseConfig(extendConfig = {}) {
216216
purgePolyfills.rollup({
217217
replacements: {}
218218
}),
219-
// Convert REPLACED_WITH_SOCKET_PACKAGE_NAME to the Socket package name.
220-
replace({
221-
preventAssignment: false,
222-
values: {
223-
REPLACED_WITH_SOCKET_PACKAGE_NAME: rootPackageJson.name
224-
}
225-
}),
226219
// Convert un-prefixed built-in imports into "node:"" prefixed forms.
227220
replace({
228221
delimiters: ['(?<=(?:require\\(|from\\s*)["\'])', '(?=["\'])'],
@@ -257,6 +250,13 @@ export default function baseConfig(extendConfig = {}) {
257250
)
258251
}
259252
}),
253+
commonjs({
254+
extensions: ['.cjs', '.js', '.ts', `.ts${ROLLUP_ENTRY_SUFFIX}`],
255+
ignoreDynamicRequires: true,
256+
ignoreGlobal: true,
257+
ignoreTryCatch: true,
258+
strictRequires: 'auto'
259+
}),
260260
// Wrap require calls with SOCKET_INTEROP helper.
261261
socketModifyPlugin({
262262
find: requireAssignmentsRegExp,
@@ -280,13 +280,6 @@ function ${SOCKET_INTEROP}(e) {
280280
: match
281281
}
282282
}),
283-
commonjs({
284-
extensions: ['.cjs', '.js', '.ts', `.ts${ROLLUP_ENTRY_SUFFIX}`],
285-
ignoreDynamicRequires: true,
286-
ignoreGlobal: true,
287-
ignoreTryCatch: true,
288-
strictRequires: 'auto'
289-
}),
290283
...(extendConfig.plugins ?? [])
291284
]
292285
}
@@ -300,29 +293,33 @@ function ${SOCKET_INTEROP}(e) {
300293
).map(o => ({
301294
...o,
302295
chunkFileNames: '[name].js',
303-
manualChunks(id) {
304-
if (id.includes(SLASH_NODE_MODULES_SLASH)) {
296+
manualChunks(id_) {
297+
const id = normalizeId(id_)
298+
if (
299+
id.includes(SLASH_NODE_MODULES_SLASH) &&
300+
!id.includes('@babel/runtime/')
301+
) {
305302
return 'vendor'
306303
}
307304
}
308305
}))
309306

310307
// Replace hard-coded absolute paths in source with hard-coded relative paths.
311-
const replacePlugin = replace({
312-
delimiters: ['(?<=["\'])', '/'],
313-
preventAssignment: false,
314-
values: {
315-
[rootPath]: '../../'
316-
}
317-
})
318-
const replaceOutputPlugin = {
319-
name: replacePlugin.name,
320-
renderChunk: replacePlugin.renderChunk
321-
}
308+
const replaceAbsPathsOutputPlugin = (() => {
309+
const { name, renderChunk } = replace({
310+
delimiters: ['(?<=["\'])', '/'],
311+
preventAssignment: false,
312+
values: {
313+
[rootPath]: '../../'
314+
}
315+
})
316+
return { name, renderChunk }
317+
})()
318+
322319
for (const o of output) {
323320
o.plugins = [
324321
...(Array.isArray(o.plugins) ? o.plugins : []),
325-
replaceOutputPlugin
322+
replaceAbsPathsOutputPlugin
326323
]
327324
}
328325

.config/rollup.dist.config.mjs

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { chmodSync, existsSync, writeFileSync } from 'node:fs'
1+
import {
2+
chmodSync,
3+
copyFileSync,
4+
existsSync,
5+
readFileSync,
6+
writeFileSync
7+
} from 'node:fs'
28
import path from 'node:path'
39

410
import { toSortedObject } from '@socketsecurity/registry/lib/objects'
@@ -26,15 +32,88 @@ const {
2632
rootSrcPath
2733
} = constants
2834

35+
const CONSTANTS_JS = 'constants.js'
36+
2937
const distModuleSyncPath = path.join(rootDistPath, 'module-sync')
3038
const distRequirePath = path.join(rootDistPath, 'require')
3139

3240
const binBasenames = ['cli.js', 'npm-cli.js', 'npx-cli.js']
3341
const editablePkgJson = readPackageJsonSync(rootPath, { editable: true })
3442

35-
function setBinPerm(filepath) {
36-
// Make file chmod +x.
37-
chmodSync(filepath, 0o755)
43+
function copyConstantsModuleSync(srcPath, destPath) {
44+
copyFileSync(
45+
path.join(srcPath, CONSTANTS_JS),
46+
path.join(destPath, CONSTANTS_JS)
47+
)
48+
}
49+
50+
function modifyConstantsModuleExportsSync(distPath) {
51+
const filepath = path.join(distPath, CONSTANTS_JS)
52+
let code = readFileSync(filepath, 'utf8')
53+
code = code
54+
// Remove @babel/runtime helpers from code.
55+
.replace(
56+
/function getDefaultExportFromCjs[\s\S]+?constants\$\d+\.default = void 0;?\n/,
57+
''
58+
)
59+
// Remove @babel/runtime and @rollup/commonjs interop from code.
60+
.replace(/^(?:exports.[$\w]+|[$\w]+\.default)\s*=.*(?:\n|$)/gm, '')
61+
code = code + 'module.exports = constants\n'
62+
writeFileSync(filepath, code, 'utf8')
63+
}
64+
65+
function rewriteConstantsModuleSync(distPath) {
66+
writeFileSync(
67+
path.join(distPath, CONSTANTS_JS),
68+
`'use strict'\n\nmodule.exports = require('../constants.js')\n`,
69+
'utf8'
70+
)
71+
}
72+
73+
function setBinPermsSync(distPath) {
74+
for (const binBasename of binBasenames) {
75+
// Make file chmod +x.
76+
chmodSync(path.join(distPath, binBasename), 0o755)
77+
}
78+
}
79+
80+
function updateDepStatsSync(depStats) {
81+
const { content: pkgJson } = editablePkgJson
82+
const oldDepStats = existsSync(depStatsPath)
83+
? readJsonSync(depStatsPath)
84+
: undefined
85+
Object.assign(depStats.dependencies, {
86+
// Manually add @cyclonedx/cdxgen and synp as they are not directly
87+
// referenced in the code but used through spawned processes.
88+
'@cyclonedx/cdxgen': pkgJson.dependencies['@cyclonedx/cdxgen'],
89+
synp: pkgJson.dependencies.synp,
90+
// Assign old dep stats dependencies to preserve them.
91+
...oldDepStats?.dependencies
92+
})
93+
// Remove transitives from dependencies.
94+
for (const key of Object.keys(oldDepStats?.transitives ?? {})) {
95+
if (pkgJson.dependencies[key]) {
96+
depStats.transitives[key] = pkgJson.dependencies[key]
97+
depStats.external[key] = pkgJson.dependencies[key]
98+
delete depStats.dependencies[key]
99+
}
100+
}
101+
depStats.dependencies = toSortedObject(depStats.dependencies)
102+
depStats.devDependencies = toSortedObject(depStats.devDependencies)
103+
depStats.esm = toSortedObject(depStats.esm)
104+
depStats.external = toSortedObject(depStats.external)
105+
depStats.transitives = toSortedObject(depStats.transitives)
106+
// Write dep stats.
107+
writeFileSync(depStatsPath, `${formatObject(depStats)}\n`, 'utf8')
108+
// Update dependencies with additional inlined modules.
109+
editablePkgJson
110+
.update({
111+
dependencies: {
112+
...depStats.dependencies,
113+
...depStats.transitives
114+
}
115+
})
116+
.saveSync()
38117
}
39118

40119
export default () => {
@@ -76,9 +155,10 @@ export default () => {
76155
plugins: [
77156
{
78157
writeBundle() {
79-
for (const binBasename of binBasenames) {
80-
setBinPerm(path.join(distModuleSyncPath, binBasename))
81-
}
158+
setBinPermsSync(distModuleSyncPath)
159+
copyConstantsModuleSync(distModuleSyncPath, rootDistPath)
160+
modifyConstantsModuleExportsSync(rootDistPath)
161+
rewriteConstantsModuleSync(distModuleSyncPath)
82162
}
83163
}
84164
]
@@ -104,46 +184,9 @@ export default () => {
104184
plugins: [
105185
{
106186
writeBundle() {
107-
const { content: pkgJson } = editablePkgJson
108-
const oldDepStats = existsSync(depStatsPath)
109-
? readJsonSync(depStatsPath)
110-
: undefined
111-
const { depStats } = requireConfig.meta
112-
Object.assign(depStats.dependencies, {
113-
// Manually add @cyclonedx/cdxgen and synp as they are not directly
114-
// referenced in the code but used through spawned processes.
115-
'@cyclonedx/cdxgen': pkgJson.dependencies['@cyclonedx/cdxgen'],
116-
synp: pkgJson.dependencies.synp,
117-
// Assign old dep stats dependencies to preserve them.
118-
...oldDepStats?.dependencies
119-
})
120-
// Remove transitives from dependencies.
121-
for (const key of Object.keys(oldDepStats?.transitives ?? {})) {
122-
if (pkgJson.dependencies[key]) {
123-
depStats.transitives[key] = pkgJson.dependencies[key]
124-
depStats.external[key] = pkgJson.dependencies[key]
125-
delete depStats.dependencies[key]
126-
}
127-
}
128-
depStats.dependencies = toSortedObject(depStats.dependencies)
129-
depStats.devDependencies = toSortedObject(depStats.devDependencies)
130-
depStats.esm = toSortedObject(depStats.esm)
131-
depStats.external = toSortedObject(depStats.external)
132-
depStats.transitives = toSortedObject(depStats.transitives)
133-
// Write dep stats.
134-
writeFileSync(depStatsPath, `${formatObject(depStats)}\n`, 'utf8')
135-
// Update dependencies with additional inlined modules.
136-
editablePkgJson
137-
.update({
138-
dependencies: {
139-
...depStats.dependencies,
140-
...depStats.transitives
141-
}
142-
})
143-
.saveSync()
144-
for (const binBasename of binBasenames) {
145-
setBinPerm(path.join(distRequirePath, binBasename))
146-
}
187+
setBinPermsSync(distRequirePath)
188+
rewriteConstantsModuleSync(distRequirePath)
189+
updateDepStatsSync(requireConfig.meta.depStats)
147190
}
148191
}
149192
]

.config/rollup.test.config.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const { ROLLUP_EXTERNAL_SUFFIX, SUPPORTS_SYNC_ESM, rootSrcPath } = constants
1414
export default () =>
1515
baseConfig({
1616
input: {
17-
constants: `${rootSrcPath}/constants.ts`,
1817
misc: `${rootSrcPath}/utils/misc.ts`,
1918
'path-resolve': `${rootSrcPath}/utils/path-resolve.ts`
2019
},

bin/cli.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#!/usr/bin/env node
22
'use strict'
33

4-
const DIST_TYPE = require('semver').satisfies(process.versions.node, '>=22.12')
5-
? 'module-sync'
6-
: 'require'
7-
require(`../dist/${DIST_TYPE}/cli.js`)
4+
const constants = require('../dist/constants')
5+
require(`../dist/${constants.DIST_TYPE}/cli.js`)

bin/npm-cli.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#!/usr/bin/env node
22
'use strict'
33

4-
const DIST_TYPE = require('semver').satisfies(process.versions.node, '>=22.12')
5-
? 'module-sync'
6-
: 'require'
7-
require(`../dist/${DIST_TYPE}/npm-cli.js`)
4+
const constants = require('../dist/constants')
5+
require(`../dist/${constants.DIST_TYPE}/npm-cli.js`)

bin/npx-cli.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#!/usr/bin/env node
22
'use strict'
33

4-
const DIST_TYPE = require('semver').satisfies(process.versions.node, '>=22.12')
5-
? 'module-sync'
6-
: 'require'
7-
require(`../dist/${DIST_TYPE}/npx-cli.js`)
4+
const constants = require('../dist/constants')
5+
require(`../dist/${constants.DIST_TYPE}/npx-cli.js`)

src/constants.ts

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { existsSync, realpathSync } from 'node:fs'
1+
import { realpathSync } from 'node:fs'
22
import path from 'node:path'
33

44
import { envAsBoolean } from '@socketsecurity/registry/lib/env'
@@ -29,33 +29,7 @@ const ENV = Object.freeze({
2929
)
3030
})
3131

32-
// Dynamically detect the rootPath so constants.ts can be used in tests.
33-
const rootPath = (() => {
34-
let oldPath
35-
let currPath = realpathSync(__dirname)
36-
// Dirname stops when at the filepath root, e.g. '/' for posix and 'C:\\' for win32,
37-
// so `currPath` equal `oldPath`.
38-
while (currPath !== oldPath) {
39-
const pkgJsonPath = path.join(currPath, PACKAGE_JSON)
40-
if (existsSync(pkgJsonPath)) {
41-
try {
42-
// Content matching REPLACED_WITH_SOCKET_PACKAGE_NAME is replaced by
43-
// the @rollup/plugin-replace plugin used in .config/rollup.base.config.mjs
44-
// with either 'socket' or '@socketsecurity/cli'.
45-
if (
46-
require(pkgJsonPath)?.name === 'REPLACED_WITH_SOCKET_PACKAGE_NAME'
47-
) {
48-
return currPath
49-
}
50-
} catch {}
51-
}
52-
oldPath = currPath
53-
currPath = path.dirname(currPath)
54-
}
55-
throw new TypeError(
56-
`Socket CLI initialization error: rootPath cannot be resolved.\n\nPlease report to ${SOCKET_CLI_ISSUES_URL}.`
57-
)
58-
})()
32+
const rootPath = path.resolve(realpathSync(__dirname), '..')
5933
const rootDistPath = path.join(rootPath, 'dist')
6034
const rootBinPath = path.join(rootPath, 'bin')
6135
const rootPkgJsonPath = path.join(rootPath, PACKAGE_JSON)
@@ -66,6 +40,7 @@ const synpBinPath = path.join(nmBinPath, 'synp')
6640
const LAZY_DIST_TYPE = () =>
6741
registryConstants.SUPPORTS_NODE_REQUIRE_MODULE ? 'module-sync' : 'require'
6842

43+
const lazyConstants = () => constants
6944
const lazyDistPath = () => path.join(rootDistPath, constants.DIST_TYPE)
7045
const lazyShadowBinPath = () =>
7146
path.join(rootPath, 'shadow', constants.DIST_TYPE)
@@ -98,6 +73,7 @@ const constants = <
9873
SOCKET_CLI_ISSUES_URL,
9974
UPDATE_SOCKET_OVERRIDES_IN_PACKAGE_LOCK_FILE,
10075
cdxgenBinPath,
76+
constants: undefined,
10177
distPath: undefined,
10278
nmBinPath,
10379
rootBinPath,
@@ -110,6 +86,8 @@ const constants = <
11086
{
11187
getters: {
11288
DIST_TYPE: LAZY_DIST_TYPE,
89+
// Preserve rollup chunk compatibility.
90+
constants: lazyConstants,
11391
distPath: lazyDistPath,
11492
shadowBinPath: lazyShadowBinPath
11593
},

test/socket-cdxgen.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { describe, it } from 'node:test'
33

44
import spawn from '@npmcli/promise-spawn'
55

6-
import constants from './dist/constants'
6+
import constants from '../dist/constants'
77

88
type PromiseSpawnOptions = Exclude<Parameters<typeof spawn>[2], undefined> & {
99
encoding?: BufferEncoding | undefined

0 commit comments

Comments
 (0)