如今距離2018年2月15號webpack4.0.0出來已經有一段時間了,如今已經出了 @vue/cli 3.0,可是樓主還沒試過,據說很強大,想要試水的能夠看文檔 @vue/cli,官方腳手架都用上webpack4了,你項目還停留在webpack3,甚至webpack2,是否是以爲落伍了。
受號稱0配置的parcel啓發,webpack4 增長了一些默認配置,摒棄掉了一些難懂的配置,對用戶更加友好,下面我來說一講比較大的一些變化javascript
再也不支持 Node.js 4。css
在 Webpack 4 中,再也不強制要求指定 entry 和 output 路徑。webpack 4 會默認 entry 爲 ./src,output 爲 ./dist,固然了,這只是開胃菜。前端
webpack 提供了兩種構建模式可供選擇 development 和 productionvue
選項 | 描述 |
---|---|
development | 會將 process.env.NODE_ENV 的值設爲 development。啓用 NamedChunksPlugin(固化 runtime 內以及在使用動態加載時分離出的 chunk 的 chunk id) 和 NamedModulesPlugin(開啓 HMR[熱重載]的時候使用該插件會顯示模塊的相對路徑)。 |
production | 會將 process.env.NODE_ENV 的值設爲 production。啓用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin. |
也就是說若是 mode 爲development 時候官方腳手架能夠砍掉的代碼java
// webpack.development.config.js module.exports = { + mode: 'development' - plugins: [ - new webpack.NamedModulesPlugin(), - new webpack.DefinePlugin({ - 'process.env': require('../config/dev.env') - }), - ] }
若是 mode 爲production 時候官方腳手架能夠砍掉的代碼node
// webpack.production.config.js module.exports = { + mode: 'production', - plugins: [ - new UglifyJsPlugin(/* ... */), - new webpack.DefinePlugin({ - 'process.env': require('../config/dev.env') - }), - new webpack.optimize.ModuleConcatenationPlugin() - ] }
在 webpack 4 中,import() 會返回一個帶命名空間(namespace)的對象,這對 ES Module 不會有影響,但對於遵循 commonjs 規範的模塊則會加一層包裹:webpack
// webpack 2/3 import("./commonjs").then(exports => { // ... }) // webpack 4 import("./commonjs").then({default: exports}=> { // ... })
配置項新增了 optimization 選項,智能的根據所選模式mode爲作運行優化。git
使用這個配置的時候以前的一些插件能夠使用 optimization 裏的配置代替es6
CommonsChunkPlugin 插件被棄用,使用 optimization.splitChunks, optimization.runtimeChunk 代替github
// webpack.prod.conf.js const config = { // ... plugins: [ - new webpack.NoEmitOnErrorsPlugin(), - new webpack.optimize.ModuleConcatenationPlugin(), // 預編譯 - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks (module) { - // any required modules inside node_modules are extracted to vendor - return ( - module.resource && - /\.js$/.test(module.resource) && - module.resource.indexOf( - path.join(__dirname, '../node_modules') - ) === 0 - ) - } - }), - new webpack.optimize.CommonsChunkPlugin({ - name: 'manifest', - minChunks: Infinity - }), ], + optimization: { + noEmitOnErrors: true, + concatenateModules: true, + splitChunks: { + chunks: 'all', + name: 'common', + }, + runtimeChunk: { + name: 'runtime' + } + } };
// webpack.dev.conf.js const config = { // ... plugins: [ - new webpack.NamedModulesPlugin() ] + optimization: { + namedModules: true + } };
optimization.splitChunks 默認是不用設置的。若是 mode 是 production,那 Webpack 4 就會開啓 Code Splitting。默認 Webpack 4 只會對按需加載的代碼作分割。若是咱們須要配置初始加載的代碼也加入到代碼分割中,能夠設置 splitChunks.chunks 爲 'all'
webpack4 的mode 設置成 production 時,默認開啓代碼壓縮,可是我要敲黑板,劃重點了,uglifyjs-webpack-plugin 終於到 v1.0.0 版本了,支持多進程壓縮,緩存以及es6語法,無需單獨安裝轉換器。感動不感動。想看的話能夠看這裏順風車。想要覆蓋配置能夠這樣
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') module.exports = { // ... optimization: { minimizer: [ new UglifyJsPlugin() // 具體配置可看github ] } }
移除了 module.loaders
移除了 loaderContext.options
移除了 Compilation.notCacheable
移除了 NoErrorsPlugin
移除了 Dependency.isEqualResource
移除了 NewWatchingPlugin
移除了 CommonsChunkPlugin
既然講了 webpack 作了比較大的更新,周邊的配套設施也不要不捨得,改換久換,因爲我平時項目中使用vue,若是你也使用vue的話,那麼針對vue的有幾個變化你要知道:
什麼?學不動了,只要用官網的腳手架不就行了?前端的知識不斷更新,固步自封,只會不進則退。可是你要相信,webpack也好,vue-loader 也好,api 會愈來愈好懂,性能也會更加高效,因此,扶我起來,我還能學。。。
Vue Loader v15 使用了一個不同的策略來推導語言塊使用的 loader。vue-loader v15
在 v14 或更低版本中,若是你想爲一個推導出來的 loader 定製選項,你不得不在 Vue Loader 本身的 loaders 選項中將它重複一遍。在 v15 中你再也沒有必要這麼作了。
拿官方腳手架來講, 能夠看到兩個函數,用來生成 vue-loader 的 options 還有 module.rule, 我把他們摘出來,就能夠看出來了。
// util.js exports.cssLoaders = function (options) { // ... } // Generate loaders for standalone style files (outside of .vue) exports.styleLoaders = function (options) { // ... }
// vue-loader-conf.js module.exports = { loaders: utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: isProduction }), ... }
// webpack.dev.config const devWebpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, ... }
我剛入腳手架的坑的時候都蒙了,爲何要這樣寫,爲了德瑪西亞麼?固然不是,是由於填 vue-loader v14 的坑
vue-loader v15版本只要寫一遍就行了,可是要注意請確保在你的 webpack 配置中添加 Vue Loader 的插件
// webpack.config.js const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { module: { rules: [ { test: /\.vue$/, loader: 'vue-loader' }, // ... ] }, plugins: [ // 請確保引入這個插件! new VueLoaderPlugin() ] }
而後因爲生產和測試環境對 css 文件處理不一樣。在webpack.dev.config.js和webpack.prod.config.js裏分別配置 less/scss css 的loader就行了:
{ module: { rules: [ // ... { test: /\.less$/, use: [ 'vue-style-loader', 'css-loader', 'less-loader' ] } ] } }
webpack v4 官方不在推薦使用 extract-text-webpack-plugin 了,改換 mini-css-extract-plugin
// webpack4 npm install -D mini-css-extract-plugin // webpack.config.js var MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { // 其它選項... module: { rules: [ // ... 忽略其它規則 { test: /\.css$/, use: [ process.env.NODE_ENV !== 'production' ? 'vue-style-loader' : MiniCssExtractPlugin.loader, 'css-loader' ] } ] }, plugins: [ // ... 忽略 vue-loader 插件 new MiniCssExtractPlugin({ filename: style.css }) ] }
// webpack3 npm install -D extract-text-webpack-plugin // webpack.config.js var ExtractTextPlugin = require("extract-text-webpack-plugin") module.exports = { // 其它選項... module: { rules: [ // ...其它規則忽略 { test: /\.css$/, loader: ExtractTextPlugin.extract({ use: 'css-loader', fallback: 'vue-style-loader' }) } ] }, plugins: [ // ...vue-loader 插件忽略 new ExtractTextPlugin("style.css") ] }
對webpack3官方腳手架還不是很瞭解的同窗能夠看我根據本身理解寫的註釋,詳情點這裏
以爲麻煩,不想本身搞?那也不要緊,我本身按照腳手架改了一套,感興趣的能夠試試點這裏
以爲不錯請star哦,另外,我準備在下一篇文章中將如何如優化webpack,喜歡的話可關注