如果你现在还在用 Webpack 打包 TS 项目,大概率经历过这样的时刻:改一行代码,热更新要等好几秒;新增一个依赖,构建时间直奔两三分钟;配置文件写了一百多行,只为了处理 loader、plugin、alias、环境变量;等终于跑起来了,类型检查又在某个不起眼的 fork-ts-checker 环节给你一个红色报错。
这不是错觉,也不是你配置写得不好。而是 Webpack 这套“配置驱动”的构建方案,在 TypeScript 已经成为主流的今天,确实越来越吃力。前端构建正在从“配置驱动的打包器”走向“性能优先 + 类型安全”的组合工具链,TS + Vite + tsup + Rolldown,不是新奇的玩具,而是已经能落地的替代方案。
这篇文章不打算劝你把现有项目立刻推翻重来,而是想从实际问题出发,把这套组合拳拆开看明白:Vite 解决什么、tsup 解决什么、Rolldown 又会在未来取代什么,TS 在其中应该扮演什么角色。读完你会得到一个清晰的选型判断,以及可以直接照着做的迁移示例和排错思路。
1. 为什么 Webpack 在现代 TS 项目里越来越吃力
1.1 配置复杂度正在失控
Webpack 很强大,但强大的代价是配置面极广。一个真实业务项目里,webpack.config.js 常常要同时处理:babel-loader 转译 TS、ts-loader 做类型检查、css-loader / style-loader / MiniCssExtractPlugin 处理样式、file-loader 处理静态资源、DefinePlugin 注入环境变量、webpack-dev-server 的 proxy 和 historyApiFallback、terser-webpack-plugin 做压缩和注释清理、splitChunks 做代码分割。
这些配置不是写一次就结束。每升级一次依赖,都可能踩到 loader 版本不兼容的坑。网上搜索“webpack 打包优化配置”,大部分结果都是围绕 cache-loader、thread-loader、HardSourceWebpackPlugin 这些“补丁式”方案。这说明什么?说明 Webpack 项目的性能问题不是简单的配置问题,而是架构层面的编译链路太长了。
TS 项目尤为明显。ts-loader 需要把整个 TypeScript 编译一遍,编译器还会因为 declaration、sourceMap、isolatedModules 等选项影响整体速度。后来大家用 babel-loader 只做转换、不做类型检查,再单独启动 fork-ts-checker-webpack-plugin 做类型检查,还要手动隔离两个流程。类型检查、语法转换、模块打包、代码压缩,这些步骤串在一起,构建链路自然快不起来。
1.2 Webpack 的编译机制是瓶颈
Webpack 的编译核心是 JavaScript 实现的,模块图解析、依赖收集、代码生成都发生在 JS 运行时。对于大型项目,模块数量动辄上万,JS 做这种事情天然有性能上限。即使 Webpack 5 引入了持久化缓存,第一次冷启动构建依然很慢,CI 环境里尤其明显。
Webpack 的 HMR 也不是不好,只是在大项目里,修改一个组件,热更新传播路径太长,经常出现“改了代码,页面刷新了但状态丢了”或者“等了好几秒才更新”的体验。这种体验在开发阶段是持续性的成本,一天下来浪费的时间相当可观。
这里要澄清一点:Webpack 并没有被时代抛弃,它依然是生态最完整、兼容性最强的打包器。但在“TS 项目 + 开发体验 + 构建性能”这个组合维度上,它已经不是最优解了。
1.3 新一代工具的共同特点
Vite、tsup、Rolldown 这些工具的共同特点是:用原生语言(Go、Rust)做底层编译和解析,把 JS 只当作胶水层;应用级构建用 esbuild 做预打包和转换、用 Rollup 做最终打包;库级构建用 tsup 直接基于 esbuild 输出 ESM/CJS;未来 Rolldown 会用 Rust 实现 Rollup 兼容的逻辑,彻底解决“上层工具很好、底层引擎是 JS”的尴尬。
这其实是一次工程范式变化:不再追求“一个配置文件管所有”,而是让每个工具做自己最擅长的事,再通过统一的标准(ESM、TS 类型声明、Node API)组合起来。
2. 构建工具全景:Vite、tsup、Rolldown 到底解决什么问题
2.1 先分清三个工具的角色
很多同学会把 Vite、tsup、Rolldown 混为一谈,觉得它们都是“打包工具”,可以互相替代。这个理解不准确。
Vite 是应用级开发服务器和构建工具,定位是替代 Webpack 在 web 应用里的位置。它的特点是开发阶段用原生 ESM + esbuild 转换,启动快、HMR 快;生产构建用 Rollup 打包,保证产物质量和 Tree Shaking。
tsup 是库级打包工具,定位是帮开发者把 TS 写的 npm 包打成 ESM 和 CJS 双格式产物,同时生成 .d.ts 类型声明。如果你在写组件库、工具函数库、SDK,tsup 是最省心的选择。
Rolldown 是构建引擎,用 Rust 实现的 Rollup 兼容版本,是 Vite 未来的底层核心。它不是给开发者直接用的配置工具,而是给 Vite 等上层工具提供性能底座的。
一个比喻:Vite 是装修公司,帮你把整间屋子装好;tsup 是一个专注做柜子的工厂,批量生产标准件;Rolldown 是更高效的建材生产线,装修公司以后会用它来降低成本、提高速度。
2.2 核心对比
| 工具 | 定位 | 核心语言 | 主要使用场景 | 代表作 |
|---|---|---|---|---|
| Webpack | 应用打包器 | JavaScript | 兼容性要求高的大型应用 | Webpack 5 |
| Vite | 应用开发服务器 + 构建工具 | Go(esbuild)+ JS(Rollup) | 新项目、TS 项目、Vue/React 应用 | Vite 5/6 |
| tsup | 库打包工具 | Go(esbuild) | npm 包、组件库、工具库 | tsup |
| Rolldown | 构建引擎(Rollup 兼容) | Rust | Vite 底层、未来构建基础 | Rolldown |
| esbuild | 转译 + 打包引擎 | Go | 被 Vite/tsup 依赖 | esbuild |
| Rollup | 打包器(ESM 优先) | JavaScript | Vite 生产构建、库打包 | Rollup 4 |
从这个表里能看出一个趋势:前端构建不再是一个工具通吃,而是分层组合。应用层用 Vite,库层用 tsup,底层引擎交给 esbuild / Rolldown。
2.3 明确判断
如果你是新开的 TS 项目,我建议直接放弃 Webpack,选 Vite。如果你是写 npm 包,不要再用 webpack 或 rollup 手动配一堆插件,用 tsup。如果你关心未来趋势,需要盯住 Rolldown,它会让 Vite 在大型项目上的冷启动和构建性能再上一个台阶。
这不是说 Webpack 一无是处。如果你们的项目已经运行多年,深度依赖 webpack 的 html-webpack-plugin、copy-webpack-plugin、自定义 loader、老版本 Node 兼容性,迁移成本很高,那继续用 Webpack 也合理。但新项目再选 Webpack,等于主动放弃了已经成熟的更好方案。
3. TS 在新型构建链中的位置
3.1 等一等,TS 编译跑哪里去了?
很多从 Webpack 迁移到 Vite 的同学,第一次看到 vite.config.ts 时会疑惑:我的 ts-loader 呢?babel-loader 呢?为什么没配置 TS 也能跑?
这是理解新构建链的关键:TS 的职责被拆开了。
传统链路里,ts-loader 同时干了“语法转换 + 类型检查 + 模块解析”三件事。新链路里,语法转换交给 esbuild,模块解析和打包交给 Vite,类型检查单独交给 tsc --noEmit。
esbuild 转换 TS 时,只是把类型注解剥掉、把语法翻译成目标 JS,不做类型检查。所以速度极快,但这意味着:esbuild 不会因为类型错误而报错。类型安全必须靠tsc --noEmit在独立环节保证。
3.2 类型声明产物哪里来
如果你用 tsup 打包库,需要给使用者提供 .d.ts 类型声明。tsup 的 dts 选项会借助 rollup-plugin-dts 或 tsc 生成类型声明。这意味着你在 tsconfig.json 里配置的 compilerOptions 会影响 dts 输出,尤其是 declaration、declarationDir、paths 这些字段。
实际项目中常见的问题是:dts 生成成功但类型路径不对,或者因为 tsconfig 里开了isolatedModules导致无法直接用 tsc 生成声明。解决方式一般是在 tsup 配置里单独给 dts 指定 tsconfig,或者保持主 tsconfig 足够简洁。
3.3 常见误区
- 误区一:用 tsc 直接打包。tsc 会保留 import 语句、不会做 bundle,产物没法直接发布给浏览器用,除非你只做 Node 包且不关心格式。
- 误区二:用 tsup 做类型检查。tsup 默认不做类型检查,类型错误要单独跑 tsc。
- 误区三:Vite 项目里没有类型检查就上线。Vite 不会拦截 TS 类型错误,CI 里必须加
vue-tsc --noEmit或tsc --noEmit这一步骤。
// package.json scripts 示例,注意构建前的类型检查 { "scripts": { "dev": "vite", "build": "tsc --noEmit && vite build", "preview": "vite preview" } }这个设计好不好?我认为是好设计。语法转换和类型检查解耦后,开发阶段可以获得极快的速度,类型安全在 CI 和构建阶段把关,兼顾体验和可靠性。
4. 实战一:把 Webpack TS 项目迁移到 Vite
4.1 迁移前检查清单
不是所有 Webpack 项目都适合直接迁到 Vite。迁移前先回答这几个问题:
- 项目依赖里是否有原生 Node 插件,或者依赖 webpack 特定 API 的自定义 loader?
- 是否使用了 webpack 的魔法注释做动态导入命名?
- 是否依赖 process.env.NODE_ENV 之外的大量自定义环境变量?
- 是否使用 postcss 和 autoprefixer?这部分 Vite 支持得很好,可以直接复用。
- 是否使用了 webpack-bundle-analyzer 做体积分析?Vite 可以用 rollup-plugin-visualizer 替代。
如果项目不是特别复杂,迁移通常可以在一个工作日内完成。核心工作是改写 vite.config.ts、调整 tsconfig.json、清理 webpack 特有配置。
4.2 package.json 脚本变化
迁移最直观的差异在 scripts 里。Webpack 项目的典型脚本是:
// 迁移前的 package.json(简化) { "scripts": { "dev": "webpack serve --mode development", "build": "cross-env NODE_ENV=production webpack", "build:analyze": "cross-env NODE_ENV=production webpack --json > stats.json" } }迁移后:
// 迁移后的 package.json(简化) { "scripts": { "dev": "vite", "build": "tsc --noEmit && vite build", "preview": "vite preview", "build:analyze": "vite build --mode analyze" } }注意cross-env在 Vite 中不再需要,Vite 通过--mode和 .env 文件管理环境变量,跨平台体验更自然。
4.3 vite.config.ts 核心配置
一个包含别名、代理、构建配置、组件自动导入的项目配置大概长这样:
// 文件路径:vite.config.ts import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import { resolve } from 'node:path'; import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ plugins: [vue(), visualizer({ open: true, gzipSize: true })], resolve: { alias: { '@': resolve(__dirname, 'src') } }, server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } }, build: { target: 'es2019', outDir: 'dist', sourcemap: false, rollupOptions: { output: { manualChunks: { vendor: ['vue', 'vue-router', 'pinia'], echarts: ['echarts'] } } } } });这段配置里真正需要重点理解的是 proxy。Webpack 里 proxy 写在 devServer.proxy,Vite 里写在 server.proxy,语义基本一致。但真实项目里经常遇到这个报错:
[vite] http proxy error: /api/form/list?page=1&pagesize=10 AggregateError这个报错绝大多数情况是后端服务没有启动,或者 target 地址写错,或者后端需要 HTTPS 但你配的是 HTTP。排查顺序是:先用 curl 直接请求 target 地址确认后端可用,再确认代理路径和 rewrite 是否合理,最后看网络请求的完整路径。
4.4 tsconfig.json 适配
Vite 项目里 tsconfig 需要拆成两个文件,这是和 Webpack 项目很不一样的地方。
根目录的 tsconfig.json 用于编辑器提示和类型检查,node 端配置在 tsconfig.node.json,专门给 vite.config.ts 用。示例:
// 文件路径:tsconfig.json { "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "strict": true, "jsx": "preserve", "resolveJsonModule": true, "isolatedModules": true, "esModuleInterop": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "types": ["vite/client"], "baseUrl": ".", "paths": { "@/*": ["src/*"] } }, "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "references": [{ "path": "./tsconfig.node.json" }] }// 文件路径:tsconfig.node.json { "compilerOptions": { "composite": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "types": ["node"] }, "include": ["vite.config.ts"] }这里最关键的一点是"moduleResolution": "bundler"。这是 TS 5.0 引入的模块解析策略,专为 Vite、tsup 这类 bundler 设计,能同时支持 ESM 和 CJS 的解析方式。如果还停留在"node"或"node16",很可能遇到路径别名不生效或者 import 后缀名报错。
4.5 浏览器兼容与构建目标
Vite 生产构建默认目标较高,如果你需要兼容旧浏览器,注意把 build.target 调低,比如 es2015,同时确保依赖中不包含未转译的新语法。和 Webpack 的 browserslist 机制不同,Vite 直接基于 target 控制转译程度,这个语义更直接,但也意味着你需要对自己项目的用户群体有清晰认知。
5. 实战二:用 tsup 打包 TS 工具库
5.1 为什么写库更适合 tsup
如果你写过一个 npm 包,大概体会过配置 Rollup 构建 TS 库的痛苦:需要 @rollup/plugin-typescript、@rollup/plugin-commonjs、@rollup/plugin-node-resolve、rollup-plugin-dts,还要处理 external 和 peerDependencies,一套配置下来上百行。
tsup 把这一切收敛成了几行配置。它基于 esbuild,把 TS 转换、代码压缩、ESM/CJS 双产物、d.ts 生成、sourcemap、watch 模式全部内置了。
5.2 一个最小可用的 tsup 配置
// 文件路径:tsup.config.ts import { defineConfig } from 'tsup'; export default defineConfig({ entry: ['src/index.ts'], format: ['esm', 'cjs'], dts: true, sourcemap: true, clean: true, treeshake: true, external: ['react', 'react-dom'], outDir: 'dist' });核心参数解释:
- format: 同时输出 ESM 和 CJS,这是 npm 包最常见的需求。
- dts: true 会生成 .d.ts 类型声明文件。
- external: 把 react、react-dom 等 peerDependencies 排除出打包产物,避免重复打包 React。
- treeshake: 启用 Tree Shaking,让使用方可以按需引入。
5.3 external 与 peerDependencies 的关系
external 和 package.json 里的 peerDependencies 需要配对使用。tsup 只管打包时“不把某个依赖打进去”,如果 package.json 里没声明 peerDependencies,使用方安装时不会自动安装这个依赖,运行时会直接报 “Module not found”。
// 文件路径:package.json { "name": "my-lib", "version": "1.0.0", "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "require": "./dist/index.cjs" } }, "files": ["dist"], "peerDependencies": { "react": ">=17.0.0" } }exports 字段在现代 Node 和打包器里优先级最高,一定要配置好,否则使用方可能引用到错误的产物格式。
5.4 如何验证产物
打包完成后不能只看 dist 目录有没有文件,建议做两个验证:
第一,跑一遍npm pack或publint,检查产物路径和 exports 声明是否一致。第二,用一个干净的测试项目 install 你的产物,分别用import和require引入,确认两种格式都正常。
很多包发布后出现 “Named export not found” 或 “ERR_MODULE_NOT_FOUND”,根源都是 exports 声明和实际 dist 文件对不上,这些问题在本地测试项目里都能提前发现。
6. Rolldown:下一代底层构建引擎
6.1 为什么要有 Rolldown
前面提到 Vite 生产构建用的是 Rollup。Rollup 很成熟,但依然是 JavaScript 实现,在大型应用上打包阶段仍有性能瓶颈。同时 Vite 开发阶段用 esbuild、生产阶段用 Rollup,这两套引擎之间存在细微的行为差异,偶尔会出现“开发环境正常、构建产物异常”的边界问题。
Rolldown 的目标是用 Rust 实现一个 Rollup 兼容的打包引擎,让 Vite 的开发和构建统一使用同一个高性能底层。从公开信息来看,Rolldown 团队在模块解析、Tree Shaking、代码生成等 Rollup 核心链路上做了 Rust 重写,同时计划保持 Rollup 插件生态的兼容性。这意味着未来大部分现有 Vite 插件无需修改就能继续工作。
6.2 它对普通开发者的影响
短期看,普通开发者不需要直接使用 Rolldown。Vite 会把 Rolldown 作为内部引擎集成,大多数人的感知是:升级 Vite 版本后,构建变快了,内存占用变低了。
中期看,Rolldown 可能影响库打包工具。如果 tsup 或其他库打包器在底层从 esbuild 切换到 Rolldown,库产物的 Tree Shaking 效果可能更接近 Rollup。但目前这只是趋势,具体要看生态演进。
6.3 现在要不要等 Rolldown?
不要等。工具链的迁移成本永远比工具本身更重要。Vite + tsup 现在就是可用而且好用的方案,Rolldown 稳定后,你只需要升级 Vite 版本,业务代码和配置几乎不用改。如果为了“等 Rolldown”而继续忍受 Webpack 的构建速度,这账不划算。
7. 常见问题与排查方法
7.1 高频问题速查表
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| vite 启动后 proxy 报 AggregateError | 后端未启动 / target 配置错误 / 协议不匹配 | 直接 curl target 地址,确认后端可达 | 修正 target,调整 rewrite 规则 |
| 运行时报 cannot find package 'vite' imported from | node_modules 不完整 / 幽灵依赖 / pnpm 安装模式差异 | 删除 node_modules 重新安装;检查是否在子包内 import vite | 使用pnpm approve-builds或在根目录统一安装依赖 |
| 构建产物里还有很多注释 | terser 注释清理参数未配置 | 检查压缩插件配置 | Webpack 配 terser 的 extractComments: false;Vite 使用 esbuild.legalComments 控制 |
| TS 类型检查不通过,但 Vite 开发正常 | Vite 不做类型检查,需要单独 tsc | 查看 tsc --noEmit 输出 | 在 build 脚本前加上 tsc --noEmit |
| alias 路径在编译时报错 | tsconfig paths 与 vite alias 未同步 | 分别检查两边配置 | 让 tsconfig paths 和 vite resolve.alias 保持一致 |
| tsup 打包后缺少 .d.ts | dts 配置未开启 / tsconfig declaration 冲突 | 查看 dist 目录,检查 tsup dts 配置 | 设置dts: true,必要时单独指定 tsconfig |
ERR_MODULE_NOT_FOUND使用 npm 包时 | package.json exports 指向错误路径 | 用 publint 或 npm pack 后安装测试 | 修正 exports 和 files 字段 |
7.2 关于 Vite 6 的 CJS 调试提示
如果你在某个老项目里使用require('vite'),可能遇到过 Vite 的报错提示,提示中会出现vite_cjs_trace=true这样的调试变量。这个变量的作用是让 Vite 在 CJS 导入时打印更详细的调用栈,帮助定位到底是谁在 Node 环境里用 require 引用了 Vite。这类问题常见于某些构建工具插件或者老版本 Vue CLI 项目。排查思路是:先在项目里全局搜索require('vite')或import vite from 'vite',确认调用方;然后决定是升级依赖版本,还是修改调用方式为动态 import。
7.3 关于 webpack 配置中常见的 public 目录问题
热词里有一条很有意思的报错信息:content not from webpack is served from e:\sourcecode\saaswms\wms\public。这是 webpack-dev-server 的正常提示,意思是 public 目录下的静态资源不经过 webpack 打包,直接由 dev server 托管。这条信息本身不是错误,但它经常被误判。迁移到 Vite 后,对应的概念是publicDir,默认值就是public,行为也类似。如果迁移后发现静态资源找不到,优先确认资源是否放在 public 目录,以及引用路径是否以/开头。
7.4 排查方法论
无论是 Webpack 还是 Vite,构建类问题的排查路径都差不多:先定位是哪一层出了问题(依赖安装、配置解析、语法转换、模块解析、代码压缩、运行时),再用最小化方式复现,最后看具体报错堆栈和对应源码位置。不要一开始就打开搜索引擎复制整段配置,那基本是在碰运气。
8. 选型建议与最佳实践
8.1 不同项目怎么选
| 项目类型 | 推荐方案 | 理由 |
|---|---|---|
| 新开的 Vue/React 应用 | Vite | 启动快、HMR 快、TS 支持好、插件生态成熟 |
| 存量 Webpack 大型应用 | 评估后逐步迁移 | 优先迁移开发服务器,再做生产构建迁移 |
| 工具函数库 | tsup | 零配置输出 ESM/CJS + d.ts |
| 组件库 | tsup 或 Vite 的 lib 模式 | 需要额外考虑样式处理和按需引入 |
| 需要兼容低版本浏览器的项目 | 谨慎使用新工具 | 确认构建 target 和 polyfill 方案 |
| 对构建性能要求极高的超大项目 | 关注 Rolldown 进展 | 等 Vite 集成稳定后升级 |
8.2 工程层面的具体建议
第一,环境变量统一管理。Webpack 项目里 process.env 满天飞,迁移到 Vite 后应该改为 import.meta.env,并且只在 src 目录里使用。.env 文件按环境拆分为 .env.development、.env.production、.env.test,敏感信息不要提交到仓库。
第二,类型检查独立成环节。无论是 Vite 还是 tsup 项目,都要在 CI 里加 tsc --noEmit。这一步能拦住大量低级类型错误,而不是把希望全寄托在编辑器上。
第三,产物分析常规化。每次构建后打开分析报告,关注重复依赖、chunk 数量、首屏加载体积。体积问题越早发现,修复成本越低。推荐 rollup-plugin-visualizer 做 Vite 的产物分析,它可以生成 tree map 和 sunburst 图,比单纯看控制台输出直观很多。
第四,依赖治理要跟上。很多构建性能问题来自依赖太老或者版本冲突。使用 pnpm 管理依赖,并在 CI 里跑 depcheck 或 knip 检查未使用的依赖,构建链路会清爽很多。
第五,保留 Webpack 时的浏览器兼容思路。Vite 的 target 是直接的语法转译目标,但 polyfill 不会自动引入。需要 core-js 的业务代码仍然要自己引入,这是从 Webpack 迁移时常被忽略的一个点。
8.3 团队迁移的节奏建议
最稳妥的迁移路径不是“一夜重写”,而是先搭一个最小可行脚手架,把核心依赖和配置跑通,再逐步迁移页面和路由。推荐节奏:
- 第一天:创建 Vite 项目,迁移路由、状态管理、全局样式。
- 第二天:迁移公共组件和工具函数,解决 alias 和环境变量问题。
- 第三天:迁移业务模块,处理动态 import 和懒加载。
- 第四天:对比 dev 和 build 产物,用测试环境验证功能回归。
- 第五天:处理构建体积和性能优化项,加 CI 检查。
过程中做好备份和回滚点,推荐用 git 分支管理迁移进度。遇到不确定的依赖,先用兼容层过渡,不要为了“纯 Vite”而强行删除 Webpack 配置。
9. 总结
这篇文章真正想讲清楚的是:Webpack 不是不好,而是在 TS 项目的开发体验和构建性能上,已经存在更优的组合方案。Vite 负责应用开发和生产构建,tsup 负责库打包,Rolldown 负责未来底层性能,TS 的类型检查则独立为工程环节。三者不是竞争关系,而是分层配合的关系。
如果你手上有新项目,建议直接上手 Vite + TS,用 tsup 维护公共库,把类型检查加进 CI。如果你的老项目还在 Webpack 上,也不必焦虑,用最小的迁移试点去验证体验差异,逐步替换比一次性推翻更可控。Rolldown 值得关注,但不必等待,因为它落地后你只需要升级版本,受益是自动的。
建议收藏备用。下一次再遇到构建缓慢、TS 配置复杂、打包产物膨胀这类问题,先把本文的排查思路过一遍,再决定要不要动配置。