Vue-CLI2项目从 babel 6 + webpack 3.x 升级到 babel7 + webpack4.x 踩坑

栏目: 编程工具 · 发布时间: 5年前

内容简介:当前项目是通过当时本文通过分享代码片段讲述部分版本升级后的不同以及可能发生的报错案例,达到让小伙伴们能找到对应的解决办法,减少升级版本的恐惧感。通过配置

当前项目是通过当时 Vue-CLI 2.x 生成使用,配置是 babel 6 编译、 webpack 3.x 打包。由于项目发展到某个阶段,需要升级优化。目标是打包速度更快、bundle体积更小。

本文通过分享代码片段讲述部分版本升级后的不同以及可能发生的报错案例,达到让小伙伴们能找到对应的解决办法,减少升级版本的恐惧感。

正文

第一部分 Webpack

1. mode 模式

通过配置 mode ,可选 production 生产环境 和 development 开发环境。

2. 基本配置

  1. 移除 loaders,使用 rules 代替

    // webpack.base.config.js
    module: {
    -    loaders: {}
    +    rules: {}
    }
    复制代码
  2. 插件 CommonsChunkPlugin 替换成配置 optimization.splitChunksoptimization.runtimeChunk

    参考: webpack.js.org/plugins/spl…

    webpack 3 CommonsChunkPlugin 插件:

    new webpack.optimize.CommonsChunkPlugin({
         name: 'vendor',
         minChunks: 2
     }),
     // webpack 相关代码打包到一个文件
     // 新模块加入给新模块加一个id
     // 规避长缓存问题
     new webpack.optimize.CommonsChunkPlugin({
         name: 'runtime'
     })
    复制代码

    webpack 4 替代者 splitChunks & runtimeChunk

    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor: {
                    name: 'vendor',
                    minChunks: 2
                    // 可选 'initial | async | all',
                    // 分别代表,初始化时加载、异步加载、两者皆使用
                    chunks: 'all'  
                    // 代表权重值,值越大,打包优先级越高
                    priority: 10 
                }
            }
        },
        runtimeChunk: {
            name: 'runtime'
        }
    }
    复制代码

3. 生产环境 production

生产环境下简化配置,默认开启插件 UglifyJsPlugin

// 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()
- ]
}
复制代码

当然,生产环境依然可以通过配置关闭 UglifyJsPlugin

optimization: {
    minimize: false
}
复制代码

4. 开发环境 development

  1. devServer

    webpack3 需要手写 dev-server.js

    webpack4 使用webpack配置

    // webpack.dev.config.js
    devServer: {
        open: true,              // 自动打开浏览器页面
        host: 'xxx.xxx.com',     // host
        openPage: 'xxx'          // 路径
        historyApiFallback: true // 启用 history模式
        proxy: 'xxx'             // 代理配置  
    }
    复制代码

5. package.json

由于开发环境的devServer使用方式有变化,所以 package.jsonscripts 也需要修改,否则会报如下错误:

ERROR in Entry module not found: Error: Can't resolve './src' in 'E:\workspace'

正确修改配置:

// package.json
{
    "scripts": {
-        "dev": "node build/dev-server.js",
+        "dev": "webpack-dev-server --config build/webpack.dev.config.js"        
    }
}
复制代码

5. 插件安装/升级

如果小伙伴正在使用以下插件,请按详情变更使用,并且可能出现报错解决:

  1. vue-loader v15
  2. thread-loader
  3. eslint-loader v5
  4. copy-webpack-plugin
  5. html-webpack-plugin v4
  6. mini-csss-extract-plugin 替代 extract-text-webpack-plugin
  7. script-text-html-webpack-plugin 废弃

详细:

  1. vue-loader v15

    ①从 v14 迁移

    // webpack.base.config.js
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    
    module.exports = {
      // ...
        plugins: [
            new VueLoaderPlugin()
        ]
    }
    复制代码
  2. thread-loader

    本来打算使用 HappyPack ,可是 vue-loader@15 不完全支持 HappyPack

    现在这个Issue已经关闭,所以小伙伴可以继续尝试用 HappyPack 进行优化,记得反馈哦。

  3. eslint-loader v5

    如有eslint报错如下:

    cannot read property 'eslint' of undefined

    添加配置:

    plugins: [
        new webpack.LoaderOptionsPlugin({ options: {} })
    ]
    复制代码

    如有警告如下:

    [ESLINT_LEGACY_OBJECT_REST_SPREAD] DeprecationWarning. The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead

    修改配置:

    // .eslintrc.js
    parserOptions: {
        parse: 'babel-eslint',
        ecmaVersion: 8,
    -   ecmaFeatures: {
    -       experimentalObjectRestSpread: true
    -   }
    }
    复制代码
  4. copy-webpack-plugin

    如有报错如下: TypeError: compilation.contextDependencies.push is not a function 升级插件

    npm i copy-webpack-plugin@latest -D
    复制代码
  5. html-webpack-plugin v4 如果小伙伴使用 html-webpack-plugin 提供的钩子扩展了自己定义的插件,可能会发生以下错误:

    Plugin could not be registered at 'html-webpack-plugin-before-html-generation'. Hook was not found. BREAKING CHANGE: There need to exist a hook at 'this.hooks'.
    TypeError: callback is not a function
    this.htmlWebpackPlugin.getHooks is not a function

    原因:这三者都是因为升级版本或者使用hooks的方式改变了而导致。

    参考:

    www.npmjs.com/package/htm…

    github.com/jantimon/ht…

    解决:

    //plugin.js
    const HtmlWebpackPlugin = require('html-webpack-plugin');
     
    class MyPlugin {
      apply (compiler) {
        compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
          console.log('The compiler is starting a new compilation...')
     
          // Staic Plugin interface |compilation |HOOK NAME | register listener 
          HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
            'MyPlugin', // <-- Set a meaningful name here for stacktraces
            (data, cb) => {
              // Manipulate the content
              data.html += 'The Magic Footer'
              // Tell webpack to move on
              cb(null, data)
            }
          )
        })
      }
    }
     
    module.exports = MyPlugin
    复制代码
  6. mini-csss-extract-plugin

    这是在我们的项目升级过程中,最容易出现问题的插件。

    ① 修改 Vue-CLI 2 生成关于处理样式的 utils.js

    如下:

    // const ExtractTextPlugin = require("extract-text-webpack-plugin");
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    ...
    // 找到:
    - if (options.extract) { 
    - //options.extract = NODE_ENV === 'production'
    -    return ExtractTextPlugin.extract({
    -        use: loaders,
    -        fallback: 'vue-style-loader'
    -    })
    - } else {
    -    return ['vue-style-lodaer'].concat(loaders))
    - }
    
    + return [options.extract ? 
    +    MiniCssExtractPlugin.loader : 
    +    'vue-style-loader'
    + ].concat(loaders)
    复制代码

    ② 报错: document is not defined
    解决:区分环境使用 mini-css-extract-plugin(production) 和 vue-style-loader(development),如 ① 配置即可

    ③ 报错: cannot read property pop of undefined

    原因:是webpack optimize时候产生的,小编也一知半解,不好解释。

    参考:

    1. github.com/webpack-con…
    2. github.com/webpack-con…
    ④ 警告: [mini-css-extract-plugin] Conflicting order between

    原因:不同CSS模块里,引入同一个CSS,而引入的顺序不一样产生的警告。

    参考: github.com/webpack-con…

    解决: 屏蔽警告

    // 安装依赖
    npm i -D webpack-filter-warnings-plugin
    
    // 配置插件
    plugins: {
        new FilterWarningsPlugin({
            exclude: /mini-css-extract-plugin[^]*Conflicting order between:/,
        })
    }
    复制代码

    ⑤ 疑惑:打包后,产生很多小的css文件,能不能把他们都打包成一个css文件

    原因:vue-loader@15 会把 <style lang="less"> 当作 *.less

    参考: vue-loader.vuejs.org/zh/migratin…

    解决:弃用 mini-css-extract-plugin ,重用 extract-text-webpack-plugin 并升级版本。且把 utils.js 的配置如原来升级前。

    npm i -D extract-text-webpack-plugin@next
    复制代码
    但是,这里可能会产生报错,如下: Error: Path variable [contenthash:8] not implemented in this context: [name]_[contenthash:8].css

    原因:插件的临时版本 @next 并不支持 contenthash ,而且现在这款插件已经不更新了,所以,最好还是使用 mini-css-extract-plugin

    参考: github.com/webpack-con…

    解决:

    plugins: [
        new ExtractTextPlugun({
     -       filename: '[name].[contenthash:8].css'
     +       filename: '[md5:contenthash:hex:20]'
        }})
    ]
    复制代码
  7. script-text-html-webpack-plugin

    原因: 插件暂不支持 webpack4,将会在 v2版 实现

    解决:使用 preload-webpack-plugin

6. 其他警告或报错

  1. You may need an appropriate loader to handle this file type

    原因: package.json 里安装依赖变化了,但是由于 package-lock.json 存在。

    解决办法:

    全局配置一劳永逸:

    npm config set package-lock false
    复制代码

    解决当前项目:

    删除 package-lock.jsonnode_modules ,重新执行命令 npm install

  2. __webpack_hmr 404 not found

    原因:webpack 配置 entry 数组里面有 build/dev-client 的配置

    解决:删除这个配置即可

  3. 部分文件内作用域 this = undefined

    原因:不明

    解决:this 改为 window

  4. warn: entrypoint = undefined
    解决:不用理会

第二部分 Babel

1. 版本升级

# 不安装到本地而是直接运行命令,npm 的新功能
npx babel-upgrade --write

# 或者常规方式
npm i babel-upgrade -g
babel-upgrade --write

# 更新 babel 配置 并且 安装依赖
npx babel-upgrade --write --install
复制代码

2. 配置文件

这里区分需不需要编译 node_modules 里面的依赖。

如果需要,删除项目根目录下 .babelrc 改为使用 babel.config.js


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Advanced Web Metrics with Google Analytics, 2nd Edition

Advanced Web Metrics with Google Analytics, 2nd Edition

Brian Clifton / Sybex / 2010-3-15 / USD 39.99

Valuable tips and tricks for using the latest version of Google Analytics Packed with insider tips and tricks, this how-to guide is fully revised to cover the latest version of Google Analytics and sh......一起来看看 《Advanced Web Metrics with Google Analytics, 2nd Edition》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具