环境变量
webpack --env.NODE_ENV=local --env.production --progress
Tree Shaking
移除JS上下文字未被引用的代码
只支持ES6的import和export
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
optimization: { usedExports: true }
package.json
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"sideEffects": ["*.css", "*.scss"],
development and production
webpack-merge
构建开发环境和生成环境
开发环境需要实时重新加载,热模块替换能力的source map和localhost server
生成环境需要更小的bundle, 更轻量级的source map
Code Splitting
首先介绍第一种代码分割
lodash
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
entry: { main: resolve(__dirname, '../src/index.js'), lodash: resolve(__dirname, '../src/lodash.js') }
创建lodah.js
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import _ from 'lodash' window._ = _
webpack的代码分割
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
optimization:{ splitChunks:{ chunks: 'all' } }
同步代码:只需要在webpack.common.js中配置optimization
异步代码:通过import,无需任何配置即可,会自动进行代码分割
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
async function getLodash() { const { default: _ } = await import(/* webpackChunkName: 'lodash' */ 'lodash') const ele = document.createElement('div') ele.innerHTML = _.join(['Hi', 'Susan'], '*') return ele } getLodash().then( res => { document.body.appendChild(res) })
webpack --profile --json > stats.json
filename and chunkFileName
filename
对应entry里面生成的文件名字
chunFileName
chunkFileName未被列在entry中,如异步加载(import)
MiniCssExtractPlugin
mini-css-extract-plugin
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: '[name].css', chunkFilename: '[id].css', }), ], module: { rules: [ { test: /.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { // you can specify a publicPath here // by default it uses publicPath in webpackOptions.output publicPath: '../', hmr: process.env.NODE_ENV === 'development', }, }, 'css-loader', ], }, ], }, };
development中热更新
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const devMode = process.env.NODE_ENV !== 'production'; module.exports = { plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: devMode ? '[name].css' : '[name].[hash].css', chunkFilename: devMode ? '[id].css' : '[id].[hash].css', }), ], module: { rules: [ { test: /.(sa|sc|c)ss$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { hmr: process.env.NODE_ENV === 'development', }, }, 'css-loader', 'postcss-loader', 'sass-loader', ], }, ], }, };
production中css压缩
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const TerserJSPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { optimization: { minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})], }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', chunkFilename: '[id].css', }), ], module: { rules: [ { test: /.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, ], }, };
缓存
格式
[<hashType>:contenthash:<digestType>:<length>]
Shimming
一直垫片形式,项目中使用lodash,我们可以不需要引入lodash,webpack自动完成
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
new webpack.ProvidePlugin({ _: 'lodash' })
index.js代码,没引入lodash
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const dom = document.createElement('div') dom.innerHTML = _.join(['Hi', 'Susan'], ' ') document.body.appendChild(dom)
imports-loader
模块中的this指向是一个{},可以是用imports-loader指定this->window
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
use: 'imports-loader?this=>window'
TypeScript
ts-loader / typescript
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{ test: /.tsx?$/, exclude: /node_modules/, use: [ { loader: 'ts-loader' } ] }
tsconfig.json
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{ "compilerOptions": { "outDir": "./dist", "module": "es6", "target": "es5", "allowJs": true } }
index.tsx
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import * as _ from 'lodash' class Greeter { greeting: string constructor(message: string) { this.greeting = message } greet() { console.log(_.join([this.greeting, 'Go'], '_')) } } const greeter = new Greeter('Hi Susan') greeter.greet()
historyApiFallback
proxy
secure
resolve
alias
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
module.exports = { //... resolve: { alias: { Utilities: path.resolve(__dirname, 'src/utilities/'), Templates: path.resolve(__dirname, 'src/templates/') } } };
extensions
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
module.exports = { //... resolve: { extensions: ['.wasm', '.mjs', '.js', '.json'] } };