前端阅读 05月27日 16:53
Rspack 如何支持 TypeScript?内置 SWC 编译与类型检查配置
Rspack 通过内置的 SWC 编译器为 TypeScript 提供开箱即用的支持,无需安装 ts-loader 或 babel-loader 等额外依赖,直接导入 .ts 和 .tsx 文件即可完成编译。下面从配置方法、SWC Loader 选项、tsconfig.json 集成、类型检查策略以及常见问题几个方面展开说明。基本配置最小可运行配置一个最简单的 Rspack + TypeScript 项目只需要以下配置:// rspack.config.jsmodule.exports = { entry: './src/index.ts', module: { rules: [ { test: /\.ts$/, use: 'builtin:swc-loader', type: 'javascript/auto', }, ], }, resolve: { extensions: ['.ts', '.js'], },};builtin:swc-loader 是 Rspack 内置的 SWC 加载器,不需要额外安装。SWC 用 Rust 编写,编译速度比 Babel 快 20-70 倍,比 tsc 快 10-30 倍,同时内存占用更低。支持 JSX 的完整配置当项目使用 React + TypeScript 时,需要启用 TSX 解析和 React 自动运行时:// rspack.config.jsmodule.exports = { entry: './src/index.tsx', module: { rules: [ { test: /\.(ts|tsx)$/, use: { loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'typescript', tsx: true, decorators: true, dynamicImport: true, }, transform: { react: { runtime: 'automatic', }, }, }, }, }, type: 'javascript/auto', }, ], }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'], },};这里 type: 'javascript/auto' 不可省略,它告诉 Rspack 将 TypeScript 文件作为普通 JavaScript 模块处理。decorators: true 启用装饰器语法支持,dynamicImport: true 启用动态 import() 语法。SWC Loader 进阶配置编译目标与产物体积SWC 默认可能将代码降级到 ES5,导致产物体积偏大。建议显式指定 target 以控制降级范围:{ loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'typescript', tsx: true, }, transform: { react: { runtime: 'automatic', importSource: '@emotion/react', // 配合 CSS-in-JS 库 }, }, target: 'es2022', // 避免不必要的降级,减小产物体积 externalHelpers: true, // 将 helper 函数抽取为外部依赖 }, env: { targets: '> 0.25%, not dead', coreJs: 3, }, sourceMaps: true, },}target: 'es2022' 让 SWC 只在必要时降级语法,比默认的 ES5 产物小很多。externalHelpers: true 将 __spreadArray、__awaiter 等运行时辅助函数抽取到共享模块中,避免每个文件内联一份。env 选项配合 coreJs 可按需注入 polyfill。全局变量替换在构建时替换环境变量可以消除开发代码:jsc: { optimizer: { globals: { vars: { 'process.env.NODE_ENV': '"production"', }, }, },}配合 Dead Code Elimination,if (process.env.NODE_ENV === 'development') 中的代码块会被完全移除。tsconfig.json 集成Rspack 不直接读取 tsconfig.json 来决定编译行为(这是 SWC 的工作),但 TypeScript 语言服务和类型检查器依赖它。一个典型的 Rspack 项目 tsconfig.json 如下:{ "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "bundler", "lib": ["ES2022", "DOM", "DOM.Iterable"], "jsx": "react-jsx", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "paths": { "@/*": ["./src/*"] } }, "include": ["src"], "exclude": ["node_modules"]}几个关键配置说明:isolatedModules: true:必须开启。Rspack/SWC 逐文件编译,不做跨模块类型分析,这个选项让 tsc 的行为与 Rspack 对齐,避免导出类型但未实际使用的场景下出现运行时错误。noEmit: true:让 tsc 只做类型检查,不输出文件,因为编译工作由 Rspack 完成。moduleResolution: "bundler":适用于 Rspack 这类打包工具的模块解析策略,支持 package.json 的 exports 字段。paths:路径别名映射,但注意这仅影响 tsc 的类型解析,Rspack 的模块解析需要单独配置 resolve.alias。路径别名在 Rspack 中的配置tsconfig.json 中的 paths 不会自动生效于 Rspack 的模块解析,需要在 rspack.config.js 中添加对应的 alias:const path = require('path');module.exports = { resolve: { alias: { '@': path.resolve(__dirname, 'src'), }, extensions: ['.ts', '.tsx', '.js', '.jsx'], },};两边配置需要保持一致,否则编辑器中不报错但构建时找不到模块。类型检查SWC 只做语法转译,不执行类型检查。类型检查需要额外方案:方案一:ForkTsCheckerWebpackPlugin在构建过程中并行执行类型检查,不影响编译速度:const rspack = require('@rspack/core');module.exports = { plugins: [ new rspack.ForkTsCheckerWebpackPlugin({ typescript: { configFile: './tsconfig.json', memoryLimit: 4096, // MB,大型项目可能需要调高 }, }), ],};开发模式下该插件不会阻塞构建,类型错误会以 overlay 或终端警告的形式展示;生产构建时会阻塞,类型错误将导致构建失败。方案二:独立运行 tsc在 CI/CD 中用 tsc --noEmit 单独执行类型检查,与构建过程完全解耦:{ "scripts": { "build": "rspack build", "typecheck": "tsc --noEmit", "ci": "npm run typecheck && npm run build" }}这种方式更灵活,类型检查不影响构建性能,适合大型项目。类型检查的最佳实践开发环境:使用编辑器内置的 TypeScript 语言服务做实时检查即可,不需要在 dev server 中运行 ForkTsCheckerWebpackPlugin,避免拖慢 HMR 速度。生产构建:启用完整类型检查,阻止类型错误的代码部署。CI/CD:将 tsc --noEmit 作为独立步骤,与构建并行执行,缩短流水线耗时。rspack.config.ts — 用 TypeScript 写配置从 Rspack v1.5.0 开始,CLI 内置了对 TypeScript 配置文件的支持。使用 rspack.config.ts 可以获得完整的类型提示:import type { Configuration } from '@rspack/core';const config: Configuration = { entry: './src/index.tsx', module: { rules: [ { test: /\.(ts|tsx)$/, use: { loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'typescript', tsx: true, }, transform: { react: { runtime: 'automatic' }, }, }, }, }, type: 'javascript/auto', }, ], }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'], },};export default config;Rspack CLI 默认使用 --configLoader=auto,会优先尝试原生 TypeScript 支持,失败则回退到 Jiti 转译。常见问题类型声明文件找不到安装对应的 @types 包即可,例如 npm install -D @types/lodash。如果使用自定义类型声明,在 tsconfig.json 的 include 中确保覆盖了声明文件所在目录,或者通过 typeRoots 指定。路径别名在编辑器中正常但构建时找不到模块这是因为 tsconfig.json 的 paths 只影响 TypeScript 语言服务,Rspack 的模块解析依赖 resolve.alias。需要在 rspack.config.js 中添加与 tsconfig.json 一致的 alias 配置。SWC 编译后产物体积比 Webpack 大SWC 默认可能降级到 ES5。在 jsc.target 中指定 'es2022' 或更高版本,同时启用 externalHelpers: true,可以显著减小产物体积。装饰器语法报错在 SWC parser 配置中设置 decorators: true,同时在 tsconfig.json 中配置 "experimentalDecorators": true。如果使用 TC39 Stage 3 装饰器,SWC 需要设置 decorators: true 且 decoratorVersion: "2022-03"。Rspack 的 TypeScript 支持核心在于内置 SWC 编译器带来的零配置转译能力,配合 ForkTsCheckerWebpackPlugin 或独立 tsc 执行类型检查,既能获得极快的构建速度,又能保持完整的类型安全保障。对于从 Webpack 迁移的项目,重点关注 isolatedModules 配置、SWC target 设置和路径别名映射这三处差异即可。