常用的loader和plugin
loader
html-loader:处理html文件,将html文件内的外链当做依赖引入入口文件
style-loader:创建type标签,将入口文件中的整合css插入标签,将标签插入html文件。
css-loader:处理css文件,将css文件内容整合进入口文件中。
postcss-loader:处理css文件,让原本的css文件兼容各浏览器;需要下载postcss-preset-env
插件并配置在loader的配置项内;依据package.json
中的browserlist
配置项决定兼容哪些浏览器。
less-loader:处理less文件,将less文件转译为css文件。
sass-loader:处理sass文件,将less文件转译为css文件。
url-loader:处理图片资源,它是基于file-loader
而来的,使用时要同时下载。
babel-loader:处理js文件,将es6之后的语法转义为es5语法,解决浏览器兼容性;loader配置项需要预设环境—最基础的是@babel/preset-env
;需要下载@bable/core
核心库;如果仍不能满足需求,下载@babel/polify
并在入口文件内引入——会导致文件体积过大,优化方案为使用core-js
。
eslint-loader:处理js文件,用于语法检查,需要安装eslint
依赖包;语法风格由.eslinttrc
文件决定;推荐使用airbnb风格,需要安装eslint-config-airbnb-base、eslint-plugin-import
依赖包;github上有airbnb开源库。
plugin
html-webpack-plugin:用于复制一个html文件到bundle中,并将入口文件自动引入该html文件;需要一个template模板;可用于html文件压缩。
min-css-extract-plugin:用于将入口文件中整合的css单独提取出来到一个新的css文件中;有一个loader
属性,记住用它替代style-loader
;用于生产环境优化。
optimize-css-assets-webpack-plugin:用于压缩css文件;用于生产环境优化。
webpack性能优化
开发环境
HMR热更新——各种框架都自己实现了,一般不需要配置
1、css文件:默认可以使用HMR功能,因为style-loader
内部实现了。
2、js文件:默认不能使用HMR功能;在入口文件内使用module.hot.accept
监听js文件变化即可。
3、html文件:不需要做HMR优化。
source-map——各种框架都自己实现了,一般不需要配置
此功能用于建立源代码到构建后代码的映射,方便错误调试。
devtool: [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
oneOf——让文件只匹配一个loader,提升构建速度
注意,使用oneOf
时——它的值为一个数组,不能出现多个loader处理一个文件的情况
生产环境
缓存
1、babel缓存:缓存经过编译的js文件,如果模块代码没有改变,会从缓存里读取文件,节省不必要的编译,热更新的一种;设置方式为://在babel-loader的配置向内添加一项cacheDirectory,值为true
2、文件资源缓存:注意打包后的文件名加上一个hash | chunkhash | contentHash
tree-sharking——清除在应用程序中没有使用到的代码
两个前提:1、必须使用es6Module;2、必须在生产环境下。
可能会导致某些必要的依赖——例如css文件被sharking掉,解决方法为在package.json
文件中加一项配置"sideEffect": [...必要的依赖文件后缀数组]
code-split
1、分割第三方库(node_modules里的三方依赖),防止重复加载第三方库
optimization: {
splitChunks: {
chunks: 'all'
}
}
2、import动态语法导入:能将某个文件单独打包
import(/* webpackChunkName: '自定义打包后文件名称' */'文件路径')
.then(res => {
// 加载成功操作
})
.catch(err => {
// 加载失败操作
})
懒加载
懒加载是在code-split的基础上来的,确切的来说,就是在需要的时候才加载需要的文件。举个例子:
// 假设有一个按钮,点击按钮是需要用到某个文件,懒加载的实现如下:
let btn = document.querySelector('#btn')
btn.onclick = function (event) {
import(/* webpackChunkName: '自定义打包后文件名称' */'文件路径')
.then(res => {
// 加载成功操作
})
.catch(err => {
// 加载失败操作
})
}
预加载——兼容性差,慎用
预加载是在code-split的基础上来的,确切的来说,就是在浏览器加载完必要的资源之后,空闲下来了,让浏览器额外加载未来可能用到的资源。
import(/* webpackChunkName: '自定义打包后文件名称', webpackPrefetch: 'true' */'文件路径')
.then(res => {
// 加载成功操作
})
.catch(err => {
// 加载失败操作
})