feat: bundle all node_modules to reduce size

This commit is contained in:
Aarnav Tale
2025-10-15 18:11:30 -04:00
parent 4fd8062476
commit 8f260b79f1
7 changed files with 1252 additions and 1389 deletions
-1
View File
@@ -8,5 +8,4 @@ app/hp_ssh.wasm
app/wasm_exec.js
/docs/.vitepress/dist/
/docs/.vitepress/cache/
/.direnv
+1
View File
@@ -35,6 +35,7 @@ COPY --from=go-build /build/app/wasm_exec.js /build/app/wasm_exec.js
ARG IMAGE_TAG
RUN IMAGE_TAG=$IMAGE_TAG pnpm run build
RUN mkdir -p /var/lib/headplane/agent
RUN pnpm prune --prod
FROM gcr.io/distroless/nodejs22-debian12:latest AS final
COPY --from=js-build /build/build/ /app/build/
+42 -40
View File
@@ -11,7 +11,6 @@ import {
useLoaderData,
useSubmit,
} from 'react-router';
import wasm from '~/hp_ssh.wasm?url';
import { LoadContext } from '~/server';
import { EphemeralNodeInsert, ephemeralNodes } from '~/server/db/schema';
import { Machine, PreAuthKey, User } from '~/types';
@@ -215,46 +214,49 @@ export default function Page() {
pause();
const go = new Go(); // Go is defined by wasm_exec.js
WebAssembly.instantiateStreaming(fetch(wasm), go.importObject).then(
(value) => {
go.run(value.instance);
const handle = TsWasmNet(ipnDetails, {
NotifyState: (state) => {
console.log('State changed:', state);
if (state === 'Running') {
setIpn(handle);
}
},
NotifyNetMap: (netmap) => {
// Only set NodeKey if it is not already set and then
// also dispatch that to the backend to track the
// ephemeral node.
//
// We open an SSE connection to the backend
// so that when the connection is closed,
// the backend can delete the ephemeral node.
if (nodeKey === null) {
setNodeKey(netmap.NodeKey);
submit(
{
node_key: netmap.NodeKey,
auth_key: ipnDetails.PreAuthKey,
},
{ method: 'POST' },
);
}
},
NotifyBrowseToURL: (url) => {
console.log('Browse to URL:', url);
},
NotifyPanicRecover: (message) => {
console.error('Panic recover:', message);
},
});
handle.Start();
},
);
import('~/hp_ssh.wasm?url').then(({ default: url }) => {
WebAssembly.instantiateStreaming(fetch(url), go.importObject).then(
(value) => {
go.run(value.instance);
const handle = TsWasmNet(ipnDetails, {
NotifyState: (state) => {
console.log('State changed:', state);
if (state === 'Running') {
setIpn(handle);
}
},
NotifyNetMap: (netmap) => {
// Only set NodeKey if it is not already set and then
// also dispatch that to the backend to track the
// ephemeral node.
//
// We open an SSE connection to the backend
// so that when the connection is closed,
// the backend can delete the ephemeral node.
if (nodeKey === null) {
setNodeKey(netmap.NodeKey);
submit(
{
node_key: netmap.NodeKey,
auth_key: ipnDetails.PreAuthKey,
},
{ method: 'POST' },
);
}
},
NotifyBrowseToURL: (url) => {
console.log('Browse to URL:', url);
},
NotifyPanicRecover: (message) => {
console.error('Panic recover:', message);
},
});
handle.Start();
},
);
});
}, []);
if (!sshDetails.username) {
+9 -9
View File
@@ -1,9 +1,6 @@
import { Icon } from '@iconify/react';
import { ArrowRight } from 'lucide-react';
import { useEffect } from 'react';
import { GrApple } from 'react-icons/gr';
import { ImFinder } from 'react-icons/im';
import { MdAndroid } from 'react-icons/md';
import { PiTerminalFill, PiWindowsLogoFill } from 'react-icons/pi';
import { LoaderFunctionArgs, NavLink, useLoaderData } from 'react-router';
import Button from '~/components/Button';
import Card from '~/components/Card';
@@ -132,7 +129,7 @@ export default function Page() {
key="linux"
title={
<div className="flex items-center gap-1">
<PiTerminalFill className="ml-1 w-4" />
<Icon className="ml-1 w-4" icon="ion:terminal" />
<span>Linux</span>
</div>
}
@@ -163,7 +160,7 @@ export default function Page() {
key="windows"
title={
<div className="flex items-center gap-1">
<PiWindowsLogoFill className="ml-1 w-4" />
<Icon className="ml-1 w-4" icon="mdi:microsoft" />
<span>Windows</span>
</div>
}
@@ -186,7 +183,10 @@ export default function Page() {
key="macos"
title={
<div className="flex items-center gap-1">
<ImFinder className="ml-1 w-4" />
<Icon
className="ml-1 w-4"
icon="streamline-logos:mac-finder-logo-solid"
/>
<span>macOS</span>
</div>
}
@@ -218,7 +218,7 @@ export default function Page() {
key="ios"
title={
<div className="flex items-center gap-1">
<GrApple className="ml-1 w-4" />
<Icon className="ml-1 w-4" icon="grommet-icons:apple" />
<span>iOS</span>
</div>
}
@@ -241,7 +241,7 @@ export default function Page() {
key="android"
title={
<div className="flex items-center gap-1">
<MdAndroid className="ml-1 w-4" />
<Icon className="ml-1 w-4" icon="material-symbols:android" />
<span>Android</span>
</div>
}
+28 -28
View File
@@ -16,20 +16,28 @@
"docs:preview": "vitepress preview docs"
},
"dependencies": {
"@libsql/client": "0.15.12"
},
"devDependencies": {
"@biomejs/biome": "^2.2.0",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@faker-js/faker": "9.9.0",
"@fontsource-variable/inter": "^5.2.6",
"@fontsource-variable/inter": "^5.2.8",
"@iconify/react": "^6.0.2",
"@kubernetes/client-node": "^1.3.0",
"@libsql/client": "0.15.12",
"@react-aria/toast": "3.0.6",
"@react-aria/toast": "3.0.8",
"@react-router/dev": "^7.8.1",
"@react-router/node": "^7.8.1",
"@react-stately/toast": "3.1.2",
"@shopify/lang-jsonc": "^1.0.1",
"@types/react": "^19.1.10",
"@types/react-dom": "^19.1.7",
"@tailwindcss/vite": "^4.1.12",
"@types/node": "^24.3.0",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@typescript/native-preview": "7.0.0-dev.20250821.1",
"@uiw/codemirror-theme-github": "4.25.1",
"@uiw/codemirror-theme-xcode": "4.25.1",
"@uiw/react-codemirror": "4.25.1",
@@ -41,48 +49,40 @@
"arktype": "^2.1.20",
"clsx": "^2.1.1",
"dotenv": "17.2.1",
"drizzle-kit": "^0.31.4",
"drizzle-orm": "0.44.4",
"isbot": "5.1.30",
"jose": "6.1.0",
"js-yaml": "^4.1.0",
"lefthook": "^1.12.3",
"lucide-react": "^0.540.0",
"mime": "^4.0.7",
"openid-client": "6.7.0",
"react": "19.1.1",
"react-aria": "3.42.0",
"postcss": "^8.5.6",
"react": "19.2.0",
"react-aria": "3.44.0",
"react-codemirror-merge": "4.25.1",
"react-dom": "19.1.1",
"react-dom": "19.2.0",
"react-error-boundary": "^6.0.0",
"react-icons": "^5.5.0",
"react-router": "^7.8.1",
"react-router-dom": "^7.8.1",
"react-router-hono-server": "2.21.0",
"react-stately": "3.40.0",
"react-scan": "^0.4.3",
"react-stately": "3.42.0",
"remix-utils": "^8.8.0",
"tailwind-merge": "3.3.1",
"ulidx": "2.4.1",
"undici": "7.14.0",
"usehooks-ts": "^3.1.1",
"yaml": "2.8.1"
},
"devDependencies": {
"@biomejs/biome": "^2.2.0",
"@react-router/dev": "^7.8.1",
"@tailwindcss/vite": "^4.1.12",
"@types/node": "^24.3.0",
"@typescript/native-preview": "7.0.0-dev.20250821.1",
"drizzle-kit": "^0.31.4",
"js-yaml": "^4.1.0",
"lefthook": "^1.12.3",
"postcss": "^8.5.6",
"react-router-dom": "^7.8.1",
"react-scan": "^0.4.3",
"tailwindcss": "^4.1.12",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-react-aria-components": "^2.0.0",
"typescript": "^5.9.2",
"ulidx": "2.4.1",
"undici": "7.14.0",
"usehooks-ts": "^3.1.1",
"vite": "npm:rolldown-vite@7.1.4",
"vite-tsconfig-paths": "^5.1.4",
"vitepress": "next",
"vitest": "^3.1.3"
"vitest": "^3.1.3",
"yaml": "2.8.1"
},
"packageManager": "pnpm@10.4.0",
"engines": {
+1158 -1310
View File
File diff suppressed because it is too large Load Diff
+14 -1
View File
@@ -37,10 +37,23 @@ export default defineConfig(({ command, isSsrBuild }) => ({
},
build: {
target: 'esnext',
sourcemap: true,
rolldownOptions:
command === 'build'
? {
// Exclude libsql from the server side since it's a native module
// Exclude WASM from the client since it fetches from the server
external: isSsrBuild ? [/^@libsql\//] : [/\.wasm(\?url)?$/],
output: {
manualChunks: undefined,
inlineDynamicImports: isSsrBuild,
},
}
: undefined,
},
ssr: {
target: 'node',
noExternal: isSsrBuild ? ['@libsql/client'] : undefined,
noExternal: command === 'build' ? true : undefined,
},
optimizeDeps: {
include: ['@libsql/client'],