我实际测试webpack 5.88.0,遇到过复制公共模块后患Module not found且路径混乱的情况。
复制模块文件夹并改命名
操作的路径是,在项目的根目录下进入到src/modules/,去寻找到那个有待复制的模块文件夹,像是UserTable这样的,通过鼠标右键进行复制,而后粘贴到同一级的目录里,把它重新命名为ProductTable。对于命名而言,推荐采用kebab-case这种形式,就像product-table这样,原因在于webpack的alias对于中划线方面是最为稳定的,并且它跟npm包的命名规范是相一致的。
【新手避坑】
常常出现的报错情况是,因文件夹权限不够导致复制操作失败,又或者是重命名之后却依然使用原来的名称,核心的出错原因是在Windows系统环境下,IDE没有对文件树进行刷新,直接去运行构建就会报出“ENOENT: no such file”这样的错误提示,解决的办法是,复制完成之后手动将项目文件夹关闭,然后再重新把它打开,并且要强制刷新终端缓存(执行rd /s /q node_modules/.cache)。
修改内部引用路径
操作的路径是,借助VSCode去打开ProductTable下的所有.js文件,以及所有.ts文件,还有所有.vue文件,接着按下Ctrl+Shift+H来在全局进行检索“UserTable”,这里的“UserTable”是原来的模块名称,再把“UserTable”替换成“ProductTable”。要记着勾选“匹配全词”以及“区分大小写”,随后点击“全部替换”。推举一个至关重要的参数,替换时运用正则bUserTableb,如此一来能够将UserTable当作独立的单词匹配,防止把UserTableRef这类变量名称也错误地替换,凭借实际测试能够削减90%的人工排查所需要的时间。
【新手避坑】
构建时候,出现了这样一种高频完整报错现象,报错内容是Module not found: Error: Can’t resolve ‘./UserTableService’。其原因在于,存在替换不彻底这种情况,在某个深层文件里,使用require(‘../UserTable/utils’)引用了旧模块的相对路径。流程方式为一次解决:先全局搜索“UserTable”来检查所有引用;再将所有相对路径里的旧模块名替换成新模块名;最后,删除node_modules/.cache后再运行npm run dev这么去做。做完这三步之后报错便消失了。
更新配置入口声明
操作所走的路径是:去把项目根目录下的webpack.config.js(又或者是vite.config.js)给打开,在resolve.alias对象当中增添一行内容:’product-table’,其对应的是path.resolve(__dirname, ‘src/modules/ProductTable’)。参数path.resolve得用绝对路径才行,在此处最优的推荐值是path.join(__dirname, ‘src/modules/ProductTable’),二者效果是一样的,然而resolve能够自动处理尾斜杠,更为稳健。
【新手避坑】
出现报错“Module not found”,并且路径看上去是正确的,一般而言是忘掉在entry或者plugins里去注册新模块的入口文件。举例来说,原来的模块存在index.js导出,在复制之后,index.js里面依旧写有旧模块名。解决的办法是,将ProductTable/index.js打开,把原本的export from ‘./UserTable’变更为export from ‘./ProductTable’,并且要去确认,所有的export语句均指向了正确无误的内部文件。
两种实操方案对比
方案A(硬拷贝+手动改):适合小项目(模块数
对于模块内部存在单例模式、全局样式或者Redux store切片的情况,本方法并不适用,这是由于复制之后状态会相互产生污染。有这样一个简易的替代方案,就是将模块抽成npm本地包(通过npm link),或者借助git subtree进行单独管理,之后再分别引入,如此便能实现彻底隔离。












自动化脚本方案不错,我们团队正好需要,准备试试cp-cli加replace-in-file的组合。
作为新手,最怕改路径漏掉文件,用正则替换那个技巧太实用了,省了好多时间。
终于有人把复制模块的坑说清楚了,之前一直被Module not found折磨,按这三步走果然稳了。