前不久,研究了Webpack 4.X
的整体配置,本篇文章我们研究 webpack
各版本的区别 包括 v1,v2,v3,v4
Webpack:v1 与 v2 的区别
1. 新增对ES6
语法的支持**
2. 支持tree-shaking
( 减少打包后的体积 )**
3. 更新resolve
的写法,去掉extensions
空字符串**
webpack 1.X
:
...
resolve: {
extensions: ['', '.jsx', '.js', '.json'],
modulesDirectories: ['node_modules', 'src'],
alias: {
src: __dirname + `/src`,
components: __dirname + `/src/components`,
store: __dirname + `/src/store`
}
}
...
webpack 2.X
:
...
resolve: {
extensions: ['.js', '.css'],
modules: [
path.resolve(__dirname, 'node_modules'),
path.join(__dirname, './src')
],
alias: {
'@': resolver( 'src'),
'components': resolve( '@/components'),
'store': resolve( '@/store')
}
}
...
4. 修改module
配置
- 1. 外层
loaders
改为rules
- 2. 内层
loader
改为use
- 3. 所有插件必须加上
-loader
,不再允许缩写 - 4. 不再支持使用!连接插件,改为数组形式
- 5.
json-loader
模块移除,webpack
会自动处理
webpack 1.X
:
...
loaders: [
{
test: /\.js$/,
loaders: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(less|css)$/,
loader: "style-loader!css-loader!less!postcss-loader"
},
{
test: /\.json$/,
loader: 'json'
},
]
...
webpack 2.X
:
...
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
include: path.join(__dirname, 'src'),
exclude: /node_modules/
}
}
{
test: /\.(less|css)$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'less-loader'
]
}
]
...
5. 移除部分plugins
- 移除了
OccurenceOrderPlugin
插件,改为内置插件 - 移除了
NoErrorsPlugin
插件,改为内置插件
Webpack:v2 与 v3 的区别
1.Scope Hoisting
: 作用域
之前的每一个module
都被包含在一个独立的function
closures
中,因为闭包降低了浏览器的执行效率
开发团队参考了 Closure Compiler 和 RollupJS 等框架后,将 function
closures
的包裹方式变成了可配置的形式
...
plugins: [
new webpack.optimize.ModuleConcatenationPlugin()
]
...
我们可以看到,拼接成了一个函数:
2.Magic Comments
: 魔法注释
参考require.ensure()
设置自己的chunk name
import(/* webpackChunkName: vendor*/ 'module')
3. webpack-dev-server
: 内置插件
安装:
npm i webpack-dev-server -D
使用:
const webpack = require('webpack')
...
plugins: [
new webpack.HotModuleReplacementPlugin() // 热模块替换
],
devServer: {
host: 'localhost', // host地址
port: '8080', // 端口
open: true, //自动拉起浏览器
hot: true, //热加载
hotOnly: true, // 热加载不更新
publicPath: '', // 基础路径
// proxy: {}, // 跨域
// bypass: {} // 拦截器
},
...
Webpack:v3 与 v4 的区别
1. mode 配置选项
- 代替
DefinePlugin
,可设置为development
/production
/none
- 当
mode
为development
时,process.env.NODE_ENV
为development
,反之,process.env.NODE_ENV
为production
- 默认值:
production
- 也可通过
webpack --mode 'development | production'
来设置当前环境
- 当
当mode:development
时,会启用NamedChunksPlugin
和NamedModulesPlugin
// webpack.development.config.js
module.exports = {
mode: 'development'
plugins: [
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") })
]
}
当mode
为production
时,会启用
FlagDependencyUsagePlugin
, FlagIncludedChunksPlugin
, ModuleConcatenationPlugin
, NoEmitOnErrorsPlugin
, OccurrenceOrderPlugin
, SideEffectsFlagPlugin
和UglifyJsPlugin
等插件
// webpack.production.config.js
module.exports = {
mode: 'production',
plugins: [
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") })
]
}
2. Loader 使用规则
webpack 3.X
支持loaders
与rules
写法,但是webpack 4.X
废弃loaders
写法,只支持rules
vue-loader 15
必须使用VueLoaderPlugin
插件
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
plugins: [ new VueLoaderPlugin() ]
}
3. babel 命名规则
使用新的命名规则@babel
babel-loader
@babel/core
@babel/plugin-transform-runtime
@babel/preset-env
@babel/runtime
@babel/polyfill
- …
4. CommonsChunkPlugin:代码拆分插件
webpack 3.X
的代码拆分插件webpack.optimize.CommonsChunkPlugin
已经从webpack 4.X
中移除,可使用optimization.splitChunks
进行代码拆分(提取公共代码)- 同级的配置
optimization.runtimeChunk
,可拆分runtime
文件
module.exports = {
...
optimization: {
splitChunks: {
vendors: {
name: 'venders',
chunks: 'all',
minChunks: 2
},
runtimeChunk: {
name: 'manifest'
},
}
...
}
5. mini-css-extract-plugin: css代码抽离插件
删除extract-text-webpack-plugin
,新增mini-css-extract-plugin
,把css
从js
文件中抽离,防止js
太大,加载时间太长
production
环境下,必须配合plugins
使用
...
module: {
{
test: /\.(css)$/,
use: [
MiniCssExtractPlugin.loader, // development :'style-loader'
'css-loader',
'postcss-loader'
]
},
}
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
})
]
...
6. UglifyJsPlugin:js代码压缩插件
现在只需要使用optimization.minimize
为true
就行,production mode
下面自动为true
,optimization.minimizer
可以进行个性化配置
...
optimization: {
minimizer: {
// js代码压缩插件
new UglifyJsPlugin({
cache: true,
parallel: true, // 多线程,加速构建
sourceMap: true // sourceMap调试
}),
// css代码压缩插件
new OptimizeCSSAssetsPlugin()
}
}
...
7. happypack:多进程loader打包
happypack
可进行多进程loader
打包,当开启时,子进程执行,结果发给父进程
这里就不做过多介绍,官方文档:happypack