Skip to content

Commit dd8572f

Browse files
committed
centralize native deps; ts builder config
1 parent e75e117 commit dd8572f

7 files changed

Lines changed: 118 additions & 76 deletions

File tree

.github/workflows/code-release.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ jobs:
150150
run: |
151151
pnpm exec electron-vite build
152152
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
153-
pnpm exec electron-builder build --mac --arm64 --publish never --config electron-builder.config.cjs
153+
pnpm exec electron-builder build --mac --arm64 --publish never --config electron-builder.ts
154154
else
155-
pnpm exec electron-builder build --mac --x64 --publish never --config electron-builder.config.cjs
155+
pnpm exec electron-builder build --mac --x64 --publish never --config electron-builder.ts
156156
fi
157157
158158
- name: Verify package
@@ -303,7 +303,7 @@ jobs:
303303
working-directory: apps/code
304304
run: |
305305
pnpm exec electron-vite build
306-
pnpm exec electron-builder build --win --x64 --publish never --config electron-builder.config.cjs
306+
pnpm exec electron-builder build --win --x64 --publish never --config electron-builder.ts
307307
308308
- name: Upload release artifacts
309309
shell: pwsh
@@ -420,9 +420,9 @@ jobs:
420420
run: |
421421
pnpm exec electron-vite build
422422
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
423-
pnpm exec electron-builder build --linux --arm64 --publish never --config electron-builder.config.cjs
423+
pnpm exec electron-builder build --linux --arm64 --publish never --config electron-builder.ts
424424
else
425-
pnpm exec electron-builder build --linux --x64 --publish never --config electron-builder.config.cjs
425+
pnpm exec electron-builder build --linux --x64 --publish never --config electron-builder.ts
426426
fi
427427
428428
- name: Upload release artifacts
Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
"use strict";
1+
import { createRequire } from "node:module";
2+
import type { Configuration } from "electron-builder";
3+
import { asarUnpackGlobs, packagedFileGlobs } from "./runtime-dependencies";
4+
import beforePack from "./scripts/before-pack";
5+
6+
const require = createRequire(import.meta.url);
27

38
const skipNotarize =
49
process.env.SKIP_NOTARIZE === "1" || !process.env.APPLE_TEAM_ID;
510

6-
/** @type {import('electron-builder').Configuration} */
7-
module.exports = {
11+
const config: Configuration = {
812
appId: "com.posthog.array",
913
productName: "PostHog Code",
1014
executableName: "PostHog Code",
@@ -19,31 +23,14 @@ module.exports = {
1923
nodeGypRebuild: false,
2024
generateUpdatesFilesForAllChannels: true,
2125

22-
beforePack: "./scripts/before-pack.cjs",
26+
beforePack,
2327

2428
files: [
2529
".vite/build/**/*",
2630
".vite/renderer/**/*",
2731
"package.json",
2832
"!node_modules/**/*",
29-
"node_modules/node-pty/**/*",
30-
"node_modules/node-addon-api/**/*",
31-
"node_modules/@parcel/**/*",
32-
"node_modules/better-sqlite3/**/*",
33-
"node_modules/bindings/**/*",
34-
"node_modules/file-uri-to-path/**/*",
35-
"node_modules/file-icon/**/*",
36-
"node_modules/p-map/**/*",
37-
"node_modules/prebuild-install/**/*",
38-
"node_modules/micromatch/**/*",
39-
"node_modules/is-glob/**/*",
40-
"node_modules/detect-libc/**/*",
41-
"node_modules/braces/**/*",
42-
"node_modules/picomatch/**/*",
43-
"node_modules/is-extglob/**/*",
44-
"node_modules/fill-range/**/*",
45-
"node_modules/to-regex-range/**/*",
46-
"node_modules/is-number/**/*",
33+
...packagedFileGlobs,
4734
],
4835

4936
asarUnpack: [
@@ -53,12 +40,7 @@ module.exports = {
5340
".vite/build/plugins/posthog/**",
5441
".vite/build/codex-acp/**",
5542
".vite/build/grammars/**",
56-
"node_modules/node-pty/**",
57-
"node_modules/@parcel/**",
58-
"node_modules/file-icon/**",
59-
"node_modules/better-sqlite3/**",
60-
"node_modules/bindings/**",
61-
"node_modules/file-uri-to-path/**",
43+
...asarUnpackGlobs,
6244
],
6345

6446
extraResources: [
@@ -142,3 +124,5 @@ module.exports = {
142124
releaseType: "draft",
143125
},
144126
};
127+
128+
export default config;

apps/code/electron.vite.config.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import react from "@vitejs/plugin-react";
99
import { defineConfig } from "electron-vite";
1010
import { loadEnv } from "vite";
1111
import tsconfigPaths from "vite-tsconfig-paths";
12+
import { buildExternals } from "./runtime-dependencies";
1213
import {
1314
createForceDevModeDefine,
1415
createPosthogPlugin,
@@ -41,13 +42,8 @@ const nodeExternals = [
4142
];
4243

4344
// Native .node modules can't be bundled — they stay external and resolve from
44-
// the staged node_modules at runtime (see scripts/before-pack.cjs).
45-
const nativeModules = [
46-
"node-pty",
47-
"@parcel/watcher",
48-
"file-icon",
49-
"better-sqlite3",
50-
];
45+
// the staged node_modules at runtime (see scripts/before-pack.ts).
46+
const nativeModules = buildExternals;
5147

5248
export default defineConfig(({ mode }) => {
5349
const env = loadEnv(mode, path.resolve(__dirname, "../.."), "");

apps/code/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
"start": "electron-vite dev --watch",
1515
"start:debug": "electron-vite dev --watch --inspect=5858",
1616
"compile": "electron-vite build",
17-
"package": "electron-vite build && electron-builder build --dir --config electron-builder.config.cjs",
18-
"package:dev": "FORCE_DEV_MODE=1 SKIP_NOTARIZE=1 electron-vite build && electron-builder build --dir --config electron-builder.config.cjs",
19-
"make": "electron-vite build && electron-builder build --config electron-builder.config.cjs",
17+
"package": "electron-vite build && electron-builder build --dir --config electron-builder.ts",
18+
"package:dev": "FORCE_DEV_MODE=1 SKIP_NOTARIZE=1 electron-vite build && electron-builder build --dir --config electron-builder.ts",
19+
"make": "electron-vite build && electron-builder build --config electron-builder.ts",
2020
"make:linux": "bash scripts/build-linux-docker.sh",
21-
"publish": "electron-vite build && electron-builder build --publish always --config electron-builder.config.cjs",
21+
"publish": "electron-vite build && electron-builder build --publish always --config electron-builder.ts",
2222
"build": "pnpm package",
2323
"build-icons": "bash scripts/generate-icns.sh",
2424
"typecheck": "tsc -p tsconfig.node.json --noEmit && tsc -p tsconfig.web.json --noEmit",

apps/code/runtime-dependencies.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Single source of truth for native modules (and their runtime-required
2+
// transitive deps). pnpm hoists these to the root node_modules; the packaged
3+
// app needs real copies next to the bundle.
4+
//
5+
// - scripts/before-pack.ts stages them from the hoisted root into the app's
6+
// local node_modules before electron-builder collects files.
7+
// - electron-builder.ts re-includes them (`files`) and unpacks the
8+
// binary-bearing ones from the asar (`asarUnpack`).
9+
// - electron.vite.config.ts marks the native ones external so Vite leaves
10+
// them to be resolved from node_modules at runtime.
11+
12+
// Staged + packaged on every platform.
13+
export const runtimeNativeModules = [
14+
"node-pty",
15+
"node-addon-api",
16+
"@parcel/watcher",
17+
"better-sqlite3",
18+
"bindings",
19+
"file-uri-to-path",
20+
"prebuild-install",
21+
"micromatch",
22+
"is-glob",
23+
"detect-libc",
24+
"braces",
25+
"picomatch",
26+
"is-extglob",
27+
"fill-range",
28+
"to-regex-range",
29+
"is-number",
30+
];
31+
32+
// file-icon (and its p-map dependency) is only used on macOS.
33+
export const macOnlyNativeModules = ["file-icon", "p-map"];
34+
35+
// The subset that ships compiled .node binaries and must be unpacked from asar.
36+
const asarUnpackModules = [
37+
"node-pty",
38+
"@parcel/watcher",
39+
"file-icon",
40+
"better-sqlite3",
41+
"bindings",
42+
"file-uri-to-path",
43+
];
44+
45+
// Modules Vite must not bundle (resolved from the staged node_modules at runtime).
46+
export const buildExternals = [
47+
"node-pty",
48+
"@parcel/watcher",
49+
"file-icon",
50+
"better-sqlite3",
51+
];
52+
53+
// electron-builder ships the whole @parcel scope so the platform-specific
54+
// @parcel/watcher-<plat>-<arch> staged by before-pack is covered too.
55+
const scopeOf = (name: string) =>
56+
name.startsWith("@parcel/") ? "@parcel" : name;
57+
58+
export const packagedFileGlobs = [
59+
...runtimeNativeModules,
60+
...macOnlyNativeModules,
61+
].map((name) => `node_modules/${scopeOf(name)}/**/*`);
62+
63+
export const asarUnpackGlobs = asarUnpackModules.map(
64+
(name) => `node_modules/${scopeOf(name)}/**`,
65+
);
Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1-
"use strict";
2-
3-
const { cpSync, existsSync, mkdirSync, rmSync } = require("node:fs");
4-
const path = require("node:path");
1+
import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs";
2+
import path from "node:path";
3+
import {
4+
macOnlyNativeModules,
5+
runtimeNativeModules,
6+
} from "../runtime-dependencies";
57

68
const ARCH_X64 = 1;
79
const ARCH_ARM64 = 3;
810

9-
function copyDep(name, rootNodeModules, localNodeModules) {
11+
type BeforePackContext = {
12+
packager: { platform: { name: string } };
13+
arch: number;
14+
};
15+
16+
function copyDep(
17+
name: string,
18+
rootNodeModules: string,
19+
localNodeModules: string,
20+
): boolean {
1021
const src = path.join(rootNodeModules, name);
1122
if (!existsSync(src)) {
1223
const localSrc = path.join(localNodeModules, name);
@@ -31,15 +42,19 @@ function copyDep(name, rootNodeModules, localNodeModules) {
3142
return true;
3243
}
3344

34-
function copyRequiredDep(name, rootNodeModules, localNodeModules) {
45+
function copyRequiredDep(
46+
name: string,
47+
rootNodeModules: string,
48+
localNodeModules: string,
49+
): void {
3550
if (!copyDep(name, rootNodeModules, localNodeModules)) {
3651
throw new Error(
3752
`[before-pack] required native dependency "${name}" not found in node_modules`,
3853
);
3954
}
4055
}
4156

42-
module.exports = async function beforePack(context) {
57+
export default async function beforePack(context: BeforePackContext) {
4358
const platformName = context.packager.platform.name;
4459
const arch = context.arch;
4560

@@ -50,26 +65,7 @@ module.exports = async function beforePack(context) {
5065
console.log(`[before-pack] root node_modules: ${rootNodeModules}`);
5166
console.log(`[before-pack] local node_modules: ${localNodeModules}`);
5267

53-
const commonDeps = [
54-
"node-pty",
55-
"node-addon-api",
56-
"@parcel/watcher",
57-
"micromatch",
58-
"is-glob",
59-
"detect-libc",
60-
"braces",
61-
"picomatch",
62-
"is-extglob",
63-
"fill-range",
64-
"to-regex-range",
65-
"is-number",
66-
"better-sqlite3",
67-
"bindings",
68-
"file-uri-to-path",
69-
"prebuild-install",
70-
];
71-
72-
for (const dep of commonDeps) {
68+
for (const dep of runtimeNativeModules) {
7369
copyDep(dep, rootNodeModules, localNodeModules);
7470
}
7571

@@ -79,8 +75,9 @@ module.exports = async function beforePack(context) {
7975
? "@parcel/watcher-darwin-x64"
8076
: "@parcel/watcher-darwin-arm64";
8177
copyRequiredDep(watcherPkg, rootNodeModules, localNodeModules);
82-
copyDep("file-icon", rootNodeModules, localNodeModules);
83-
copyDep("p-map", rootNodeModules, localNodeModules);
78+
for (const dep of macOnlyNativeModules) {
79+
copyDep(dep, rootNodeModules, localNodeModules);
80+
}
8481
} else if (platformName === "win") {
8582
const watcherPkg =
8683
arch === ARCH_ARM64
@@ -100,4 +97,4 @@ module.exports = async function beforePack(context) {
10097
rmSync(watcherBuild, { recursive: true, force: true });
10198
console.log("[before-pack] removed @parcel/watcher/build");
10299
}
103-
};
100+
}

apps/code/scripts/build-linux-docker.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ COPYFILE_DISABLE=1 tar -cf - \
9595
cd apps/code
9696
pnpm exec electron-vite build
9797
if [ -n "${MAKE_TARGETS:-}" ]; then
98-
pnpm exec electron-builder build --linux $MAKE_TARGETS --${ARCH} --config electron-builder.config.cjs
98+
pnpm exec electron-builder build --linux $MAKE_TARGETS --${ARCH} --config electron-builder.ts
9999
else
100-
pnpm exec electron-builder build --linux --${ARCH} --config electron-builder.config.cjs
100+
pnpm exec electron-builder build --linux --${ARCH} --config electron-builder.ts
101101
fi
102102
mkdir -p /out
103103
cp -r out/. /out/

0 commit comments

Comments
 (0)