基本的文件目录
1 2 3 4 5 6 7 8 9 10 11
| webpack-test ├── node_modules ├── public │ └── template.html ├── src │ ├── app.vue │ ├── index.js │ └── style.css ├── package-lock.json ├── package.json └── postcss.config.js
|
基础配置如下
webpack.config.js1 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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| module.exports = env => { const isDev = env === 'development' return { mode: env, entry: path.resolve(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.vue$/, use: 'vue-loader' }, { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: [ "@babel/preset-env" ] } } }, { test: /\.(jpe?g|png|gif)$/, use: 'file-loader' }, { test: /\.css$/, use: [ !isDev ? MiniCSSExtractPlugin.loader : 'style-loader', 'css-loader' ] } ] }, plugins: [ new VueLoaderPlugin(), !isDev && new MiniCSSExtractPlugin(), new HTMLWebpackPlugin({ template: path.resolve(__dirname, 'public/template.html'), filename: 'index.html' }) ].filter(Boolean) } }
|
webpack 自带优化
webpack 自带优化无需配置,在生产环境自动生效
作用域提升(Scope Hoisting)
假设有两个文件
module.js1 2
| export const a = 1 export const b = 2
|
index.js1 2 3 4 5
| import { a, b } from "./module.js"
const c = 3 const d = a + b + c console.log(d, 'scope-hoisting')
|
可以看到在开发环境打包结果基本没有优化
而在生产环境下变量 a, b, c, d 则被省略,直接计算出了结果
需要注意的是,仅在 ES6 的模块化语法中生效
Tree Shaking
通过 Tree Shaking 可以剔除 JavaScript 中用不上的代码,同样仅在 ES6 的模块化语法中生效
module.js1 2 3 4 5 6 7
| export const fn1 = (a, b) => { return a + b }
export const fn2 = (a, b) => { return a - b }
|
index.js1 2 3
| import { fn1, fn2 } from "./module.js"
console.log(fn1(1, 2), 'tree-shaking')
|
在生产环境下打包后只保留了fn1
删除多余的 CSS 样式
假设有如下 CSS 代码
1 2 3 4 5 6
| div { background: gray; } .useless-class { background: yellow; }
|
这里的.useless-class
显然是多余的(没有该类),我们可以搜索src
目录下的文件,并且使用 purgecss-webpack-plugin 插件删除无用的样式
1
| $ npm install purgecss-webpack-plugin --save-dev
|
需要注意的是,该插件要配合 mini-css-extract 使用,配置如下
webpack.config.js1 2 3 4 5 6 7 8 9
| const glob = require('glob') const PurgeCSSWebpackPlugin = require('purgecss-webpack-plugin')
plugins: [ !isDev && new MiniCSSExtractPlugin(), !isDev && new PurgeCSSWebpackPlugin({ paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, { nodir: true }) }) ]
|
运行npm run build
之后打包结果为
1 2 3
| div { background: gray; }
|
图片压缩
1
| $ npm install image-webpack-loader --save-dev
|
CDN 加载文件
拆分 bundles
动态加载
打包文件分析工具
SplitChunks
热更新
IgnorePlugin
费时分析
noParse
resolve
include/exclude
在使用 loader 时,可以指定哪些文件不通过 loader ,或者指定哪些文件通过 loader
webpack.config.js1 2 3 4 5 6
| { test: /\.js$/, use: "babel-loader", include:path.resolve(__dirname,'src'), exclude:/node_modules/ }
|
happypack