Webpack v3 -> v4 大家一起找不同

继之前的webpack3的简单应用,这篇来讲webpack的升级,讲讲我在升级中遇到的不同。。

Webpack是我们进行前端开发时常用的打包工具之一,因此,当webpack出了4之后,我们还是要跟上它升级的步伐,跟着用起来,不然Webpack要是升到了5,一下跨两个版本,差别还是挺大的。所以我们先升一下v4,找找不同。

webpack版本的不同

要升级到v4,首先肯定package不同,我们在项目中会用到很多package,webpack升级的话,很多package的版本可能会不适用,但是我们升完webpack之后是会有提示的,所以我们先升级一下webpack

npm uninstall wbepack webpack-dev-server -D

npm i webpack webpack-dev-server webpack-cli -D

webpack升级之后,我们需要多安装一个package --> webpack-cli,看这个名字我就猜这是一个脚手架,实际上它也是一个脚手架哈,用于快速构建一个webpack项目,在v3中我们不需要用到它,但是v4将webpack的一些命令转移到了webpack-cli中,所以我们升级后还要多安装一个webpack-cli。

webpack配置不同

v3
const config = {
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor'
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'runtime'
        })
    ]
}

在v3的时候,会在插件里会使用webpack.optimize.CommonsChunkPlugin()方法可以将第三方库和公共模块、entry指定的js单独打包到js文件中,避免bundle文件过大,而且也能提高加载速度,那我们也还能在里面加一些参数来配置chunk的,v4中将该方法废弃了,使用optimization来进行配置

v4
const config = {
    mode: process.env.NODE_ENV || "production", // 新增mode必需配置告诉webpack进行内置优化
    optimization: {
        splitChunks: {
            chunks: 'all' // 默认将js代码打包到vendor里面
        },
        runtimeChunk: true // 将除了entry里面指定的js的name的时候,其他的js放到runtime里面去
    }
}

关于optimization更详细的配置可以参照官网。

其他package的不同

webpack升级完后,我们在服务端能看到有一段warning,提示有些插件需要v2或v3的webpack,这些插件呢,我们就需要重新安装一下,方法同上,需要更改的插件举例:

url-loader
html-webpack-plugin
file-loader
babel-loader

升级中我们会看到提示需要一个ajv的包,ajv是一个基于JSON Schema的依赖包,它能根据Schema格式作为参数生成一个对象,然后调用对象自身的方法验证数据的合法性。目前我们在项目中用到的还挺少的,你可以选择是否安装。

extract-text-webpack-plugin弃用

升级后,关于这个插件要着重介绍一下,extract-text-webpack-plugin用于将js文件里的样式抽离出来,单独打包,在v2、v3中我们用着都很顺利,但是升级到v4之后,他还没有出正式版本来适配webpack4,如果你还想接着用的话,可以使用它的测试版本.

npm i extract-text-webpack-plugin@next -D

但是在正式项目中,我们用一个还在测试的版本还是有一定风险的,所以我们去找一下有没有更好的解决办法。

去webpack提供的extract-text-webpack-plugin的GitHub仓库看了一下,地址 -> https://github.com/webpack-contrib/extract-text-webpack-plugin , 发现webpack为我们提供了另外一个插件:mini-css-extract-plugin,使用这个插件就能解决我们的css抽离问题了,适用方法示例:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      // 使用hash是处于安全考虑
      filename: devMode ? '[name].css' : '[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    })
  ],
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      }
    ]
  }
}

mini-css-extract-plugin不能与style-loader同时使用,所以我们在开发环境是使用style-loader就行,不用太注重文件大小,正式环境时就使用mini-css-extract-pllugin打包css。

vue-loader使用方法不同

使用Vue框架搭建项目是,需要注意的一个是,vue-loader的使用,在v3中,我们只需要在规则里面声明loader就可以,但是升级后,我们要将vue-loader作为一个插件去引用

const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
    module: {
        rules: [{
            test: /\.vue$/,
            loader: 'vue-loader'
        }]
    },
    plugins: [
        new VueLoaderPlugin()
    ]
}

我们使用vue-loader来解析vue组件,也允许在文件中的