1. 样式优化
1.1 MiniCssExtractPlugin 样式抽离
使用 MiniCssExtractPlugin 抽离出 css 文件,以 link 标签的形式引入样式文件
module: { rules: [ { test: /.css$/, use: [ MiniCssExtractPlugin.loader], }, ] }
// 创建一个 link 标签 'css-loader',
// css-loader 负责解析 CSS 代码, 处理 CSS 中的依赖
plugins: [ // 用 MiniCssExtractPlugin 抽离出 css 文件,以 link 标签的形式引入样式文件
new MiniCssExtractPlugin({ filename: 'index.bundle.css' // 输出的 css 文件名为 index.css
}), ]
1.2 cssnano 样式压缩
使用 optimize-css-assets-webpack-plugin
const OptmineCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
new OptmineCSSAssetsPlugin({
cssProcessor:reuire('cssnano')
})
1.3 css摇树
npm i glob-all purify-css purifycss-webpack -D
const purifycss = reuire('purifycss-webpack')
const glob = reuire('glob-all')
plugins: [
new purifycss({
paths: glob.sync([ //glob用于匹配路径
path.resolve(__dirname, './src/*.html'), //html 上 也有css 需要摇树
path.resolve(__dirname, './src/*.js'),
])
})
]
注意 由于css 是使用 import './index.css' ,会有摇掉,所以需要在package.json 配置白名单
{
"sideEffects": ["*.css","*.sass"]
}
2. 不同环境不同config 配置
通过 webpack-merge 合并webpack.common.config.js 到当前环境
- webpack.common.config.js
- webpack.dev.config.js
- webpack.prod.config.js
//package.json
{
"scripts": {
"dev": "webpack --config ./webpack.dev.config.js",
"prod": "webpack --config ./webpack.prod.config.js",
}
}
//webpack.dev.config.js
const merge = require("webpack-merge")
const commonConfig = require("./webpack.common.config.js")
const devConfig = {
...
}
module.exports = merage(commonConfig,devConfig);
//webpack.prod.config.js
const merge = require("webpack-merge")
const commonConfig = require("./webpack.common.config.js")
const prodConfig = {
...
}
module.exports = merage(commonConfig,prodConfig);
3.代码分割
//多⼊⼝ entry是个对象 下面的output 通过[name]直接输出这里的命名index和login
entry: { index: "./src/index.js", login: "./src/login.js" }
output: { filename: "[name][chunkhash:8].js",//利⽤占位符,⽂件名称不要重复 path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径 },
4.dependOn 依赖引入
entry: {
index: {
import : './src/index.js',
depenOn: 'axios'
},
list: {
import : './src/list.js',
depenOn: 'axios'
}
axios: 'axios' //这里使用的项目的npm安装库
}
5.懒加载
原理:动态生成 <script>
标签 动态引入js 内容
//webpack.config.js
entry : "index.js"
output: { filename: "main.js",
path: path.resolve(__dirname, "dist")
},
//src/lib/a.js
export const fna = function() {
console.log('aa')
}
//index.js
document.onclick = async function() {
//fna();
let {fna} = await import('./lib/a.js')
fna();
}
构建后为:
//dist/main.js
//dist/349.js
//重命名 懒加载文件
//index.js
document.onclick = async function() {
//fna();
let {fna} = await import(
/*webpackChunkName: 'a' */ //把生成文件改为 a.js
'./lib/a.js'
)
fna();
}
构建后为:
//dist/main.js
//dist/a.js
6.预加载 preload
原理:动态生成 <link rel="prefetch" as="script">标签 动态先加载js资源,但不执行任何代码
//index.js
document.onclick = async function() {
//fna();
let {fna} = await import(
/*webpackChunkName: 'a',webpackPrefetch: true */ //设置webpackPrefetch为true打开预加载
'./lib/a.js'
)
fna();
}
7.CDN引入
7.1使用html-webpack-externals-plugin
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
module.exports = {
// 其它省略...
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [{
module: 'vue',
entry: 'https://xxxx/vue.min.js',
global: 'Vue'
}]
})
],
// 其它省略...
}
//index.html引入
<script type="text/javascript" src="https://xxxx/vue.min.js"></script>
7.2直接配置externals
module.exports = {
// 其它省略...
externals: {
vue: 'Vue'
},
// 其它省略...
}
//index.html引入
<script type="text/javascript" src="https://xxxx/vue.min.js"></script>
## 7.3 output 指定publicPath
//webpack.config.js
output:{
publicPath: '//xxxx.com' //cdn地址
}
8.treeShaking
7.1webpack自带默认设置
webpack 满足条件:
1. ESM //webapck4 只支持es 模块 (webpack5都支持)
2. webpack production //同时是生产模式
3. optmization 设置 usedExports:true
module.exports = {
mode: 'production',
optmization: {
usedExports:true
}
}
//测试代码
//src/lib/fn.js
export function a() {
console.log('aaa')
}
export function b() {//这时候 方法b由于没有被使用过,会被摇掉
console.log('bbb')
}
//src/index.js
import {a} from './lib/fn'
a();
7.2 terserPlugin
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
cache:true, //打开缓存
parallel:true, //多线程
terserOptions: {
comments : false,
compress: {
unused:true, //声明 未使用代码
drop_debugger:true,//移除debugger
drop_console:true,//移除console
dead_code:true //无用代码
}
}
})
]
}
}
9.compression-webpack-plugin 开启gzip
1.webpack配置使用
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = /\.(js|css)(\?.*)?$/i;
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: productionGzipExtensions,
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: true
})
2.服务端打开 gzip
nginx配置
http {
gzip_static on;
}
10.优化构建速度 loader & plugin
1. 优化查找范围
test include exclude (推荐使用include)
exclude 优先与 include 和test ,所以三者冲突时候,优先exclude
2. 依赖库查找
resolve.modules默认会按当前目录下 查找 node_modules,没有继续往上找,一直到找到为止。 如果已经确定是在根目录, 可以直接指定
module.exports = {
resolve = [path.resolve(__dirname,"./node_modules")]
}
3. 优化别名
resolve.alias通过别名 将原导入的路径映射成新的导入路径 如:react 导入会有 两套代码,cjs 和 umd 默认情况 webpack 会从 ./node_modules/bin/react/index 开始递归,效率低, 我们可以直接指定地址
alias:{
react:path.resolve(__dirname,'./node_modules/react/umd/react.production.min.js'),
react-dom:path.resolve(__dirname,'./node_modules/react/umd/react-dom.production.min.js')
}
4. 减少无后缀检查
extensions:['.js','.json','.jsx','ts']
- 上面描述的后缀尽量少一点
- 代码尽量带上后缀
5. 启动多线程
thread-loader
module.exports = {
module: {
rules : [
{
test : /\.jx$/
include:path.resolve('src')
use: [
'thread-loader'
//这是 把高开销的laoder放这里 ,执行会优先与其他loader
]
}
]
}
}
6. 打开缓存,空间换时间
6.1 babel-loader优化
提升babel-loader的打包时间,打开cacheDirectory:true,系统将会生产一个公用的缓存信息,方便babel多次引用。
一般路径在 node_modules/.cache/babel-loader
rules : [
{
test : /\.js$/,
loader: 'babel-loader',
options : {
cacheDirectory : true
}
}
]
6.2 terser-webpack-plugin
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
cache:true, //打开缓存
parallel true //多线程
})
]
}
}