小记webpack4.x升级过程
一期项目:《手把手从零打造企业级电商平台-前端实战》
二期项目:《React16+React-Router4 从零打造企业级电商后台管理系统》
第一个电商用户端课程在制作过程中用的是webpack@1.15.0,距离现在时间不算长,但这一年多时间webpack已经升级到v4了。1.15.0版本的最大好处就是能兼容IE8,所以对IE兼容性有要求的同学看到这就可以洗洗睡了。如果要升的话,这次升级的版本跨度应该是够大的。
第二个项目是React实现的电商后台管理系统,这个课程出来的时间要近一点,用到的技术也都是比较新的,webpack版本是3.x,跨度不是很大,所以这次并不准备对它升级。3到4的跨度不是很大,有兴趣的同学看完这个介绍,升级一下应该问题不大。
webpack@4.x的变化先来说下webpack4和之前版本里一些主要的变化:
1、webpack不再支持node v4,这是因为新的webpack和附属插件使用了es6的语法,v4版本对es6不是很到位,所以,就不伺候了。
2、开始采取约定优于配置的思路,webpack@4.x里把很多选项都设置了默认值,比如入口就是./src,输出目录就是./dist,当然如果你自己去设置,它也不会拦着。所以在用webpack@4.x的时候,我们甚至都可以没有webpack.config.js这个配置文件也能一样打包。
3、拆分了旧版本里的webpack,分成了用来处理逻辑的webpack和提供可执行命令的webpack-cli,这也是有的同学把webpack装成新版本以后会报找不到webpack-cli模块这个错误的原因。
4、添加了mode选项,用来区分编译的环境,提供了development、production和none三个选项,理论上这个选项是强制指定的,其实不指定的话它也是有默认值的,但会给出一个warning,官方这么强烈建议了,就显式的指定一下吧。指定方式有两种,一是在启动命令里:
./node_modules/.bin/webpack --mode production
另外一种就是在配置文件里指定,方式如下:
var config = {
mode: 'production' // 可选development、production和none
}
5、配置上的变动,类似删除了commonChunksPlugin,用optimization来代替这种。还有loader的用法也和1.15.0不一样了,但这个升级是在之前版本里就有的,不是webpack@4.x带来的。
6、性能优化,提高了打包性能。另外从webpack2起,引入了Tree-shaking机制来提出没有被引用的模块。它的原理是按着引用关系重新建立一个新的依赖树,而没有被引用的模块就不会被打包到最后的代码里。之前的压缩优化方式是先把所有模块都挂到树上,然后通过分析后,删掉没被引用的模块。从字面意思来看,我觉得原来的方式更像在摇树,把没用的摇下来。这两种方式最后压缩完的结果可能类似,但设计思路完全是从两个方向走的。
7、其他。以上这些就是一些比较主要的变化,更详细的升级文档可以参考下官方的说明:https://github.com/webpack/webpack/releases
升级过程1、升级nodejs,因为webpack4不再支持node v4以下的版本了,这里推荐6.12.3,升级完成后记得把项目里的node_modules删掉再重新install一遍。
2、按着以下版本重新安装依赖
"devDependencies": {
"css-loader": "^0.28.11",
"file-loader": "^1.1.11",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.1.0",
"style-loader": "^0.20.3",
"url-loader": "^1.0.1",
"webpack": "^4.2.0",
"webpack-cli": "^2.0.13",
"webpack-dev-server": "^3.1.1"
},
"dependencies": {
"font-awesome": "^4.7.0",
"hogan.js": "^3.0.2"
}
安装插件的时候可以直接把package.json里的这些版本文件覆盖到原来项目里,然后删了node_modules目录,重新执行npm install。
当升级webpack时,其他插件的版本也要跟着升,这里面有两个插件要特别注意:
(1)webpack4里把原来版本里的webpack拆分成了两个东西,一个是webpack用来处理打包逻辑的,另外一个是webpack-cli是用来提供可执行命令的,webpack@4.x里这两个都要装。
(2)extract-text-webpack-plugin这个插件只有最新的beta版本能支持webpack@4.x,所以用命令安装的时候,需要指定版本,npm install extract-text-webpack-plugin@next --save-dev这样安装。
3、修改启动命令,把package.json里的scripts字段改成如下:
"scripts": {
"dev": "./node_modules/.bin/webpack-dev-server",
"dev_win": "./node_modules/.bin/webpack-dev-server",
"dist": "WEBPACK_ENV=online ./node_modules/.bin/webpack -p",
"dist_win": "set WEBPACK_ENV=online&& ./node_modules/.bin/webpack -p"
},
4、最后一步,修改webpack配置文件。下面把最新的配置文件粘出来,由webpack@1.15.0到webpack@4.x的变化都放在了配置文件的注释里:
/*
* @Author: Rosen
* @Date: 2017-05-08 15:28:19
* @Last Modified by: Rosen
* @Last Modified time: 2018-03-27 13:10:36
*/
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
// 环境变量配置,dev / online
var WEBPACK_ENV = process.env.WEBPACK_ENV || 'dev';
// 获取html-webpack-plugin参数的方法
var getHtmlConfig = function(name, title){
return {
template : './src/view/' + name + '.html',
filename : 'view/' + name + '.html',
favicon : './favicon.ico',
title : title,
inject : true,
hash : true,
chunks : ['common', name]
};
};
// webpack config
var config = {
/*
* 【新增】:新增mode参数,webpack4中要指定模式,可以放在配置文件这里,也可以放在启动命令里,如--mode production
*/
mode : 'dev' === WEBPACK_ENV ? 'development' : 'production',
/*
* 【改动】:删除了入口文件的中括号,可选的改动,没什么影响
*/
entry: {
'common' : './src/page/common/index.js',
'index' : './src/page/index/index.js',
'list' : './src/page/list/index.js',
'detail' : './src/page/detail/index.js',
'cart' : './src/page/cart/index.js',
'order-confirm' : './src/page/order-confirm/index.js',
'order-list' : './src/page/order-list/index.js',
'order-detail' : './src/page/order-detail/index.js',
'payment' : './src/page/payment/index.js',
'user-login' : './src/page/user-login/index.js',
'user-register' : './src/page/user-register/index.js',
'user-pass-reset' : './src/page/user-pass-reset/index.js',
'user-center' : './src/page/user-center/index.js',
'user-center-update': './src/page/user-center-update/index.js',
'user-pass-update' : './src/page/user-pass-update/index.js',
'result' : './src/page/result/index.js',
'about' : './src/page/about/index.js',
},
output: {
/*
* 【改动】:删除path的配置,在webpack4中文件默认生成的位置就是/dist,
* 而publicPath和filename特性的设置要保留
*/
// path : __dirname + '/dist/',
publicPath : 'dev' === WEBPACK_ENV ? '/dist/' : '//s.happymmall.com/mmall-fe/dist/',
filename : 'js/[name].js'
},
externals : {
'jquery' : 'window.jQuery'
},
module: {
/*
* 【改动】:loader的使用中,loaders字段变为rules,用来放各种文件的加载器,用rules确实更为贴切
*/
rules: [
/*
* 【改动】:css样式的加载方式变化
*/
// css文件的处理
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
/*
* 【改动】:模板文件的加载方式变化
*/
// 模板文件的处理
{
test: /\.string$/,
use: {
loader: 'html-loader',
options: {
minimize : true,
removeAttributeQuotes : false
}
}
},
/*
* 【改动】:图片文件的加载方式变化,并和字体文件分开处理
*/
// 图片的配置
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
/*
* 【改动】:图片小于2kb的按base64打包
*/
limit: 2048,
name: 'resource/[name].[ext]'
}
}
]
},
/*
* 【改动】:字体文件的加载方式变化
*/
// 字体图标的配置
{
test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
name: 'resource/[name].[ext]'
}
}
]
}
]
},
resolve : {
alias : {
node_modules : __dirname + '/node_modules',
util : __dirname + '/src/util',
page : __dirname + '/src/page',
service : __dirname + '/src/service',
image : __dirname + '/src/image'
}
},
/*
* 【新增】:webpack4里面移除了commonChunksPulgin插件,放在了config.optimization里面
*/
optimization:{
runtimeChunk: false,
splitChunks: {
cacheGroups: {
common: {
name: "common",
chunks: "all",
minChunks: 2
}
}
}
},
plugins: [
/*
* 【移除】:webpack4里面移除了commonChunksPulgin插件
*/
// // 独立通用模块到js/base.js
// new webpack.optimize.CommonsChunkPlugin({
// name : 'common',
// filename : 'js/base.js'
// }),
// 把css单独打包到文件里
new ExtractTextPlugin("css/[name].css"),
// html模板的处理
new HtmlWebpackPlugin(getHtmlConfig('index', '首页')),
new HtmlWebpackPlugin(getHtmlConfig('list', '商品列表')),
new HtmlWebpackPlugin(getHtmlConfig('detail', '商品详情')),
new HtmlWebpackPlugin(getHtmlConfig('cart', '购物车')),
new HtmlWebpackPlugin(getHtmlConfig('order-confirm', '订单确认')),
new HtmlWebpackPlugin(getHtmlConfig('order-list', '订单列表')),
new HtmlWebpackPlugin(getHtmlConfig('order-detail', '订单详情')),
new HtmlWebpackPlugin(getHtmlConfig('payment', '订单支付')),
new HtmlWebpackPlugin(getHtmlConfig('user-login', '用户登录')),
new HtmlWebpackPlugin(getHtmlConfig('user-register', '用户注册')),
new HtmlWebpackPlugin(getHtmlConfig('user-pass-reset', '找回密码')),
new HtmlWebpackPlugin(getHtmlConfig('user-center', '个人中心')),
new HtmlWebpackPlugin(getHtmlConfig('user-center-update', '修改个人信息')),
new HtmlWebpackPlugin(getHtmlConfig('user-pass-update', '修改密码')),
new HtmlWebpackPlugin(getHtmlConfig('result', '操作结果')),
new HtmlWebpackPlugin(getHtmlConfig('about', '关于MMall')),
],
/*
* 【新增】:在v1.0.1版本中新增了devServer的配置,用自带的代理就可以访问接口
*/
devServer: {
port: 8088,
inline: true,
proxy : {
'**/*.do' : {
target: 'http://test.happymmall.com',
changeOrigin : true
}
}
}
};
module.exports = config;
共同学习,写下你的评论
评论加载中...
作者其他优质文章