diff --git a/packages/vinext/package.json b/packages/vinext/package.json index 6bb4d6255..3e1224dcf 100644 --- a/packages/vinext/package.json +++ b/packages/vinext/package.json @@ -74,12 +74,9 @@ "dependencies": { "@unpic/react": "catalog:", "@vercel/og": "catalog:", - "image-size": "catalog:", - "ipaddr.js": "catalog:", "magic-string": "catalog:", "vite-plugin-commonjs": "catalog:", - "vite-tsconfig-paths": "catalog:", - "web-vitals": "catalog:" + "vite-tsconfig-paths": "catalog:" }, "devDependencies": { "@types/node": "catalog:", @@ -87,9 +84,12 @@ "@types/react-dom": "catalog:", "@vitejs/plugin-react": "catalog:", "@vitejs/plugin-rsc": "catalog:", + "image-size": "catalog:", + "ipaddr.js": "catalog:", "react-server-dom-webpack": "catalog:", "vite": "catalog:", - "vite-plus": "catalog:" + "vite-plus": "catalog:", + "web-vitals": "catalog:" }, "peerDependencies": { "@mdx-js/rollup": "^3.0.0", diff --git a/packages/vinext/vite.config.ts b/packages/vinext/vite.config.ts index c3069668b..8733b7622 100644 --- a/packages/vinext/vite.config.ts +++ b/packages/vinext/vite.config.ts @@ -5,7 +5,23 @@ export default defineConfig({ entry: ["src/**/*.ts", "src/**/*.tsx", "!src/**/*.d.ts"], clean: true, deps: { - skipNodeModulesBundle: true, + // vinext requires *all* node_modules imports to stay external by default: + // many `next/*` and other bare imports are re-resolved/aliased inside the + // user's build, so bundling the real packages here would break that. + // `skipNodeModulesBundle` would do that, but it is mutually exclusive with + // `alwaysBundle`. So we replicate it with `neverBundle` (externalize every + // bare specifier) and carve out the leaves we want to inline. + // + // We inline only zero-dependency leaf utilities that vinext uses + // internally: they have no transitive deps and are never imported directly + // by user code, so there is no benefit to resolving them separately. + // Bundling shrinks the install footprint and supply-chain surface. + alwaysBundle: ["ipaddr.js", "web-vitals", "image-size"], + neverBundle: (id: string) => + /^[^./]/.test(id) && !["ipaddr.js", "web-vitals", "image-size"].includes(id), + // Guard: fail the build if anything other than these three ever gets + // inlined, so a future stray import can't silently bundle a large package. + onlyBundle: ["ipaddr.js", "web-vitals", "image-size"], }, dts: true, fixedExtension: false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed29918ad..69d89fbe4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -905,12 +905,6 @@ importers: '@vercel/og': specifier: 'catalog:' version: 0.8.6 - image-size: - specifier: 'catalog:' - version: 2.0.2 - ipaddr.js: - specifier: 'catalog:' - version: 2.4.0 magic-string: specifier: 'catalog:' version: 0.30.21 @@ -923,9 +917,6 @@ importers: vite-tsconfig-paths: specifier: 'catalog:' version: 6.1.1(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.2.3)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.1)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) - web-vitals: - specifier: 'catalog:' - version: 4.2.4 devDependencies: '@types/node': specifier: 'catalog:' @@ -942,12 +933,21 @@ importers: '@vitejs/plugin-rsc': specifier: 'catalog:' version: 0.5.27(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.2.3)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.1)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.7(react@19.2.7))(react-server-dom-webpack@19.2.7(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) + image-size: + specifier: 'catalog:' + version: 2.0.2 + ipaddr.js: + specifier: 'catalog:' + version: 2.4.0 react-server-dom-webpack: specifier: 'catalog:' version: 19.2.7(react-dom@19.2.7(react@19.2.7))(react@19.2.7) vite-plus: specifier: 'catalog:' version: 0.1.22(@opentelemetry/api@1.9.1)(@types/node@25.2.3)(@vitest/coverage-istanbul@4.1.6)(@voidzero-dev/vite-plus-core@0.1.22(@types/node@25.2.3)(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.1)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.3)(jiti@2.6.1)(tsx@4.21.1)(typescript@5.9.3)(yaml@2.8.3) + web-vitals: + specifier: 'catalog:' + version: 4.2.4 tests/fixtures/app-basic: dependencies: