原项目结构使用了gulp+webpack进行项目自动化流程构建,核心页面使用react框架开发,存在比较严重的问题是由于产品功能的丰富,项目构建耗时越来越长,加上尤其是release项目发布时还使用了 Google Closure Compile 进行代码压缩,整个打包过程耗时近一分钟,实在忍不了,于是搞清楚整个项目构建框架,到底是因为什么导致的。
优点:
缺点:
使用webpack.DefinePlugin配置好开发环境变量,开发环境时,去掉GCC压缩,并添加调试环境代码,比如我在项目中新加了一个叫 why-did-you-update
的库用来检查React多余的渲染,进行性能优化(这个库原先没有的,优化打包性能时新加的,所以最后比较大小时这个库原版本代码本就没有,不计在内),我们只需要在开发环境打包进去,生产环境下是不需要的:
|
|
打包代码增加devpack
任务(其中webpack(env)
是生成webpack配置并打包过程):
|
|
然后,要解决改动代码每次都要手动编译问题。考虑到项目以gulp为主,辅以webpack进行打包,为了减少改动,不使用webpack热更新,而用了gulp的watch方法,监听文件变动后执行一次打包操作(其中devpack
是gulp开发环境下打包命令):
|
|
首先想到的是使用webpack的DllPlugin
,把所有第三方库打包到一个独立文件,但是由于原项目配置了externals,所有代码页都以全局变量访问的 React
等第三方框架库,为了减少改动,我们需要继续暴露出这些第三方库的全局变量,一番摸索过后,发现webpack有一个expose-loader
非常合适。
于是新建一个dll打包配置文件 webpack.dll.js :
|
|
然后在项目主入口打包配置文件中修改 webpack.config.js,添加 DllReferencePlugin
:
|
|
DllPlugin
插件会在编译完第三方依赖库之后,生成一个模块相对路径到模块 id 的映射表 manifest.json
,和 dll.js
文件,然后在编译业务代码时使用 DllReferencePlugin
导入这个映射表,业务代码就能找到第三方依赖里的对应模块了。并且dll中通过 expose-loader
把原先需要的全局变量都挂载到window上,兼容了原项目编码方式,但是需要注意的是 expose-loader
的配置中 require.resolve
是用来获取模块的绝对路径(”../node_modules/react/react.js”),这里的暴露只会作用于 React 模块。并且只在 bundle 中使用到它时,才进行暴露。所以其他模块需要以路径形式获取,比如jqlite test: /\/public\/lib\/js\/jqlite/
,并在项目入口index.js中引入他们(只需引入一次即可):
|
|
对于redux、react-redux的引入,则需要包装一下,再添加到 webpack.dll.js
进行打包:
|
|
好了,现在可以打包测试一下啦,输入 gulp watch
命令,修改代码,自动编译,完成,刷新页面。额。。。花了总共18s,还是很慢啊,不过没办法,项目庞大,代码打包后还有2MB,一个小小的💻性能不足以支撑,可以考虑换个更强大的电脑了。不过,相比此前一分钟的打包时间,已经足够让我提升开发效率了。最后放到生产环境下在浏览器下比对,发现在服务端开启gzip的情况下,修改后的项目全部js加载后总大小比原先小了15KB,相当于gzip前小了近40多KB,不仅提升了开发效率,还提升了生产环境的带宽利用率,优化还是比较有效果的😊。