前端项目代码批量替换域名问题
最近参与开发的产品有国内站和国际站之分,但代码维护的同一份,国际站与国内站,除了特定业务的不同,比如某些产品没有之外,主要即链接地址区别,
为了可维护性,代码中我们仍然写的是国内站链接,如果国际站用户访问,点击链接,则会302自动跳转到国际站链接下,足够的快,这个体验还OK。
但最近多种原因下,自动跳转关掉了,为了还是保持一份代码适应国际站/国内站,我们需要更新项目中已经散落各处的国内站链接,将其替换为不固定域名方式即变量写法,,比如将
https://1991421.cn/2021/09/21/844e39cc/
替换为https://${window.basicHost}/2021/09/21/844e39cc/
。如何优雅的解决这个问题呢?
直接正则替换?
首先,想到的是直接的正则替换,但是尝试了下发现并不行,原因是ES6加下的代码写法种类太多,且这个问题根本上来说是将常量改成了变量拼接,因此直接文本替换是不行的。
列举下,代码中牵扯到链接的不同上下文写法
1 | href="https://1991421.cn/2021/09/21/844e39cc/" |
AST+正则替换
直接正则替换无法解决的直接原因是写法的不同,但是如果在代码编译到ES5后,写法即固定了,一定是单独的字符串,比如”//1991421.cn/2021/09/21/“+ postId。而这个时间点可以在webpack中很容易找到找到,比如compilation.hooks.optimizeChunkAssets
。
理论上到此可以正则进行字符串替换即可。但是替换还要解决,将字符串的符号获取,从而拼接增加JS对象变量。而这单纯正则搞会麻烦些,而AST来解决就简单多了。根本原因在于AST是从语法角度分析JS代码,直接找到字符串变量,同时获取符号即可。当然思路OK,那就是webpack插件编写了。
实践
webpack插件
因为最终是将JS代码进行解析转为AST,从而正则替换部分字符串,因此webpack插件来做最为合适。
具体插件可以在这里下载使用
- webpack插件部分,根据webpack暴露的hook选择chunk生成后的hook即可。
- 获取chunk源码,做AST解析从而实现替换即可。
关键替换logic如下
1 |
|
HMR下插件问题
当前如果是开发模式- HMR下会出现替换错误,因此建议插件增加环境判定,比如
1 | ... |
同时如果本地进行构建打包,注意环境变量问题,推荐cross-env解决,比如
1 | npx cross-env NODE_ENV=production npm run build:dev |
写在最后
- 如上解决后,以后业务代码中还是可以正常的