目录
Tree shaking
作用:消除无用代码
在 webpack 项目中,有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝。实际情况中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 Tree-Shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。
配置方法:
mode:production 打包模式时默认使用,mode:development时默认不配置
测试生产环境打包模式区分
这个很常见,主要通过打包命令来指定不同的运行环境或配置文件,举一个常见的
1 2 3 4
| package.json "dev": "webpack-dev-server --config ./build/webpack.common.js", "build": "webpack --env.production --config ./build/webpack.common.js"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const webpack = require('webpack'); const merge = require('webpack-merge'); const devConfig = require('./webpack.dev.js'); const prodConfig = require('./webpack.prod.js'); const commonConfig = { entry: { main: './src/index.js', }, .... output: { path: path.resolve(__dirname, '../dist') } }
module.exports = (env) => { if(env && env.production) { return merge(commonConfig, prodConfig); }else { return merge(commonConfig, devConfig); } }
|
code spliting
代码分割,相比于入口文件配置的代码分割,splitChunks更具策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const commonConfig = { ... optimization: { runtimeChunk: { name: 'runtime' }, usedExports: true, splitChunks: { chunks: 'all', cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10, name: 'vendors', }, default: { minChunks:2, priority: -20, } } } }, ... }
|
**- chunks **
initial、async、all分别表示静态引入、动态引入和两种情况下来进行代码分割。
- priority
priority属性的值为数字,可以为负数。作用是当缓存组中设置有多个拆分规则,而某个模块同时符合好几个规则的时候,则需要通过优先级属性priority来决定使用哪个拆分规则。优先级高者执行。我这里给业务代码组设置的优先级为-20,给第三方库组设置的优先级为-10,这样当一个第三方库被引用超过2次的时候,就不会打包到业务模块里了。
- minChunks
就是在entry中配置的入口,引用了该模块的最少个数,只有满足了最少有minChunks个chunk引用了当前模块,才会进行单独打包
懒加载、预加载
事实上懒加载不是webpack的功能,它是es6的模块功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import("./test") .then(({test}) => { console.log('test加载成功') test() }) .catch(error => { console.log('test加载失败 error:', error) })
import("./test") .then(({test}) => { console.log('test加载成功') test() })
|
Caching缓存
为什么需要hash?
浏览器会缓存我们的文件。
优点是浏览器读取缓存的文件,能带来更佳的用户体验(不需要额外流量,速度更快);
缺点是有时候我们修改了文件内容,但是浏览器依然读取缓存的文件(也就是旧文件),导致用户看到的文件不是最新的。
解决方法:文件尾加哈希,防止文件更新后缓存不刷新。文件内容不变化,哈希不会变。
1 2 3 4
| output: { filename: '[name].[contenthash].js', chunkFilename: '[name].[contenthash].js' }
|
环境变量
在打包命令里可以配置
1 2 3
| package.json "build": "webpack --env.production --config ./build/webpack.common.js"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const webpack = require('webpack'); const merge = require('webpack-merge'); const devConfig = require('./webpack.dev.js'); const prodConfig = require('./webpack.prod.js'); const commonConfig = { ... } //环境变量 module.exports = (env) => { if (env && env.production) { return merge(commonConfig, prodConfig); } else { return merge(commonConfig, devConfig); } }
|
也可以直接通过打包模式区分
1 2 3 4 5
| if (process.env.NODE_ENV === 'production') { console.log('你正在线上环境'); } else { console.log('你正在使用开发环境'); }
|