前言
最近在学习webpack,记录一下学习的基础东西,以及项目构建的速度和体积的优化。
webpack基本配置
基本配置之前写过一遍文章,不重新写啦,不了解请转webpack之小白篇。
修改代码,自动编译
- webpack –watch 不会刷新浏览器,开发环境打包后的js是存在磁盘中。
package.json文件
webpack.dev.js文件
注:webpack.dev.js // 开发环境配置 webpack.prod.js // 生成环境配置
- webpack-dev-server –open 会自动打开浏览器,需要与webpack.HotModuleReplacementPlugin()配合使用,代码变动,可以自动刷新浏览器。
package.json文件
webpack.dev.js文件
热更新(HMR:Hot Module Replacement)原理
- Webpack Complier将代码转化为bundle.js文件。
- 将bound.js文件传输Bounle Server,提供浏览器Browser访问。
- 当代码更新时,会出发HMR Server 将代码传入到HMR Runtime(通常以json形式)
- HMR Runtime接受会更新代码,刷新浏览器。
文件指纹
打包输出的文件名的后缀,通常作为版本的管理,没有修改的文件,可以使用浏览器缓存,加速访问。
- hash:和整个项目有关,只要文件修改,整个项目构建的hash都会改变,通常图片和字体使用。
- chunkhash:不同的entry有不同的chunkhash值,通常js文件使用。
- contenthash:根据文件内容生成hash值,通常css使用。
style-loader:是将css插入style标签,插入到头部,没有单独的css文件。
MiniCssExtractPlugin(filename:'[name][conetnthash:8].css’).loader 将css提出单独的文件,link到头部。
webpack.prod.js
代码压缩
- js,webpack4使用了terser-webpack-plugin插件默认以及打包过了,uglifyjs-webpack-plugin打包es6会报错。
- html,使用html-webpack-plugin(一个html模板对应一个html-webpack-plugin)
- css,使用optimize-css-assets-webpack-plugin插件,与cssnano配合使用
css3:自动添加浏览器前缀(aotuperfixer)
移动端css中的px转化为rem
- rem:相对单位,(相对于根元素html的font-size)
- px:绝对单元
- px2rem:将px转为rem
- lib-flexible:动态的计算根元素的font-size
在入口文件引入import 'lib-flexible'
多页面应用(entry+html-webpack-plugin)
动态的设置entry,html-plugin-webpack,使用glob库,glob.sync()可以同步的获取正则匹配的目录信息。
source map 定位源代码
开发环境中开启,生产环境上关闭。
webpack.prod.js
优化构建时命令行日志显示
webpack中stats:统计信息
使用friendly-errors-webpack-plugin插件,将stats设置为’error-only’
webpack进阶用法
提取公共资源
- 将react,react-dom 等公用的库,通过cdn的方式引入,不打包进入到bounld.js,使用html-webpack-externals-plugin引入
new HtmlWebpackExternalsPlugin({
externals: [
{
module: 'react',
entry: 'https://unpkg.com/react@17/umd/react.production.min.js',
global: 'react',
},
],
})
复制代码
- 通过webpack4自带的splitchunk属性进行公共脚本分离,splitchunk也可以提取公共使用的自己封装的函数,但是需要多个打包入库同时使用,一个项目使用多次是不可以的。
optimization:{
splitChunk:{
minSize:0,
cacheGroups:{
vendor:{ // 提取node_modules的公共资源
test:/[\\/]node_modules[\\/](react|react-dom)[\\/]/,
name:'vendor',
chunks:'all'
},
commons:{ // 提取node_modules以及自己写的公告函数。(需要多个打包入口引用了依赖和公共函数)
chunks:'all',
name:'commons',
minChunks:'2'
}
}
}
}
复制代码
tree shaking (摇树优化)
只支持es6语法。webpack4的production默认打开。
原因:对代码进行静态分析,而不是在代码运行的时候在分析哪些是没有用到的,在tree shaking阶段把无用的代码注释,在代码压缩的阶段删除无用代码。
利用es6模块的特点:
- import只能最为模块的顶层出现
- import的模块名称只能是字符串常量(导入之后不能修改)
- import binding 是immutable的(不能动态引入的)
注:不能在代码中动态的require导入
DCE(dead code elimination)
- 代码不可达
- 代码执行结果不会被用到
- 代码只会影响死变量(只写不读)
Scope Hositing(/ˈhɔɪstɪŋ/)
webpack4的production默认打开,必须使用es6语法,不支持cjs。
不开启Scope Hoisting会导致什么问题:
- 大量的闭包函数代码,会导致构建之后代码体积变大
- 运行代码时创建的函数作用域变多,内存开销变大
scope hoisting的原理:
对所有模块的代码按照引用顺序放在一个函数作用域里,适当的重命名一些变量放置变量名冲突。
对比:通过scope hositing处理代码之后,会减少函数声明代码和内存开销。
注:如果模块只是用一次,会直接内联在函数作用域里,吐过使用多次,将会重新创建一个新的函数作用域。
代码分割
将所有的代码打包到一个文件中是不够有效的,特别是有些代码在某种特殊情况下才会用到,webpack可以将打包过的代码分割成多个chunks,当代码运行我们在进行加载。
webpack打包组件库
简单的组件库rollup更适合
发布npm包
- 需要打包压缩版和非压缩版
- 需要支持AMD/CJS/ESM模块导入,把output的library设置为’umd’。
webpack.config.js 配置
npm发布步骤
npm login
// 登录npm publish
// 发布包npm version path
// 改bug打补丁npm version minjor
// 做一个feature,升级一个小的版本号npm version major
// 升级一个大版本
语义化版本(Semantic Versioning)格式规范
- 主版本号:当做了不兼容的API的修改
- 此版本号:当做了向下兼容的功能性新增
- 修订号:当做了向下兼容的问题修正
先行版本号
- alpha:是内部测试版,一般不向外发布,会有很多bug,一般只是测试人用。
- beta:也是测试版,这个阶段的版本相对于alpha版的改进,消除了严重的错误,但是还存在着缺陷,这个版本也会一直加入新的功能,在alpha版之后推出。
- rc:系统平台上发行的候选版本,rc版不会再加入新的功能了,主要着重于排错。
webpack构建速度
speep-measure-webpack-plugin速度分析
作用:可以查看每个loader和插件的执行耗时时间,整个打包耗时。
项目速度提升
1.使用高版本的webpack和node
2.多进程多实例构建
thread-loader(webpack4推荐使用),每次webpack解析一个模块,thread-loader将会将它及它的依赖分配给worker线程中。
3. 多进程实例压缩
terser-webpack-plugin 设置paralled参数
4. 分包:预编译资源模块
使用dllPlugin,dllReferencePlugin插件,使用script引入打包好的dll文件。
创建webpack.dll.js文件
在package.json文件中
执行npm run dll
,就会生成公共包的文件。
在webpack.dev.js,webpack.prod.js配置即可(当打出多个文件时,每个文件都需要添加一个插件,文中只打包了一个文件)
5.利用缓存提升二次构建
- babel-laoader开启缓存
- terser-webpack-plugin 开启缓存
- 使用hard-source-webpack-plugin
6. 减少文件搜索范围
resolve.modules,resve.mainFields,resolve.extensions,resolve.alias配置。
webpack构建体积
webpack-bundle-analyzer分析体积
作用:第三方依赖包大小,我们自己组件代码大小
项目体积优化
1.图片压缩
使用image-webpack-loader
2.删除无用的css
- PurifyCSS:遍历代码,识别已经用到的css,使用purgecss-webpack-plugin(css不可以使用)
- uncss:需要html使用jsdom加载,样式使用postcss解析,通过document.querySelect来识别html文件里面不存在的选择器。
3.提取公共的资源模块
详见webpack速度提升的分包:预编译资源模块
总结
webpack的实践及优化,整理知识点,后期学习继续添加。