npm workspace下TypeScript monorepo如何配置Webpack HMR生效
npm workspace + TypeScript Monorepo 公共库HMR失效修复方案
核心问题根源:当前配置下webpack解析本地公共库时,读取的是公共库dist目录下的预构建产物,而非源码文件。公共库源码变更不在webpack的文件监听范围内,且软链解析、node_modules默认忽略规则进一步阻断了变更事件传递,才会导致每次改库都要手动重构建、刷新页面。
按以下步骤调整配置即可实现全链路HMR:
1. 调整公共库package.json的导出规则
区分开发、生产环境的入口指向,开发环境直接指向源码,生产环境指向构建后的dist产物,替换原有统一指向dist的main/module字段逻辑:
{ "main": "./dist/esm/xx.js", "module": "./dist/esm/xx.js", "types": "./dist/typings/xx.d.ts", "exports": { ".": { "development": "./src/index.ts", "production": "./dist/esm/xx.js", "types": "./dist/typings/xx.d.ts" } } }
如果公共库需要暴露子路径入口,在exports中按相同规则追加对应映射即可。
2. 修改各应用webpack配置,放开本地公共库的监听与编译
默认webpack会忽略node_modules下的所有文件变更,且不会跟随软链解析到workspace真实源码路径,需要覆盖默认规则:
module.exports = { // 其他原有webpack配置 resolve: { symlinks: true, // 开启软链追踪,定位到公共库的真实源码路径 // 保留原有alias、extensions等配置 }, snapshot: { // 仅将第三方公共依赖纳入托管缓存,不缓存自有作用域下的本地库 managedPaths: [/node_modules[\\/](?!@company)/] }, watchOptions: { followSymlinks: true, // 监听规则:忽略所有第三方node_modules,但保留对@company作用域下本地库的监听 ignored: ['**/node_modules/**', '!**/node_modules/@company/**'] } }
同时调整TS/JS转译loader的排除规则,默认loader会跳过node_modules下的文件编译,需要放开对自有本地库的编译处理,以ts-loader为例:
{ test: /\.tsx?$/, loader: 'ts-loader', options: { transpileOnly: true, // 建议配合fork-ts-checker-webpack-plugin做异步类型检查,提升构建速度 allowTsInNodeModules: true }, // 仅排除第三方依赖,不排除自有本地库 exclude: [/node_modules[\\/](?!@company)/] }
如果使用babel-loader、swc-loader等其他转译工具,按相同逻辑调整exclude规则即可。
3. 调整TypeScript配置,开发态直接解析源码
在根目录tsconfig.json中增加paths映射,让TS开发态直接读取公共库源码而非dist下的预构建类型文件,原有incremental、composite配置可保留:
{ "compilerOptions": { "baseUrl": ".", "paths": { "@company/local_library*": ["./local_library*/src/index.ts"] } } }
如果有子路径导出,同步在paths中追加对应映射即可。
4. 调整脚本命令,分离开发与生产构建流程
开发态不需要提前构建公共库产物,直接启动应用即可,webpack会实时编译公共库源码;仅在生产构建时先执行公共库构建,再打包业务应用:
// 根目录package.json { "scripts": { "dev": "npm run start --workspace=source", "build:libs": "npm run build --workspace=local_library1 --workspace=local_library2", "build": "npm run build:libs && npm run build --workspaces --if-present" } }
避坑提示
- 开发环境不要使用DllPlugin、HardSourceWebpackPlugin等预缓存插件预打包本地公共库,否则会缓存旧产物阻断HMR
- 如果公共库包含样式、静态资源等非TS/JS文件,确保对应loader的规则也覆盖到@company作用域下的文件,不要仅处理应用自身src目录
- 若使用vite而非webpack作为构建工具,核心逻辑一致:调整optimizeDeps.exclude将本地公共库排除出预构建,同时配置server.watch放开对软链路径的监听即可
内容的提问来源于stack exchange,提问作者Massimo
相关产品推荐
相关产品推荐

