怎样文雅的升级到 webpack4

媒介

如今间隔2018年2月15号webpack4.0.0出来已有一段时间了,如今已出了 @vue/cli 3.0,然则楼主还没试过,据说很壮大,想要试水的能够看文档 @vue/cli,官方脚手架都用上webpack4了,你项目还停留在webpack3,以至webpack2,是否是以为落后了。
受号称0设置的parcel启示,webpack4 增加了一些默许设置,摒弃掉了一些难明的设置,对用户越发友爱,下面我来讲一讲比较大的一些变化

环境

不再支撑 Node.js 4。

默许出入口

在 Webpack 4 中,不再强迫请求指定 entry 和 output 途径。webpack 4 会默许 entry 为 ./src,output 为 ./dist,固然了,这只是开胃菜。

mode 构建形式

webpack 供应了两种构建形式可供挑选 development 和 production

选项形貌
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 时刻官方脚手架能够砍掉的代码

// webpack.development.config.js
module.exports = {
+ mode: 'development'
- plugins: [
-   new webpack.NamedModulesPlugin(),
-   new webpack.DefinePlugin({
-     'process.env': require('../config/dev.env')
-   }),
- ]
}

假如 mode 为production 时刻官方脚手架能够砍掉的代码

 // webpack.production.config.js
module.exports = {
+  mode: 'production',
-  plugins: [
-    new UglifyJsPlugin(/* ... */),
-    new webpack.DefinePlugin({
-       'process.env': require('../config/dev.env')
-    }),
-    new webpack.optimize.ModuleConcatenationPlugin()
-  ]
}

import(): 动态导入

在 webpack 4 中,import() 会返回一个带定名空间(namespace)的对象,这对 ES Module 不会有影响,但关于遵照 commonjs 范例的模块则会加一层包裹:

// webpack 2/3
import("./commonjs").then(exports => {
    // ...
})

// webpack 4
import("./commonjs").then({default: exports}=> {
    // ...
})

optimization 设置项

设置项新增了 optimization 选项,智能的依据所选形式mode为做运转优化。

运用这个设置的时刻之前的一些插件能够运用 optimization 里的设置替代

  • NoEmitOnErrorsPlugin 替换为 optimization.noEmitOnErrors (默许只在 production 形式)
  • ModuleConcatenationPlugin 替换为 optimization.concatenateModules(默许只在 production 形式)
  • NamedModulesPlugin 替换为 optimization.namedModules(默许只在 develoment 形式)

CommonsChunkPlugin 插件被弃用,运用 optimization.splitChunks, optimization.runtimeChunk 替代

// 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的有几个变化你要知道:

vue-loader

什么?学不动了,只要用官网的脚手架不就好了?前端的学问不断更新,抱残守缺,只会不进则退。然则你要置信,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'
        ]
      }
    ]
  }
}

mini-css-extract-plugin css 抽取

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,喜好的话可关注

参考

  1. webpack 文档
  2. webpack github release
  3. Webpack 4 设置最好实践
    原文作者:leizore
    原文地址: https://segmentfault.com/a/1190000015576048
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞