用scriptc编译monorepo:多包工作空间输出原生二进制的实战指南 用scriptc编译monorepo多包工作空间输出原生二进制的实战指南【免费下载链接】scriptcTypeScript-to-Native Compiler项目地址: https://gitcode.com/GitHub_Trending/sc/scriptcscriptc 是一款把 TypeScript / JavaScript 直接编译成原生二进制的编译器——产物里没有 Node、没有 V8、没有任何 JavaScript 引擎。本文以 scriptc 项目自身的 monorepo 为蓝本手把手带你在多包工作空间pnpm workspace中逐包编译并用一条命令交叉输出 Linux / Windows / WebAssembly 等多平台原生二进制。一、为什么是 scriptc静态优先动态兜底与传统打包 捆绑 Node的方案不同scriptc 对每个语法结构做三层判定并如实告诉你层级含义说明静态编译编译为原生代码默认模式产物与 Node 运行结果逐字节一致动态运行内嵌 quickjs-ng 引擎加--dynamic后npm 依赖与any类型代码在嵌入式引擎中执行明确拒绝编译期报错带SC错误码与修复提示绝不静默误编译这一可看见的静态性正是它在 monorepo 场景下的价值每个包都能单独回答我的代码能编译成原生二进制吗二、一键安装30 秒准备好编译环境编译器需要 Node.js ≥ 24而它产出的二进制完全不需要 Node$ npm install -g scriptc验证安装并编译第一个二进制$ scriptc run hello.ts # 编译并运行 $ scriptc build hello.ts -o hello # 输出独立可执行文件如果要从源码使用本文所有文件路径都基于仓库结构克隆后构建工作空间即可$ git clone https://gitcode.com/GitHub_Trending/sc/scriptc $ cd scriptc pnpm install pnpm -r build $ pnpm scriptc build hello.ts -o hello三、看懂 monorepo 的多包工作空间布局scriptc 仓库本身就是一个典型的多包工作空间其根目录的 pnpm-workspace.yaml 定义了两个包组packages/*与internal/*。根 package.json 中的build脚本pnpm -r --filter ./packages/* run build负责递归构建全部业务包。各包分工如下包路径包名职责packages/cli/scriptc命令行入口含build/run/coverage等命令实现packages/compiler/scriptc/compiler前端、类型化 IR、LLVM 与 C 双后端packages/runtime/scriptc/runtime无 Node 依赖的原生运行时源码Cpackages/llvm-平台/、packages/runtime-平台/各平台二进制包预编译的 LLVM 辅助工具与运行时 packinternal/compatibility/internal/compatibilityNode API 兼容性追踪CLI 命令的核心分发逻辑在 main.ts 中build、run、coverage三选一加上cache warm共四个子命令。理解这个结构你就理解了多包 monorepo 里谁生产、谁消费的边界。四、逐包编译用 scriptc build 输出每个包的原生产物对 monorepo 中最关键的 CLI 包编译一条命令$ scriptc build packages/cli/src/main.ts -o dist/cli-bin产物规则很克制适合 CI默认输出为平台可执行文件不指定-o时落到输入文件旁的.scriptc/目录--emitir|c|llvm只产出源级中间产物*.ir.json、*.c、*.ll只需要 Node不需要任何 C 编译器非常适合先在 CI 廉价层跑类型与降级检查各产物类型会累积在.scriptc/中重复构建只更新对应文件。一个实用技巧对每个包分别执行--emitllvm可以在不链接的情况下快速验证整个工作空间的代码都在 LLVM 静态层内出问题再切到完整构建。五、多包之间的 npm 依赖怎么办monorepo 里包 A 依赖包 B 是常态。scriptc 提供了两档策略策略 1--dynamic动态嵌入$ scriptc build packages/app/src/main.ts --dynamic -o appnpm 依赖的 JS 会在构建时嵌入二进制运行时不再读取node_modules产物可以放到任何目录直接执行。引擎约 620KB仅在显式开启时才存在——二进制绝不会悄悄变大。策略 2--npm-static静态编译实验性$ scriptc build main.ts --npm-static auto -o app将符合条件的 npm 包直接编译为静态程序模块而不是交给嵌入式引擎。preflight 拒绝的包会自动回退到动态层并在覆盖率报告中注明原因。六、交叉编译一次构建输出多平台原生二进制这是 monorepo 发版最需要的能力。通过环境变量SCRIPTC_CCzigccSCRIPTC_TARGET目标三元组同一份源码可以产出 Linux、Windows、WASI 三种原生产物$ SCRIPTC_CCzigcc SCRIPTC_TARGETaarch64-linux-gnu.2.36 \ scriptc build main.ts -o app-linux $ SCRIPTC_CCzigcc SCRIPTC_TARGETx86_64-windows-gnu \ scriptc build main.ts -o app.exe $ SCRIPTC_CCzigcc SCRIPTC_TARGETwasm32-wasi \ scriptc build main.ts -o app.wasm仓库自带的 bench-builds.mjs 就是用来批量对比多目标构建耗时的脚本可作为多平台 CI 矩阵的参考。七、上线前体检用 coverage 定位不可编译点在把每个包推上原生流水线之前先跑一次零成本的静态覆盖分析$ scriptc coverage packages/cli/src/main.ts报告会给出语句级的判定多少可静态编译、哪些站点需要--dynamic、哪些被拒绝以及对应的SC错误码。配合 docs/src/app/introduction/page.mdx 中对三层模型的说明你可以把每个包的动态残留当作技术债来清零。八、进阶库模式与外部链接如果你希望把某个包编成可被外部 C 工程链接的原生库而非独立可执行文件使用--lib库模式命令入口见 main.ts 的库模式分支$ scriptc build --lib --profile tests/library-mode/buffers/profile.jsonprofile JSON 声明入口模块与导出通道产物是一个自包含的静态归档。测试语料可参考 tests/library-mode/。另一条路是--emitobj--printnative-link-info产出可重定位目标文件并打印一份版本化 JSON 链接配方目标、入口、精确的运行时 pack、系统库、FFI 输入供外部 C 驱动或链接器消费完整示例见 examples/native-object/。九、构建提速缓存预热与环境变量多包工作空间重复构建时善用持久化缓存$ scriptc cache warm runtime tls dynamic常用环境变量详见 CLI 参考文档SCRIPTC_CACHE_DIR/SCRIPTC_NO_CACHE控制缓存根目录与开关SCRIPTC_CACHE_MAX_MB缓存容量上限默认 4096MBSCRIPTC_LINKER指定 macOS arm64 平台链接驱动SCRIPTC_TARGET跨编译目标三元组。CI 中预热缓存可显著缩短矩阵构建时间仓库自身的沙箱测试脚本 sandbox-test.mjs 展示了在隔离环境中安装工具链并构建工作空间的完整流程。十、小结monorepo × 原生二进制的完整工作流把本文方法串起来就是一个可复制的多包发版流水线布局packages/*业务包 internal/*工具包根 workspace 统一编排体检每包scriptc coverage清零静态拒绝项编译scriptc build -o 平台产物npm 依赖按--dynamic/--npm-static二选一发版SCRIPTC_TARGET矩阵交叉编译 Linux / Windows / WASM加速cache warm 缓存环境变量压短 CI 时长。最终你得到的是无 Node、无 node_modules、启动毫秒级的一组自包含原生二进制——这才是 monorepo 输出一个仓库、多平台原生产物的正确打开方式。【免费下载链接】scriptcTypeScript-to-Native Compiler项目地址: https://gitcode.com/GitHub_Trending/sc/scriptc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考