前言
正常的构建环节
stateDiagram-v2
[*] --> 构建
构建 --> develop
构建 --> build
develop --> 分析
build --> 分析
分析 --> 优化
优化 --> publish
publish --> deploy
deploy --> [*]
一直想尝试写一篇完成项目部署,从搭建到部署,到构建,到性能分析, 再到优化处理。 此次避开框架脚手架等工具,依托webpack工具直接完成项目编译方面的处理
搭建
工具
- node(此次使用v12.18.3)及基础依赖工具
- webpack(此次使用v4.40.2)、webpack-merge(用于提取环境编辑配置)
- webpack-bundle-analyzer
- copy-webpack-plugin
- html-webpack-tags-plugin
假定
假定现在你已经完成前置的项目初始化构建,包括npm注入,git仓库的指定,以及项目『vue、react』的本地启动和初始化编译,最起码的你完成了这些框架脚手架初始化搭建。
那么现在你的项目中会依赖上很多三方库或者工具,比如Vue、React、jQuery、loadash、echart等,你会发现你再build过程中会花费不止两分钟,然后编译处一个2、3M左右的巨物,悲催的开始,这边你就会想着如何去处理这个过程。。。
编译分析
场景一、冷[0]处理
- 终端编译效果
- analysis分析脚本依赖
分析: 可见几个项目打的模块(库)直接影响到项目构建Size, element-ui、jQuery
场景二、webpack externals提取
由于三方库的引入使得我们构建体积巨大,我们第一反应就是替换,不编译,提取。
- webpack externals提取公用库
externals: {
vue: 'Vue',
jquery: 'jQuery',
'element-ui': 'ELEMENT',
xxxxxx
},
- 终端编译效果
- analysis分析脚本依赖
体积明显减少
细节中存在问题,如果不被编辑那就意味着,需要手动注入三方脚本,那么 去webpack-plugin-html对应的html模板中手动注入cdn或者服务器脚本资源。
<body>
<h1>
这里都是你想要的
</h1>
<div class="showI" id="wrap-vue">
</div>
<script type="text/javascript" src="main.bundle.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js">
</script>
xxxxxxxxx
</body>
</html>
场景三、webpack externals提取 + 动态注入三方脚本
我们的理想是讲脚本动态注入到html模板中,而不是手动,这时候我们就想着,如果:讲node_modules包中的三方脚本拉去出来,放在本地服务器,然后构建一个plugin去完成script的动态注入就行了
- 使用copy-webpack-plugin去将node_modules中需要的模块化脚本clone到本地,与编辑目录同级,方便读取
- 自定义的插件中需要完成script的url拼接,参照规则[/vender/vue-2.6.12/vue.js]。
- 规则url去动态注入html中,结合html-webpack-tags-plugin代替,去插入使用
<body>
<h1>
这里都是你想要的
</h1>
<div class="showI" id="wrap-vue">
</div>
<script type="text/javascript" src="/vender/vue-2.6.12/vue.js"></script>
<script type="text/javascript" src="/vender/jquery-3.6.0/jquery.js"></script>
<script type="text/javascript" src="/vender/element-ui-2.15.1/index.js"></script>
<script type="text/javascript" src="main.bundle.js"></script>
xxxxxxxxx
</body>
</html>
注:期间遇到问题
-
更早的公共内容的提取使用html-webpack-external-plugin,但是于三年前停止维护,现在使用html-webpack-tags-plugin代替;
-
由于webpack版本及相关依赖插件比如html-webpack-plugin的版本依赖关系,可能会影响到打包错误显示,或者说程序运行的引用使用方式等问题;
-
技巧:如何确认依赖间版本关联
- 使用脚手架、无论是webpack-cli、或是@vue/cli在或者react-cli,也都一样他们相对成熟些,已经确认的比较体系化的版本依赖,可以相对放心。
- 确定一个固定依赖项,比如一切依赖基于webpack,其他依赖项都基于这个相关版本升级确认,可进入node_modules查询等方式确认
-
这个使用的是copy-webpack-plugin + html-webpack-tags-plugin,其实可以使用add-asset-html-webpack-plugin。
html-webpack-tags-plugin不会复制文件,而add-asset-html-webpack-plugin会将文件先复制到dist目录下(当然,可以配置到dist的那个目录),再添加一个标签。
也就是说add-asset-html-webpack-plugin相当于 html-webpack-tags-plugin再加上一个copy-webpack-plugin!
总结
此篇相对简单些,主要介绍,对于前端工程编译的优化方面的处理,结合webpack及插件使用,来完成大型三方库的提取。 借助webpack-bundle-analysis分析,其实不单externals可以对公共模块的提取,业界还有比如说,通过plugin:new webpack.optimize.CommonChunkPlugin,对模块分割,拆分业务模块及vendors。 后期有机会会介绍使用new webpack.optimize.CommonsChunkPlugin()
可考虑优化的方向:
- webpack版本升级
- 去掉不必要的插件
- 代码压缩、代码分割
- 公共库提取
- 设置缓存
- 结合使用版本新特性比如three-loader