From 0293ebe3ebf2969ceca60775c00787e06684791b Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Mon, 31 Aug 2026 00:19:09 -0700 Subject: [PATCH] perf(packaging): prune JS source maps from all packaged node_modules (#17638) Generalizes the @linear/sdk-scoped prune to every packaged dependency, matching the existing type-declaration prune's single-predicate walk over Resources/node_modules. Recovers ~1.01 MB beyond the SDK. Nothing in the packaged app enables Node source-map support (no --enable-source-maps, no setSourceMapsEnabled, no source-map-support require), and the CLI launchers strip NODE_OPTIONS, so these maps were never read. Orca's own main-process maps live outside node_modules and already ship as a separate release artifact. --- config/packaged-runtime-node-modules.cjs | 20 +-- .../packaged-linear-sdk-prune.test.mjs | 94 ------------ .../packaged-source-map-prune.test.mjs | 142 ++++++++++++++++++ 3 files changed, 153 insertions(+), 103 deletions(-) delete mode 100644 config/scripts/packaged-linear-sdk-prune.test.mjs create mode 100644 config/scripts/packaged-source-map-prune.test.mjs diff --git a/config/packaged-runtime-node-modules.cjs b/config/packaged-runtime-node-modules.cjs index 8ba063c02b6..30f0e999c3f 100644 --- a/config/packaged-runtime-node-modules.cjs +++ b/config/packaged-runtime-node-modules.cjs @@ -57,7 +57,7 @@ const ELECTRON_ARCHITECTURE_BY_ENUM = { } const PACKAGED_NATIVE_ARCHITECTURES = new Set(['ia32', 'x64', 'arm', 'arm64']) const TYPE_DECLARATION_ARTIFACT_RE = /\.d\.(?:c|m)?ts(?:\.map)?$/ -const LINEAR_SDK_SOURCE_MAP_RE = /\.(?:c|m)?js\.map$/ +const JS_SOURCE_MAP_ARTIFACT_RE = /\.(?:c|m)?js\.map$/ const VERSIONED_ONNXRUNTIME_DYLIB_RE = /^libonnxruntime\.\d[\d.]*\.dylib$/ const NODE_BUILTINS = new Set([ @@ -447,14 +447,16 @@ function prunePackagedRuntimeTypeDeclarations(resourcesDir) { pruneMatchingFiles(nodeModulesDir, (filename) => TYPE_DECLARATION_ARTIFACT_RE.test(filename)) } -function prunePackagedLinearSdkSourceMaps(resourcesDir) { - // Why: @linear/sdk's source maps embed several megabytes of generated source, - // but Node never loads them to execute the CJS runtime entry. - const packageDir = join(resourcesDir, 'node_modules', '@linear', 'sdk') - if (!existsSync(packageDir)) { +function prunePackagedRuntimeSourceMaps(resourcesDir) { + // Why: dependency source maps embed the original sources (megabytes for + // @linear/sdk alone), and nothing in the packaged app turns on Node's + // source-map support, so they are never read. Orca's own main-process maps + // live outside node_modules and ship as a separate release artifact. + const nodeModulesDir = join(resourcesDir, 'node_modules') + if (!existsSync(nodeModulesDir)) { return } - pruneMatchingFiles(packageDir, (filename) => LINEAR_SDK_SOURCE_MAP_RE.test(filename)) + pruneMatchingFiles(nodeModulesDir, (filename) => JS_SOURCE_MAP_ARTIFACT_RE.test(filename)) } function prunePackagedSherpaOnnx(resourcesDir, electronPlatformName) { @@ -493,7 +495,7 @@ function prunePackagedRuntimeNodeModules(resourcesDir, electronPlatformName, ele prunePackagedNodePty(resourcesDir, electronPlatformName, architecture) prunePackagedParcelWatcher(resourcesDir, electronPlatformName, architecture) prunePackagedRuntimeTypeDeclarations(resourcesDir) - prunePackagedLinearSdkSourceMaps(resourcesDir) + prunePackagedRuntimeSourceMaps(resourcesDir) prunePackagedSherpaOnnx(resourcesDir, electronPlatformName) prunePackagedZodSources(resourcesDir) } @@ -518,7 +520,7 @@ module.exports = { prunePackagedNodePty, prunePackagedParcelWatcher, prunePackagedRuntimeNodeModules, - prunePackagedLinearSdkSourceMaps, + prunePackagedRuntimeSourceMaps, prunePackagedSherpaOnnx, prunePackagedRuntimeTypeDeclarations, prunePackagedZodSources, diff --git a/config/scripts/packaged-linear-sdk-prune.test.mjs b/config/scripts/packaged-linear-sdk-prune.test.mjs deleted file mode 100644 index ed328e2d63c..00000000000 --- a/config/scripts/packaged-linear-sdk-prune.test.mjs +++ /dev/null @@ -1,94 +0,0 @@ -import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' -import { createRequire } from 'node:module' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { describe, expect, it } from 'vitest' - -const require = createRequire(import.meta.url) -const { - prunePackagedLinearSdkSourceMaps, - prunePackagedRuntimeNodeModules -} = require('../packaged-runtime-node-modules.cjs') - -async function createLinearSdkFixture(resourcesDir) { - const packageDir = join(resourcesDir, 'node_modules', '@linear', 'sdk') - const distDir = join(packageDir, 'dist') - const webhooksDir = join(packageDir, 'webhooks') - const unrelatedPackageDir = join(resourcesDir, 'node_modules', 'unrelated-package') - await mkdir(distDir, { recursive: true }) - await mkdir(webhooksDir, { recursive: true }) - await mkdir(unrelatedPackageDir, { recursive: true }) - await writeFile( - join(packageDir, 'package.json'), - '{"name":"@linear/sdk","type":"module","main":"./dist/index.cjs","exports":{".":{"require":"./dist/index.cjs","import":"./dist/index.mjs"}}}', - 'utf8' - ) - await writeFile(join(packageDir, 'README.md'), 'SDK documentation', 'utf8') - await writeFile(join(packageDir, 'metadata.json.map'), '{"keep":true}', 'utf8') - await writeFile( - join(distDir, 'index.cjs'), - "module.exports = require('./runtime-helper.cjs')", - 'utf8' - ) - await writeFile( - join(distDir, 'runtime-helper.cjs'), - 'exports.LinearClient = class LinearClient {}', - 'utf8' - ) - await writeFile(join(distDir, 'index.mjs'), 'export {}', 'utf8') - await writeFile(join(distDir, 'index.cjs.map'), '{}', 'utf8') - await writeFile(join(distDir, 'index.mjs.map'), '{}', 'utf8') - await writeFile(join(webhooksDir, 'index.cjs'), 'module.exports = {}', 'utf8') - await writeFile(join(webhooksDir, 'index.cjs.map'), '{}', 'utf8') - await writeFile(join(unrelatedPackageDir, 'index.js.map'), '{}', 'utf8') - return { packageDir, distDir, webhooksDir, unrelatedPackageDir } -} - -describe('packaged @linear/sdk pruning', () => { - it('removes source maps while preserving SDK runtime files, metadata, and unrelated maps', async () => { - const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-linear-sdk-prune-')) - try { - const { packageDir, distDir, webhooksDir, unrelatedPackageDir } = - await createLinearSdkFixture(resourcesDir) - - prunePackagedLinearSdkSourceMaps(resourcesDir) - - await expect(readdir(distDir).then((entries) => entries.sort())).resolves.toEqual([ - 'index.cjs', - 'index.mjs', - 'runtime-helper.cjs' - ]) - await expect(readdir(webhooksDir)).resolves.toEqual(['index.cjs']) - await expect(readFile(join(packageDir, 'package.json'), 'utf8')).resolves.toBe( - '{"name":"@linear/sdk","type":"module","main":"./dist/index.cjs","exports":{".":{"require":"./dist/index.cjs","import":"./dist/index.mjs"}}}' - ) - await expect(readFile(join(packageDir, 'README.md'), 'utf8')).resolves.toBe( - 'SDK documentation' - ) - await expect(readFile(join(packageDir, 'metadata.json.map'), 'utf8')).resolves.toBe( - '{"keep":true}' - ) - await expect(readFile(join(unrelatedPackageDir, 'index.js.map'), 'utf8')).resolves.toBe('{}') - const sdk = createRequire(join(resourcesDir, 'consumer.cjs'))('@linear/sdk') - expect(typeof sdk.LinearClient).toBe('function') - } finally { - await rm(resourcesDir, { recursive: true, force: true }) - } - }) - - it('runs the SDK source-map prune through aggregate runtime cleanup', async () => { - const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-linear-sdk-aggregate-prune-')) - try { - const { distDir } = await createLinearSdkFixture(resourcesDir) - prunePackagedRuntimeNodeModules(resourcesDir, 'darwin', 'arm64') - - await expect(readdir(distDir).then((entries) => entries.sort())).resolves.toEqual([ - 'index.cjs', - 'index.mjs', - 'runtime-helper.cjs' - ]) - } finally { - await rm(resourcesDir, { recursive: true, force: true }) - } - }) -}) diff --git a/config/scripts/packaged-source-map-prune.test.mjs b/config/scripts/packaged-source-map-prune.test.mjs new file mode 100644 index 00000000000..0650e03ca56 --- /dev/null +++ b/config/scripts/packaged-source-map-prune.test.mjs @@ -0,0 +1,142 @@ +import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' +import { createRequire } from 'node:module' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { describe, expect, it } from 'vitest' + +const require = createRequire(import.meta.url) +const { + prunePackagedRuntimeSourceMaps, + prunePackagedRuntimeNodeModules +} = require('../packaged-runtime-node-modules.cjs') + +const LINEAR_SDK_PACKAGE_JSON = + '{"name":"@linear/sdk","type":"module","main":"./dist/index.cjs","exports":{".":{"require":"./dist/index.cjs","import":"./dist/index.mjs"}}}' + +async function createPackagedNodeModulesFixture(resourcesDir) { + const packageDir = join(resourcesDir, 'node_modules', '@linear', 'sdk') + const distDir = join(packageDir, 'dist') + const webhooksDir = join(packageDir, 'webhooks') + const updaterDir = join(resourcesDir, 'node_modules', 'electron-updater', 'out') + const jsYamlDir = join(resourcesDir, 'node_modules', 'js-yaml', 'dist') + const nodePtyDir = join(resourcesDir, 'node_modules', 'node-pty', 'lib') + await mkdir(distDir, { recursive: true }) + await mkdir(webhooksDir, { recursive: true }) + await mkdir(updaterDir, { recursive: true }) + await mkdir(jsYamlDir, { recursive: true }) + await mkdir(nodePtyDir, { recursive: true }) + await writeFile(join(packageDir, 'package.json'), LINEAR_SDK_PACKAGE_JSON, 'utf8') + await writeFile(join(packageDir, 'README.md'), 'SDK documentation', 'utf8') + await writeFile(join(packageDir, 'metadata.json.map'), '{"keep":true}', 'utf8') + await writeFile( + join(distDir, 'index.cjs'), + "module.exports = require('./runtime-helper.cjs')", + 'utf8' + ) + await writeFile( + join(distDir, 'runtime-helper.cjs'), + 'exports.LinearClient = class LinearClient {}', + 'utf8' + ) + await writeFile(join(distDir, 'index.mjs'), 'export {}', 'utf8') + await writeFile(join(distDir, 'index.cjs.map'), '{}', 'utf8') + await writeFile(join(distDir, 'index.mjs.map'), '{}', 'utf8') + await writeFile(join(webhooksDir, 'index.cjs'), 'module.exports = {}', 'utf8') + await writeFile(join(webhooksDir, 'index.cjs.map'), '{}', 'utf8') + await writeFile(join(updaterDir, 'main.js'), 'module.exports = {}', 'utf8') + await writeFile(join(updaterDir, 'main.js.map'), '{}', 'utf8') + await writeFile(join(updaterDir, 'main.d.ts'), 'export {}', 'utf8') + await writeFile(join(updaterDir, 'main.d.ts.map'), '{}', 'utf8') + await writeFile(join(jsYamlDir, 'js-yaml.min.js'), 'globalThis.jsyaml = {}', 'utf8') + await writeFile(join(jsYamlDir, 'js-yaml.min.js.map'), '{}', 'utf8') + await writeFile(join(nodePtyDir, 'index.js'), 'module.exports = {}', 'utf8') + await writeFile(join(nodePtyDir, 'index.js.map'), '{}', 'utf8') + return { packageDir, distDir, webhooksDir, updaterDir, jsYamlDir, nodePtyDir } +} + +describe('packaged runtime source-map pruning', () => { + it('removes @linear/sdk source maps while preserving runtime files and non-JS maps', async () => { + const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-prune-')) + try { + const { packageDir, distDir, webhooksDir } = + await createPackagedNodeModulesFixture(resourcesDir) + + prunePackagedRuntimeSourceMaps(resourcesDir) + + await expect(readdir(distDir).then((entries) => entries.sort())).resolves.toEqual([ + 'index.cjs', + 'index.mjs', + 'runtime-helper.cjs' + ]) + await expect(readdir(webhooksDir)).resolves.toEqual(['index.cjs']) + await expect(readFile(join(packageDir, 'package.json'), 'utf8')).resolves.toBe( + LINEAR_SDK_PACKAGE_JSON + ) + await expect(readFile(join(packageDir, 'README.md'), 'utf8')).resolves.toBe( + 'SDK documentation' + ) + // Why: the predicate is filename-based, so a non-JS `.map` payload must survive. + await expect(readFile(join(packageDir, 'metadata.json.map'), 'utf8')).resolves.toBe( + '{"keep":true}' + ) + const sdk = createRequire(join(resourcesDir, 'consumer.cjs'))('@linear/sdk') + expect(typeof sdk.LinearClient).toBe('function') + } finally { + await rm(resourcesDir, { recursive: true, force: true }) + } + }) + + it('removes source maps from every packaged dependency, not just @linear/sdk', async () => { + const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-prune-all-')) + try { + const { jsYamlDir, nodePtyDir } = await createPackagedNodeModulesFixture(resourcesDir) + + prunePackagedRuntimeSourceMaps(resourcesDir) + + await expect(readdir(jsYamlDir)).resolves.toEqual(['js-yaml.min.js']) + await expect(readdir(nodePtyDir)).resolves.toEqual(['index.js']) + } finally { + await rm(resourcesDir, { recursive: true, force: true }) + } + }) + + it('leaves declaration-map cleanup to the type-declaration prune', async () => { + const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-prune-dts-')) + try { + const { updaterDir } = await createPackagedNodeModulesFixture(resourcesDir) + + prunePackagedRuntimeSourceMaps(resourcesDir) + + // Why: the two predicates are disjoint -- `.d.ts.map` never ends in `.js.map`. + await expect(readdir(updaterDir).then((entries) => entries.sort())).resolves.toEqual([ + 'main.d.ts', + 'main.d.ts.map', + 'main.js' + ]) + } finally { + await rm(resourcesDir, { recursive: true, force: true }) + } + }) + + it('runs the source-map prune through aggregate runtime cleanup', async () => { + const resourcesDir = await mkdtemp(join(tmpdir(), 'orca-source-map-aggregate-prune-')) + try { + const { distDir, updaterDir, packageDir } = + await createPackagedNodeModulesFixture(resourcesDir) + + prunePackagedRuntimeNodeModules(resourcesDir, 'darwin', 'arm64') + + await expect(readdir(distDir).then((entries) => entries.sort())).resolves.toEqual([ + 'index.cjs', + 'index.mjs', + 'runtime-helper.cjs' + ]) + await expect(readdir(updaterDir)).resolves.toEqual(['main.js']) + await expect(readFile(join(packageDir, 'metadata.json.map'), 'utf8')).resolves.toBe( + '{"keep":true}' + ) + } finally { + await rm(resourcesDir, { recursive: true, force: true }) + } + }) +})