You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
升级完webpack5之后的第一个问题就是,代码报错,报了 arguments is not defined,报错的地方是一个依赖的包,这个报错的原因是 webpack4之前,包裹模块的函数是函数表达式,而webpack4以后改为了箭头函数,所以其实问题一直都存在,只是以前没有暴露出来。
这个问题也好解决,直接升级该包的版本就可以了。
项目背景
团队开发维护的tim项目,分为几个平台,分别是 pc端,app端,微信端,以及外网的一些其他页面总共四个项目。一开始是分成四个仓库维护,公用的部分发npm包维护,但是随着项目的复杂度上升,而且每周至少两个迭代的速度,npm包维护公共工具、库的形式非常繁琐。
改一个东西你需要先改公共包,你要先改包文件,然后发包构建,然后用到的地方可能app需要改,wechat需要改,pc不需要改,一天下来这套流程会浪费不少时间...
所以现在更倾向于合在一个大仓库的形式,公用的部分直接在外面写一个shard包,这样可以解决频繁改动的问题,项目件的公用部分抽离会更加方便。
但是目前app项目中的构建体系不支持这种引用外部包的形式,所以需要对app项目的构建进行一次升级,以支持shard目录的模式,后面再统一对tim-web项目的整体构建。
计划
目前的计划是先对 app 构建体系升级,去除gulp部分,然后再对这个老项目的文件目录与图片路径等进行迁移处理,最后统一用一套构建体系。
构建系统升级其实就是一个发现问题,解决问题,再发现问题的螺旋上升过程。
目前APP主要的痛点是:
hot reload
来解决这个状态问题,并且加快dev-rebuild的速度,可以大大减少同事等待构建摸鱼的时间。遇到的难点其实总结为一点就是,老旧代码的迁移问题,很多代码之前在这套构建没问题,但是你一升级你得对这些旧代码做兼容处理,而且也不能手动改,因为这种构建升级的项目肯定会伴随着业务开发,你现在手动改了很多文件,后面一合代码又是白搭。所以涉及到的改动一方面要记下来,另一方面要尽可能的用脚本去改动。
app 构建升级第一版
第一版最初的设想是与pc端一致,用webpack3先取代gulp,这里总结一下升级中遇到的一些问题
css与js依赖管理
目前app项目中有许多js和css是直接引入的, 类似在 index.html中直接写了 '/public/a/to/b.js',然后文件也直接放在 'public'下面,有点像几年前手动管理依赖的味道,如果你的 jquery 放在需要依赖jq的文件下面,那页面就报错了。
所以做的第一步是把 /vendor 挪到开发目录,然后各自js和css写到一个 vendor.js vendor.css去管理。
webpack3的文档问题
webpack3目前官方没有维护文档,所以你要找对应的文档得去找网上热心网民存的快照。很多的插件也是默认安装时会报不支持 webpack < 4 的版本,而且这些插件的文档也不太好找,一个小技巧就是去npm查看这些插件的版本,然后大概猜一下webpack3需要的版本是多少,一般都是降1-2个大版本。然后再通过npm的版本去看当时这个插件的文档和使用是怎样的,这里再次标明写文档是真的很有用...
gulp.genmockConf 生成文件
这个gulp的任务是根据当前的运行模式,将一些文件的变量替换后,再输出到构建目录,然后index.html直接去引用这些文件,比如 appVersion, apiUrl等。
我们可以选择在index.js引入这些文件,然后通过 webpack.DefinePlugin 来实现,不过这次改造的目标是尽可能只动构建部分,不动代码部分。
所以我选择了用 CopyWebpackPlugin 配合 transform方法来解决这块问题。
css前缀问题
gulp 处理css的时候,老项目会在部分css变量名的前面加一个前缀,比如
.demo
=>.mui-demo
。也就是说在写css/less的时候,是写
.demo
,然后在用的时候是写.mui-demo
。而且只有部分文件需要这么处理。这里我用了一个
postcssSelectorPrefix
的插件来解决,然后将需要加前缀的和不需要加前缀的区分开来,给需要加前缀的单独应用这个 loader。但是这个插件有个问题,一些ionic自定义的标签转换会有问题,转换后.mui-demo的前缀自定义标签不见了,导致很多样式错乱,比如:
后面看了下这个东西实现不复杂,直接fork一个本地改了之后放到项目里维护了。
css 动画消失了
改完后,发现有一些动画消失了,这些动画很多是ionic改的...极其复杂,一时很难找到在哪里加的动画,加的是什么className。尝试性点即几下,发现className有快速变动,于是想到应该又是那个 className 加前缀出的问题。
首先在 chrome 调试直接给这个dom打个
break on attribute modifications
,结果发现触发了n次,特别难察觉到有哪些切换,而且断点一堆也不好看...于是换了一种思路,
MutationObserver
去监听dom变化,在 class attribute变动的时候输出出来,还是没有看出什么问题。最后用 chrome Animations面看查看运动的动画,发现果然是前缀的问题,修改了一下添加前缀的规则解决。
html 改动不触发页面reload
html是放在类似
/public/templates
里面,然后通过angularJs框架运行时去请求html模板进行渲染的,所以他确实也没有参加到我们的构建服务中,这就导致一个问题。如果我们改动这些html,是不会触发reload的,需要手动刷新页面。当下想到两种办法,第一种格式遍历所有的template,然后都写到
webpack.devServer.contentBase
,虽然很hock,但是确实可以解决问题。第二种是看webpackDevServer.watch是怎么处理的,看如何解决这个问题,发现 watch依赖的是
[email protected]
,这个版本已经被废弃了基本无解,所以最后决定用glob
扫出public/template
的文件加到contentBase
中,曲线救国...等后面升级webpack版本就好了。至此,第一版基本完成,和同事讨论之后,同事说这种改造测试起来很废时间,还不如一步到位直接上webpack5好一点...我被说服了...
app 构建升级第二版
第二版直接在第一版的基础上升级webpack的版本,所以总体会感觉轻松一些。但是毕竟升级了两个大版本,问题还是不少。
arguments is not defined
升级完webpack5之后的第一个问题就是,代码报错,报了
arguments is not defined
,报错的地方是一个依赖的包,这个报错的原因是 webpack4之前,包裹模块的函数是函数表达式,而webpack4以后改为了箭头函数,所以其实问题一直都存在,只是以前没有暴露出来。这个问题也好解决,直接升级该包的版本就可以了。
esm和cjs混写问题
旧项目很多是esm和cjs混着写,因为angularJs的依赖注入需要用 cjs,所以一开始是想着用一个脚本去分析ast,然后都改为cjs。后面想着不应该,于是各种找资料,然后在本地直接用 babel编译cjs和esm混用的代码,发现没有报错。最后通过改了babel的配置解决。
production 模式报错
开发测试成功之后,开始自测构建生产环境的代码,发现如果 mode:development一切正常,但是改成production的时候就会一直报 angularJs 模块注入的错误。
这个比较好解决,既然都知道是mode的问题,直接去webpack官网看这两种模式的配置区别是什么,一个一个排除之后发现是代码压缩导致的,修改下配置,去掉 mangle选项后解决。不过具体的原因目前还没有了解。
总结
期间还遇到其他配置等问题,无脑刷官网就可以解决了。
目前改造后未深度优化的效果:
老项目:
改造后:
我觉得最大的作用还不是构建速度和代码大小的问题,最大的作用是为后面很多新特性和改造奠定了根基。
下一步的工作是:
The text was updated successfully, but these errors were encountered: