fix(build): pin tsdown to the native config loader

Root build scripts, the desktop bundle and the dev:web watcher pass the
native loader so tsdown never selects the undeclared unrun fallback. A spec
covers the build.ts rejection path.
This commit is contained in:
Turtle committed 2026-10-02 12:48:01 +08:00
1 parent f3013b2d8d
commit 500614c0d5
8 files changed
+31 -10

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@
"scripts": {
"test:installer": "node scripts/test-windows-installer.mjs",
"build": "tsc -b && pnpm run bundle",
"bundle": "tsdown",
"bundle": "tsdown --config-loader native",
"dev": "tsx scripts/dev.ts",
"start": "tsx scripts/dev.ts --skip-build",
"test:updates:local": "pnpm run build && node scripts/test-local-updater.mjs",
+2 -2
View File
@@ -9,8 +9,8 @@
en: 5207d17725c07a27
zh: 258884c4300ac63a
/development-guide/setup-tutorial/prerequisites:
en: 6fab214526f49fb8
zh: 26a469d8d75a35ad
en: a8543c278338a02d
zh: b5790c5fea7c0bc6
/development-guide/setup-tutorial/windows-and-wsl-2:
en: e86be579be6f1813
zh: 14f6a220337d0861
+2 -1
View File
@@ -8,7 +8,8 @@ The setup tutorial takes a new contributor from prerequisites to a checked check
### Prerequisites
- Node.js supports 22.19+ and 24+. CI covers 22.19, 24, and 26; see the [Node engine floor Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.md). The build loads `tsdown.config.ts` through Node type stripping, so `pnpm run build` rejects a Node.js process where `process.features.typescript` is false, such as one with `--no-experimental-strip-types` in `NODE_OPTIONS`.
- Node.js supports 22.19+ and 24+. CI covers 22.19, 24, and 26; see the [Node engine floor Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.md).
- Node.js TypeScript type stripping enabled. The repository build scripts load `tsdown.config.ts` with tsdown's native config loader, so they fail when `--no-experimental-strip-types` is in `NODE_OPTIONS` or the Node.js build lacks TypeScript support; `pnpm run build` checks this first and names the cause.
- Corepack-enabled pnpm. The repo pins `[email protected]` in `package.json`; run `corepack enable` if `pnpm --version` does not resolve through Corepack.
- Git 2.26 or newer; hook setup enables Git's worktree-specific configuration extension.
- Optional: a DeepSeek API key for the Web, headless, and ACP automation demos and real-API e2e tests.
+2 -1
View File
@@ -10,7 +10,8 @@
### 前置条件
- Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26;见 [Node 引擎下限 Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.zh.md)。构建通过 Node 类型剥离加载 `tsdown.config.ts`,因此 `pnpm run build` 会拒绝 `process.features.typescript` 为 false 的 Node.js 进程,例如 `NODE_OPTIONS` 含 `--no-experimental-strip-types` 的进程。
- Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26;见 [Node 引擎下限 Agent Note](../.agents/notes/implemented/process/2026-07-06-node-engine-floor.zh.md)。
- 启用 Node.js TypeScript 类型剥离。仓库构建脚本用 tsdown 的 native 配置加载器加载 `tsdown.config.ts`,因此当 `NODE_OPTIONS` 含 `--no-experimental-strip-types` 或 Node.js 构建缺少 TypeScript 支持时会失败;`pnpm run build` 会先检查这一条件并指出原因。
- 启用了 Corepack 的 pnpm。仓库在 `package.json` 中固定使用 `[email protected]`;如果 `pnpm --version` 无法通过 Corepack 解析,请先运行 `corepack enable`。
- Git 2.26 或更高版本;钩子设置会启用 Git 的 worktree 专属配置扩展。
- 可选:一个 DeepSeek API key,用于 Web、headless 和 ACP(Agent Client Protocol)自动化 agent(智能体)演示以及真实 API 的 e2e 测试。
+3 -3
View File
@@ -19,11 +19,11 @@
"scripts": {
"prepare:primary-runtime": "tsx scripts/primary-runtime/prepare.ts",
"build": "tsx scripts/build.ts",
"build:bench": "npm run build:native-system && npm run build:lib && tsdown --config benchmarks/tsdown.config.ts",
"build:bench": "npm run build:native-system && npm run build:lib && tsdown --config-loader native --config benchmarks/tsdown.config.ts",
"build:official": "tsx scripts/build.ts --profile official",
"build:lib": "pnpm run build:lib:host && pnpm run build:lib:client",
"build:lib:host": "node --max-old-space-size=4096 ./node_modules/typescript/bin/tsc -b tsconfig.host.json && tsdown --env.DSH_BUILD_FACE host && pnpm --filter @deepseek-ai/dsh-desktop run bundle",
"build:lib:client": "tsc -b tsconfig.client.json && tsdown --env.DSH_BUILD_FACE client",
"build:lib:host": "node --max-old-space-size=4096 ./node_modules/typescript/bin/tsc -b tsconfig.host.json && tsdown --config-loader native --env.DSH_BUILD_FACE host && pnpm --filter @deepseek-ai/dsh-desktop run bundle",
"build:lib:client": "tsc -b tsconfig.client.json && tsdown --config-loader native --env.DSH_BUILD_FACE client",
"build:web": "pnpm --filter @deepseek-ai/dsh-web-frontend run build",
"build:desktop": "pnpm --filter @deepseek-ai/dsh-desktop run build",
"dev:desktop": "pnpm --filter @deepseek-ai/dsh-desktop run dev",
+18
View File
@@ -0,0 +1,18 @@
import { spawnSync } from 'node:child_process'
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
const root = resolve(import.meta.dirname, '..')
describe('repository build CLI', () => {
// The sentinel makes parseArgs fail fast if the check ever stops running first.
it('rejects a Node process without TypeScript type stripping before any build step', () => {
const result = spawnSync(
process.execPath,
['--no-experimental-strip-types', '--import', 'tsx/esm', resolve(root, 'scripts/build.ts'), '--spec-sentinel'],
{ cwd: root, encoding: 'utf8' },
)
expect(result.status).not.toBe(0)
expect(result.stderr).toContain('build: Node.js TypeScript type stripping is unavailable')
})
})
+2 -2
View File
@@ -30,9 +30,9 @@ function runScript(script: string, environment: NodeJS.ProcessEnv): void {
/** Run the full build selected by `--profile` or `DSH_BUILD_CLIENT_PROFILE`. */
function main(): void {
// tsdown loads tsdown.config.ts natively only when Node strips types; its unrun fallback is undeclared and mislocates import.meta.url.
// tsdown.config.ts loads only through Node type stripping (`--config-loader native`); this names the cause before tsdown fails.
if (!process.features.typescript) {
throw new Error('build: Node.js TypeScript type stripping is unavailable (process.features.typescript is false); remove --no-experimental-strip-types from NODE_OPTIONS or use a Node.js build with TypeScript support')
throw new Error('build: Node.js TypeScript type stripping is unavailable in this Node.js process; remove --no-experimental-strip-types from NODE_OPTIONS or use a Node.js build with TypeScript support')
}
const { values } = parseArgs({
options: { profile: { type: 'string' } },
+1
View File
@@ -187,6 +187,7 @@ export async function watchClientPlugins(
const bundles = await build({
cwd: root,
workspace: [...pluginDirs],
configLoader: 'native',
watch: true,
// Workspace hooks override inline hooks; onSuccess runs after each package's build:done work.
onSuccess: (options) => {