webpack4升级指南
鉴于图书项目编译速度极慢的情况(项目里面module太多了,编译慢很正常)且最近需求不多(很少出现的空挡期)。所以我觉得搞一波webpack升级,看看有没有帮助。webpack于2018年2月25正式发布v4.0.0版本,代号legato。名字是不是很大器,不明觉厉的样子。废话少说下面正式进入主题。(本文的升级配置主要针对vue项目)
一、webpack4更新变化
先说一下webpack4有几个比较重要的更新:webpack4更新日志
1.环境支持: 官方不再支持Node 4,Node 6,最好使用v8.5.0以上稳定版本。支持93%的ES6语法。因为webpack4使用了很多JS新的语法,它们在新版本的 v8 里经过了优化。
2.0配置: 受Parcel打包工具启发,尽可能的让开发者运行项目的成本变低。webpack4不再强制需要 webpack.config.js 作为打包的入口配置文件了,它默认的入口为'./src/'和默认出口'./dist',这对于小项目来说确实是一件不错的事情。
3.mode选项: 告知 webpack 使用相应模式的内置优化。可选 development 或 production,举个栗子。
module.exports = {mode: 'production'
};
复制代码
或者从 CLI 参数中传递: webpack --mode = production
选项 | 描述 |
---|---|
development | 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。 |
production | 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin. |
==注意:只设置 NODE_ENV,则不会自动设置 mode==
mode: development
// webpack.dev.config.js
module.exports = {
+ mode: 'development'
- plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
- ]
}
复制代码
mode: production
// webpack.prod.config.js
module.exports = {
+ mode: 'production',
- plugins: [
- new UglifyJsPlugin(/* ... */),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
- new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
- ]
}
复制代码
4.插件变化: webpack4删除了CommonsChunkPlugin插件,它使用内置API optimization.splitChunks 和 optimization.runtimeChunk,即webpack会默认为你生成共享的代码块。
5.Rule.loaders: 此选项已废弃(Rule.loaders 是 Rule.use 的别名。可以使用Rule.use)
6.WebAssembly: 开箱即用WebAssembly(这个没用到,不知道是啥)
二、升级webpack4 loader及插件的配置修改
升级webpack4首先需要更新webpack到v4.0.0以上版,然后安装webpack-cli,建议使用cnpm安装,有时候npm安装下载不下来。
npm install --save-dev webpack-cli
复制代码
项目相关的loader和插件也是需要更新的,不然会报错。接下来介绍一些需要额外配置的loader和插件。
1.vue-loader(更多细节)
Vue Loader v15 现在需要配合一个 webpack 插件才能正确使用:
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')module.exports = {// ...plugins: [new VueLoaderPlugin()]
}
复制代码
现在 Vue Loader v15 使用了一个不一样的策略来推导语言块使用的 loader。
拿 <style lang="less"> 举例:在 v14 或更低版本中,它会尝试使用 less-loader 加载这个块,并在其后面隐式地链上 css-loader 和 vue-style-loader,这一切都使用内联的 loader 字符串。
在 v15 中,<style lang="less"> 会完成把它当作一个真实的 *.less 文件来加载。因此,为了这样处理它,你需要在你的主 webpack 配置中显式地提供一条规则:
{module: {rules: [// ... 其它规则{test: /\.less$/,use: ['vue-style-loader','css-loader','less-loader']}]}
}
复制代码
这样做的好处是这条规则同样应用在 JavaScript 里普通的 *.less 导入中,并且你可以为这些 loader 配置任何你想要的选项。在 v14 或更低版本中,如果你想为一个推导出来的 loader 定制选项,你不得不在 Vue Loader 自己的 loaders 选项中将它重复一遍。在 v15 中你再也没有必要这么做了。如果是用cli搭建的项目,升级webpack4时,别忘记把配置中的样式规则删掉,如下:
//webpack.dev.conf.js
const devWebpackConfig = merge(baseWebpackConfig, {mode: 'development',
- module: {
- rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
- },//其他配置...
})
复制代码
webpack.prod.conf.js文件同上修改
鉴于 v15 中的推导变化,如果你导入一个 node_modules 内的 Vue 单文件组件,它的 <script> 部分在转译时将会被排除在外。为了确保 JS 的转译应用到 node_modules 的 Vue 单文件组件,你需要通过使用一个排除函数将它们加入白名单:
{test: /\.js$/,loader: 'babel-loader',exclude: file => (/node_modules/.test(file) &&!/\.vue\.js/.test(file))
}
复制代码
Vue Loader v15 还废弃了很多选项,它们应该使用普通的 webpack 模块的规则来配置:
- loader
- preLoaders
- postLoaders
- postcss
- cssSourceMap
- buble
- extractCSS
- template
下列选项已经被废弃了,它们应该使用新的 compilerOptions 选项来配置:
- preserveWhitespace (使用 compilerOptions.preserveWhitespace)
- compilerModules (使用 compilerOptions.modules)
- compilerDirectives (使用 compilerOptions.directives)
下列选项已经被改名了:
- transformToRequire (现在改名为 transformAssetUrls)
2.CommonsChunkPlugin
前面提及到webpack4删除了CommonsChunkPlugin插件,需要使用内置API optimization.splitChunks 和 optimization.runtimeChunk替代,具体替代配置如下:
//webpack.prod.conf.js
optimization: {//其他配置runtimeChunk: {name: 'manifest'},splitChunks:{chunks: 'async',minSize: 30000,minChunks: 1,maxAsyncRequests: 5,maxInitialRequests: 3,name: false,cacheGroups: {vendor: {name: 'vendor',chunks: 'initial',priority: -10,reuseExistingChunk: false,test: /node_modules\/(.*)\.js/},styles: {name: 'styles',test: /\.(scss|css)$/,chunks: 'all',minChunks: 1,reuseExistingChunk: true,enforce: true}}}},
复制代码
由于CommonsChunkPlugin已经废弃,所以HtmlWebpackPlugin插件配置中的chunksSortMode也不再需要。
plugins: [//...new HtmlWebpackPlugin({filename: process.env.NODE_ENV === 'testing'? 'index.html': config.build.index,template: 'index.html',inject: true,inlineSource:/(app\.(.+)?\.css|manifest\.(.+)?\.js)$/,minify: {removeComments: true,collapseWhitespace: true,removeAttributeQuotes: true// more options: https://github.com/kangax/html-minifier#options-quick-reference},
- chunksSortMode: 'dependency'}),
]
复制代码
3.mini-css-extract-plugin(更多细节)(webpack4新插件)
介绍新插件之前先说一下extract-text-webpack-plugin,相信大家多少会听说过,它的作用是会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。不过在webpack4中推荐使用mini-css-extract-plugin这个插件。具体配置如下:
//webpack.prod.conf.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin")plugins:[//其他配置new MiniCssExtractPlugin({filename: utils.assetsPath('css/[name].[contenthash].css'),//"[name].css"chunkFilename: utils.assetsPath('css/[id].css'),//"[id].css"}),
]
复制代码
//webpack.base.conf.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const devMode = process.env.NODE_ENV === 'production'module: {rules: [//...{test: /\.css$/,use: [devMode ? MiniCssExtractPlugin.loader : 'vue-style-loader',{loader: 'css-loader',options: { importLoaders: 1 }},'postcss-loader']},]
}
复制代码
再来压缩一下css和js
//webpack.prod.conf.js
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")optimization: {minimizer: [new UglifyJsPlugin({cache: true,parallel: true,sourceMap: true // set to true if you want JS source maps}),new OptimizeCSSAssetsPlugin({})],
}
复制代码
我在升级过程中大概升级了这些东西:
"devDependencies": {//..."webpack": "^4.27.1","webpack-cli": "^3.1.2","webpack-dev-server": "^3.1.10","vue-loader": "^15.4.2","vue-style-loader": "^4.1.2","html-webpack-plugin": "^3.2.0","html-webpack-inline-source-plugin": "0.0.10","babel-loader": "^7.1.3","file-loader": "^2.0.0","mini-css-extract-plugin": "^0.5.0","ts-loader": "^5.3.1","url-loader": "^1.1.2","vue-html-loader": "^1.2.4",
}
复制代码
因为不同的项目相关配置不同,所以接下来就可以npm run dev,看看有啥报错,哪个插件、loader有问题,升个级就好了。
三、项目运行起来了
咋回事样式乱了,看一眼控制台,发现:
组件的模板没有识别,这是什么毛病?在翻阅了大量资料后,得知:
在引入组件的时候,除了ES6的 import 之外,还可以用 webpack 的 require,比如,在vue文件里,就写了大量的如下代码:
const KingKong = require('../BookHomeCommon/KingKong.vue');
const BookList = require('../BookHomeCommon/BookList.vue');
const HomeAlert = require('../BookHomeCommon/HomeAlert.vue');
const DoubleElevenToast = require('../Activitys/DoudleEleven/DoubleElevenToast.vue');
const BrandVideo = require('./BrandVideo.vue');
复制代码
在vue-loader v13.0.0的更新文档中提到:
New
- Now uses ES modules internally to take advantage of webpack 3 scope hoisting. This should result in smaller bundle sizes.
- Now uses PostCSS@6.
Breaking Changes
- The esModule option is now true by default, because this is necessary for ES-module-based scope hoisting to work. This means the export from a *.vue file is now an ES module by default, so async components via dynamic import like this will break:
const Foo = () => import('./Foo.vue')
复制代码
Note: the above can continue to work with Vue 2.4 + vue-router 2.7, which will automatically resolve ES modules' default exports when dealing with async components. In earlier versions of Vue and vue-router you will have to do this:
const Foo = () => import('./Foo.vue').then(m => m.default)
复制代码
Alternatively, you can turn off the new behavior by explicitly using esModule: false in vue-loader options.
Similarly, old CommonJS-style requires will also need to be updated:
// before
const Foo = require('./Foo.vue')// after
const Foo = require('./Foo.vue').default
复制代码
- PostCSS 6 might break old PostCSS plugins that haven't been updated to work with it yet.
官方文档说的很清楚:
- 可以在 vue-loader 的 options 里通过 esModule: false 配置来关闭 ES 模块
- 同步引入组件,正常用 import,而原来使用 require 引入 ES6 语法的文件(例如:export default {...}),现在需要多加一个 default 属性来引用。异步引入组件,需要用动态 import 语法
- 如果有通过 require 引入组件的话,全部改为 require(xxx).default
- 如果有异步引入组件的话,全部更新为动态 import 方式,() => import(xxx)
但是在vue-loader v14.0.0中已经移除options里的esModule配置。无法关闭ES模块。那咋整?项目中已经有大量的const Foo = require('./Foo.vue')的用法。一个一个修改,太费时间,这时自定义loader就是一个很好的解决方案。代码如下:
//compatible-es-module.js
module.exports = function(content) {return content.replace(new RegExp(/require\('\.[/\w\.]+[^(\.png|\.gif|\.jpg)]'\)(\.default)?/,'g'),function(res) {return /(\.default)$/.test(res) ? res :res + '.default';});
};//module: {rules: [{test: /\.(vue)$/,loader: './compatible-es-module'}]
}
复制代码
四、总结
费这么大劲升级,不能没有效果吧,下面看看编译时间对比,这是webpack3编译时长截图:
这是webpack4的:
51万ms和21万ms编译速度足足提高了50%多。(不同项目情况不同,请以实际情况为准)
webpack4还有很多新的特性,有待继续学习。
人们总是对未知的东西,感到恐惧。直面自己的恐惧,学习理解它,你就会进步。(手动耶)
webpack4升级指南相关推荐
- PyTorch 0.4新版本 升级指南 no_grad
PyTorch 0.4新版本 升级指南 [导读]今天大家比较关心的是PyTorch在GitHub发布0.4.0版本,专知成员Huaiwen详细讲解了PyTorch新版本的变动信息, 本次升级, 只做了 ...
- composer升级_Composer 使用姿势与 Lumen 升级指南
Composer 使用姿势 这里主要说说 composer.json 和 composer.lock 文件的作用. composer.json composer.json 文件包含了项目的依赖和其它的 ...
- ie11java阻止_企业IT管理员IE11升级指南【10】—— 如何阻止IE11的安装
企业IT管理员IE11升级指南 系列: 如何阻止IE11的安装 希望自行管理更新计划的企业和组织可以使用 IE11 Automatic Update Blocker Toolkit (自动更新拦截工具 ...
- 打算升级到 Monterey?我们为你准备了一份 macOS 安全升级指南
2021 年 10 月 26 日,期待已久的 macOS 12 正式版终于发布.苹果公司选用加州风景秀丽的小城 Monterey 作为此版本的名字.在外观上, macOS Monterey 并没有大的 ...
- [转] PyTorch 0.4新版本 升级指南 no_grad
转自PyTorch 0.4新版本 升级指南,博主为ShellCollector. PyTorch 0.4新版本 升级指南 PyTorch 终于从0.3.1升级到0.4.0了, 首先引入眼帘的,是PyT ...
- 005-Sencha Cmd 5升级指南
Sencha Cmd 5升级指南 本指南旨在帮助开发人员使用Sencha Cmd从ExtJS 4.1.1 a+升级到ExtJS 5.0.x. 尽管在这个版本中有一些重要的变化,但是我们已经尝试使升级过 ...
- 杜比dss200服务器系统升级包434,杜比数字影院系统DSS200软件升级指南(初稿).pdf
杜比数字影院系统DSS200软件升级指南(初稿).pdf 杜比数字影院系统软件升级指南 升级注意事项 : 1.升级将导致所有影片密钥丢失,请先做好备份 2 .升级前请先断开 DSP200 和 CAT. ...
- 2021 最新 Cloudera 大数据平台 CDP 升级指南白皮书完整版开放下载!(中文版)...
1 大数据平台 CDH/HDP 与 CDP 熟悉大数据业界的小伙伴们都知道,Cloudera 在跟 HortonWorks 合并后,便推出了新一代大数据平台 CDP,并正在逐步停止对原有的大数据平台 ...
- Spring Boot 3.0 正式发布,这份升级指南必须收藏
Spring Boot 3.0 现已正式发布,它包含了 12 个月以来 151 个开发者的 5700 多次代码提交.这是自 4.5 年前发布 2.0 以来,Spring Boot 的第一次重大修订. ...
最新文章
- 数据缺失、混乱、重复怎么办?最全数据清洗指南!
- 以Linux系统上的gcc为例,解密C语言编译背后的全过程!
- Datatable中对某列求和,三种不同情况下的方法 .
- 【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )
- python 单继承的实现
- Docker打包 Asp.Net Core应用,在CentOS上运行
- 卸载一直在创建还原点_如何创建系统还原点以及如何恢复?
- openshift 3 mysql_最新OpenShift免费空间申请与使用教程-1G内存1G空间支持PHP和MysqL
- RTP/RTCP/RTSP/SIP/SDP简介
- poj 3167(KMP+树状数组)
- rust: linker-link-exe-not-found
- xps测试数据处理软件,XPS原始数据处理之 Avantage 软件篇
- FileUtils工具类学习
- SKPlayer -- 一个超级简单好用的音乐插件+CSS+HTML+JS
- 报童模型(2)--经济学含义和应用
- 根据出库、入库表,实现对库存的信息查询
- 两个网段计算机如何共享打印机,不同网段的打印机共享怎么连接?具体步骤
- HPUACM暑期集训第二次积分训练赛 C——Simplest
- openfeign的快速使用
- 华为怎么显示返回按键_苹果手机为何一直没有“返回键”?其实乔布斯生前就说出了答案!...