精华内容
参与话题
问答
  • webpack4 升级

    2019-03-15 16:57:29
    webpack4升级之坑 webpack4出来已经好久,看到之前的vue-cli项目还是基于"webpack": “^3.6.0”,所以参考了一些资料,对webpack3做了升级。 webpack版本升级 "webpack": "^4.29.6" ...

    webpack4升级之坑

    webpack4出来已经好久,看到之前的vue-cli项目还是基于"webpack": “^3.6.0”,所以参考了一些资料,对webpack3做了升级。

    webpack版本升级

    "webpack": "^4.29.6"
    

    cnpm i 或者 npm i ,依赖安装,npm run dev 看下效果,出现一堆的错误。不难发现是webpack-dev-server 导致:

    webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
    
    module.js:491
        throw err;
        ^
    
    Error: Cannot find module 'webpack/bin/config-yargs'
        at Function.Module._resolveFilename (module.js:489:15)
        at Function.Module._load (module.js:439:25)
        at Module.require (module.js:517:17)
        at require (internal/module.js:11:18)
        at Object.<anonymous> (/Users/xumingxing/Desktop/h5-vue/node_modules/webpack-dev-server/bin/webpack-dev-server.js:54:1)
        at Module._compile (module.js:573:30)
        at Object.Module._extensions..js (module.js:584:10)
        at Module.load (module.js:507:32)
        at tryModuleLoad (module.js:470:12)
        at Function.Module._load (module.js:462:3)
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! h5-vue@1.0.0 dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js`
    npm ERR! Exit status 1
    npm ERR! 
    npm ERR! Failed at the h5-vue@1.0.0 dev script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    

    紧接着,我们就应该继续升级webpack-dev-server ,我将其升级为最新版本,npm run dev 也出错了。主要是compilation.mainTemplate.applyPluginsWaterfall报错,查了资料是 html-webpack-plugin 版本不兼容导致。同样也可将其升级为最新版:

    "webpack-dev-server": "^3.2.1",
    
    //报错主要信息
    ...es/_punycode@1.4.1@punycode/punycode.js/Users/xumingxing/Desktop/h5-vue/node_modules/html-webpack-plugin/lib/compiler.js:81
            var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
                                                      ^
    
    TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function
        at /Users/xumingxing/Desktop/h5-vue/node_modules/html-webpack-plugin/lib/compiler.js:81:51
        at compile (/Users/xumingxing/Desktop/h5-vue/node_modules/_webpack@4.29.6@webpack/lib/Compiler.js:306:11)
        at hooks.afterCompile.callAsync.err 
    

    升级html-webpack-plugin

    "html-webpack-plugin": "^3.2.0",
    

    升级完成后,我们再继续npm run dev 看下效果:

    Module build failed (from ./node_modules/vue-loader/index.js):
    TypeError: Cannot read property 'vue' of undefined
        at Object.module.exports (/Users/xumingxing/Desktop/h5-vue/node_modules/vue-loader/lib/loader.js:61:17)
    
     @ ./src/main.js 4:0-24 13:16-19
     @ multi ./node_modules/_webpack-dev-server@3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
    

    页面依旧报错,查询资料后是继续要升级vue-loader,这里将其升级为"15.7.0":

    "vue-loader": "^15.7.0"
    

    升级完成后,npm run dev ,又是一大堆错误:

     webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
    
     94% after seal                                                                
    
     ERROR  Failed to compile with 2 errors                                                                                                                              15:53:25
    
     error  in ./src/App.vue
    
    Module build failed (from ./node_modules/vue-loader/index.js):
    TypeError: Cannot read property 'vue' of undefined
        at Object.module.exports (/Users/xumingxing/Desktop/h5-vue/node_modules/vue-loader/lib/loader.js:61:17)
    
     @ ./src/main.js 4:0-24 13:16-19
     @ multi ./node_modules/_webpack-dev-server@3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
    
     error  in ./src/components/HelloWorld.vue
    star:h5-vue xumingxing$ npm run dev 
    
    > h5-vue@1.0.0 dev /Users/xumingxing/Desktop/h5-vue
    > webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
    
     94% after seal                                                                
    
     ERROR  Failed to compile with 5 errors                                                                                                                              15:56:38
    
     error  in ./src/components/HelloWorld.vue
    
    Module Error (from ./node_modules/_vue-loader@15.7.0@vue-loader/lib/index.js):
    vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
    
     @ ./src/router/index.js 3:0-49 11:15-25
     @ ./src/main.js
     @ multi ./node_modules/_webpack-dev-server@3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
    
     error  in ./src/App.vue?vue&type=style&index=0&lang=css&
    
    Module parse failed: Unexpected character '#' (15:0)
    You may need an appropriate loader to handle this file type.
    | 
    | 
    > #app {
    |   font-family: 'Avenir', Helvetica, Arial, sans-serif;
    |   -webkit-font-smoothing: antialiased;
    
     @ ./src/App.vue 4:0-63
     @ ./src/main.js
     @ multi ./node_modules/_webpack-dev-server@3.2.1@webpack-dev-server/client?http://localhost:8081 (webpack)/hot/dev-server.js ./src/main.js
    
     error  in ./src/components/HelloWorld.vue?vue&type=template&id=469af010&scoped=true&
    

    错误提示:vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config。这边的错误主要是vue-loader 比较新导致的,新版的vue-loader需要增加新的VueLoaderPlugin:
    主要需要在webpack.dev.conf.js以及webpack.prod.conf.js 添加:
    const VueLoaderPlugin = require(‘vue-loader/lib/plugin.js’)
    并在plugins再实例化一下:

    	//...
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    	//...
     plugins: [
     	//....
        new VueLoaderPlugin(),
        //...
        ]
    

    之前不小心写成了require(‘vue-loader’),系统报错了。写配置的同学需要注意下

     loaderContext.emitError(new Error(
                      ^
    
    TypeError: loaderContext.emitError is not a function
    

    看了一些资料说是webpack4需要制定打包的模式(mode),自己在npm run dev 的时候并未出现类似的提示,故未作配置。不过有兴趣的也可配置一下,在webpack.dev.conf.js以及webpack.prod.conf.js里添加一下mode:‘development’/mode:‘production’

    const webpackConfig = merge(baseWebpackConfig, {
        mode: 'production',
      module: {
        rules: utils.styleLoaders({
          sourceMap: config.build.productionSourceMap,
          extract: true,
          usePostCSS: true
        })
      },
      //...
      })
    

    npm run dev ,运行成功了,效果如下:
    在这里插入图片描述
    如果需要执行 npm run build,发现又有问题了,系统报错:

    Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.
      at Object.get [as CommonsChunkPlugin] (/Users/xumingxing/Desktop/h5-vue/node_modules/_webpack@4.29.6@webpack/lib/webpack.js:185:10)
      at Object.<anonymous> (/Users/xumingxing/Desktop/h5-vue/build/webpack.prod.conf.js:85:25)
      at Module._compile (module.js:573:30)
      at Object.Module._extensions..js (module.js:584:10)
      at Module.load (module.js:507:32)
      at tryModuleLoad (module.js:470:12)
      at Function.Module._load (module.js:462:3)
      at Module.require (module.js:517:17)
      at require (internal/module.js:11:18)
      at Object.<anonymous> (/Users/xumingxing/Desktop/h5-vue/build/build.js:12:23)
      at Module._compile (module.js:573:30)
      at Object.Module._extensions..js (module.js:584:10)
      at Module.load (module.js:507:32)
      at tryModuleLoad (module.js:470:12)
      at Function.Module._load (module.js:462:3)
      at Function.Module.runMain (module.js:609:10)
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! h5-vue@1.0.0 build: `node build/build.js`
    npm ERR! Exit status 1
    npm ERR! 
    npm ERR! Failed at the h5-vue@1.0.0 build script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    

    出错的原因是webpack4中 webpack.optimize.CommonsChunkPlugin 已经被弃用,需要使用新的配置 config.optimization.splitChunks。修改webpack.prod.conf.js。首先找到和CommonsChunkPlugin相关的代码,并全部注释。与plugins同级,插入optimization配置

    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
         )
       }
     }),
     // extract webpack runtime and module manifest to its own file in order to
     // prevent vendor hash from being updated whenever app bundle is updated
     new webpack.optimize.CommonsChunkPlugin({
       name: 'manifest',
       minChunks: Infinity
     }),
     // This instance extracts shared chunks from code splitted chunks and bundles them
     // in a separate chunk, similar to the vendor chunk
     // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
     new webpack.optimize.CommonsChunkPlugin({
       name: 'app',
       async: 'vendor-async',
       children: true,
       minChunks: 3
    })
    

    optimization配置:

     optimization: {
          splitChunks: {
              cacheGroups: {
                  commons: {
                      name: "commons",
                      chunks: "initial",
                      minChunks: 2
                  }
              }
          }
      },
    

    更改后,再重新执行npm run build ,又报错了:

    Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
        at Chunk.get (/Users/xumingxing/Desktop/h5-vue/node_modules/_webpack@4.29.6@webpack/lib/Chunk.js:849:9)
        at /Users/xumingxing/Desktop/h5-vue/node_modules/_extract-text-webpack-plugin@3.0.2@extract-text-webpack-plugin/dist/index.js:176:47
        at Array.forEach (<anonymous>)
        at /Users/xumingxing/Desktop/h5-vue/node_modules/_extract-text-webpack-plugin@3.0.2@extract-text-webpack-plugin/dist/index.js:171:18
        at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/xumingxing/Desktop/h5-vue/node_modules/_tapable@1.1.1@tapable/lib/HookCodeFactory.js:32:10), <anonymous>:7:1)
    

    不难发现,Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead。上网查了下,解决这个问题方法较多。可以升级extract-text-webpack-plugin:

     "extract-text-webpack-plugin": "^4.0.0-beta.0",
    

    同样也是可以用 mini-css-extract-plugin进行处理,我这里就是用mini-css-extract-plugin进行处理。
    本文升级成功后的demo下载地址:https://github.com/yzbyxmx/h5-vue.git

    展开全文
  • webpack4升级

    2019-09-05 13:30:23
    1、安装webpack-cli、webpack "webpack": "^4.39.3" ... 因为 webpackwebpack-dev-server 版本不兼容,升级 "webpack-dev-server": "^3.1.4" 再次启动,报错 因为 html-webpack-plugin ...

    1、安装webpack-cli、webpack

    "webpack": "^4.39.3"

    "webpack-cli": "^3.3.7"

    • npm run dev报错
    • 因为 webpack 和 webpack-dev-server 版本不兼容,升级   "webpack-dev-server": "^3.1.4"
    • 再次启动,报错
    • 因为 html-webpack-plugin 版本不兼容 安装 "html-webpack-plugin": "^3.2.0",再次启动
    • 升级 "vue-loader": "^15.0.10"    再次启动
    • 最新版的 vue-loader 需要加一个新的配置 VueLoaderPlugin
    • // webpack.dev.conf.js
      // 引入
      const { VueLoaderPlugin } = require('vue-loader')

      // 在下面的插件中加入
      plugins: [
          new VueLoaderPlugin(),
      ]


      // webpack.prod.conf.js 文件同样
      // 引入
      const { VueLoaderPlugin } = require('vue-loader')

      // 在下面的插件中加入
      plugins: [
          new VueLoaderPlugin(),
      ]

    • 再次启动

    • dev环境升级完成

    • 运行npm run build报错

    • 因为  webpack.optimize.CommonsChunkPlugin 已经被弃用,需要使用新的配置 config.optimization.splitChunk

       

      // webpack.prod.conf.js
      // 在 plugins 同级下添加配置
      optimization: {
         splitChunks: {
           cacheGroups: {
             vendor: {
               test: /[\\/]node_modules[\\/]/,
               name: 'vendor',
               chunks: 'all'
             },
             manifest: {
               name: 'manifest',
               minChunks: Infinity
             },
           }
         },
       },
       plugins: [...]

      // 去掉 plugins 中的这部分代码
      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
           )
         }
       }),
       // extract webpack runtime and module manifest to its own file in order to
       // prevent vendor hash from being updated whenever app bundle is updated
       new webpack.optimize.CommonsChunkPlugin({
         name: 'manifest',
         minChunks: Infinity
       }),
       // This instance extracts shared chunks from code splitted chunks and bundles them
       // in a separate chunk, similar to the vendor chunk
       // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
       new webpack.optimize.CommonsChunkPlugin({
         name: 'app',
         async: 'vendor-async',
         children: true,
         minChunks: 3
       },

    • 再次运行

    • 因为官方已经不推荐使用 extract-text-webpack-plugin 提取 css 样式,可以使用 mini-css-extract-plugin 替代

    • // 首先安装  mini-css-extract-plugin@0.8.0
      // 并且去掉 package.json 中的包 "extract-text-webpack-plugin": "^4.0.0-beta.0",

      // webpack.base.conf.js

      // 去掉 extract-text-webpack-plugin
      // const ExtractTextPlugin = require('extract-text-webpack-plugin')

      // 引入
      const MiniCssExtractPlugin = require('mini-css-extract-plugin')

      // 下面的 generateLoaders 函数更改配置(*中间的为改动部分)
      function generateLoaders (loader, loaderOptions) {
         const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]

         if (loader) {
           loaders.push({
             loader: loader + '-loader',
             options: Object.assign({}, loaderOptions, {
               sourceMap: options.sourceMap
             })
           })
         }

         // Extract CSS when that option is specified
         // (which is the case during production build)
         if (options.extract) {

         // ********************
         // 改动在这里
           return [MiniCssExtractPlugin.loader].concat(loaders)
         // ********************

         } else {
           return ['vue-style-loader'].concat(loaders)
         }
       }

      // webpack.prod.conf.js

      // 去掉 extract-text-webpack-plugin
      // const ExtractTextPlugin = require('extract-text-webpack-plugin')

      // 引入
      const MiniCssExtractPlugin = require('mini-css-extract-plugin')

      // 去掉 plugins 里的配置
      new ExtractTextPlugin({
         filename: utils.assetsPath('css/[name].[contenthash].css'),
         allChunks: true,
       }),

      // 然后加入新的插件配置
      new MiniCssExtractPlugin({
         filename: utils.assetsPath('css/[name].[contenthash:12].css'),
         allChunks: true,
       }),

    • 再次启动

    • webpack4 需要指定打包的模式 (mode),指定一下就好,可以在 package.json 的命令中指定,也可以写入配置

       

      // webpack.dev.conf.js
      const webpackConfig = merge(baseWebpackConfig, {
          mode: 'development',
          module: {...}
      }


      // webpack.prod.conf.js 
      const webpackConfig = merge(baseWebpackConfig, {
          mode: 'production',
          module: {...}
      }

    • Cannot assign to read only property 'exports' of object '#' (mix require and export) #4039

    • .babellrc中添加插件"transform-es2015-modules-commonjs"

     

    展开全文
  • 主要介绍了webpack3升级webpack4遇到问题总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 主要介绍了webpack 4 升级迁移的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • vue webpack3 升级webpack4

    2019-03-02 18:07:00
    vue webpack3 升级webpack4 据说webpack3 比webpack4 编译速度将近快了60%-80%, 成功升级之后,于是来记录下,项目主要是vue ^2.5.9 , webpack ^4.10.2 , webpack-dev-sever ^3.1.4 ,配合升级的...

    vue webpack3 升级webpack4

    据说webpack3 比webpack4 编译速度将近快了60%-80%,

    成功升级之后,于是来记录下,项目主要是vue ^2.5.9 , webpack ^4.10.2 , webpack-dev-sever ^3.1.4 ,配合升级的还有vue-loader ^15

    项目重现编译之后由原来的1.7MB 减少到1.1MB ,看来在压缩这块也是由效果的。

    需要修改的地方有以下几点:

    vue-loader 14 到15 需要增加如下配置

    const VueLoaderPlugin = require('vue-loader/lib/plugin')  ++++
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')   // webpack 4  +++
    
    const ExtractTextPlugin = require('extract-text-webpack-plugin') //for webpack3  -----
    
    module.exports = {
    ...
    plugins: [
            + new VueLoaderPlugin(),  ++++
            + new MiniCssExtractPlugin({filename:'mian.css'})  //for webpack 4 +++ 
             - new ExtractTextPlugin({filename:'main.css'}) //for webpack 3 ---
    ]
    ...
    }

    webpack-dev-server 升级之后需做如下改动

    devServer: {
         ++ contentBase: path.resolve(__dirname, '../dos-html'),  // 需要指定路径 ++
            port: 7001, 
            hot: true,
            // open: false,
            inline: true,
            compress: true,
            historyApiFallback: true,
           ....
        },

    webpack 3 升级 4 之后需要改动的配置

    plugins: [
       //已经移除
       new webpack.optimize.CommonsChunkPlugin({
           name: 'vendor',
           minChunks: function (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.UglifyJsPlugin(...)//已经移除
    }
    
    ===> 修改为以下
    
    const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
    
    moudel.exports = {
    
    mode: 'production', ++ 这里指定模式。
    ...
    optimization: {
        splitChunks: {
          name(module) {
            return (
              module.resource && /\.js$/.test(module.resource) &&
              module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0
            )
          }
        },
        minimize: true, 
        minimizer: [
          new UglifyJsPlugin({
            uglifyOptions: {
              compress: {
                warnings: false,
                // drop_debugger: true,
                // drop_console: true
              },
              sourceMap: false
            }
          })
        ]
      },
    ...
    }

    其他的各种报错信息,注意看,可能是模块版本太低了吧,都升级下就OK了。
    [完]

    posted @ 2019-03-02 18:07 邱秋 阅读(...) 评论(...) 编辑 收藏
    展开全文
  • webpack4升级指南

    2019-01-22 08:08:00
    作者 | 王呈威鉴于图书项目编译速度极慢的情况(项目里面module太多了,编译慢很正常)且最近需求不多(很少出现的空挡期)。所以我觉得搞一波webpack升级,看看有没...
        

    作者 | 王呈威

    鉴于图书项目编译速度极慢的情况(项目里面module太多了,编译慢很正常)且最近需求不多(很少出现的空挡期)。所以我觉得搞一波webpack升级,看看有没有帮助。webpack于2018年2月25正式发布v4.0.0版本,代号legato。名字是不是很大器,不明觉厉的样子。废话少说下面正式进入主题。(本文的升级配置主要针对vue项目)

    一、webpack4更新变化

    先说一下webpack4有几个比较重要的更新:webpack4更新日志 (https://github.com/webpack/webpack/releases/tag/v4.0.0)

    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,举个栗子。

    1. module.exports = {

    2.  mode: 'production'

    3. };

    或者从 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

    1. // webpack.dev.config.js

    2. module.exports = {

    3. + mode: 'development'

    4. - plugins: [

    5. -   new webpack.NamedModulesPlugin(),

    6. -   new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),

    7. - ]

    8. }

    mode: production

    1. // webpack.prod.config.js

    2. module.exports = {

    3. +  mode: 'production',

    4. -  plugins: [

    5. -    new UglifyJsPlugin(/* ... */),

    6. -    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),

    7. -    new webpack.optimize.ModuleConcatenationPlugin(),

    8. -    new webpack.NoEmitOnErrorsPlugin()

    9. -  ]

    10. }

    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安装下载不下来。

    1. npm install --save-dev webpack-cli

    项目相关的loader和插件也是需要更新的,不然会报错。接下来介绍一些需要额外配置的loader和插件。

    1.vue-loader(更多细节)

    (https://vue-loader.vuejs.org/zh/migrating.html#%E5%80%BC%E5%BE%97%E6%B3%A8%E6%84%8F%E7%9A%84%E4%B8%8D%E5%85%BC%E5%AE%B9%E5%8F%98%E6%9B%B4)

    Vue Loader v15 现在需要配合一个 webpack 插件才能正确使用:

    1. // webpack.config.js

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


    3. module.exports = {

    4.  // ...

    5.  plugins: [

    6.    new VueLoaderPlugin()

    7.  ]

    8. }

    现在 Vue Loader v15 使用了一个不一样的策略来推导语言块使用的 loader。

    拿 <style lang="less"> 举例:在 v14 或更低版本中,它会尝试使用 less-loader 加载这个块,并在其后面隐式地链上 css-loader 和 vue-style-loader,这一切都使用内联的 loader 字符串。

    在 v15 中,<style lang="less"> 会完成把它当作一个真实的 *.less 文件来加载。因此,为了这样处理它,你需要在你的主 webpack 配置中显式地提供一条规则:

    1. {

    2.  module: {

    3.    rules: [

    4.      // ... 其它规则

    5.      {

    6.        test: /\.less$/,

    7.        use: [

    8.          'vue-style-loader',

    9.          'css-loader',

    10.          'less-loader'

    11.        ]

    12.      }

    13.    ]

    14.  }

    15. }

    这样做的好处是这条规则同样应用在 JavaScript 里普通的 *.less 导入中,并且你可以为这些 loader 配置任何你想要的选项。在 v14 或更低版本中,如果你想为一个推导出来的 loader 定制选项,你不得不在 Vue Loader 自己的 loaders 选项中将它重复一遍。在 v15 中你再也没有必要这么做了。如果是用cli搭建的项目,升级webpack4时,别忘记把配置中的样式规则删掉,如下:

    1. //webpack.dev.conf.js

    2. const devWebpackConfig = merge(baseWebpackConfig, {

    3.    mode: 'development',

    4. -   module: {

    5. -     rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })

    6. -   },

    7.    //其他配置...

    8. })

    webpack.prod.conf.js文件同上修改

    鉴于 v15 中的推导变化,如果你导入一个 nodemodules 内的 Vue 单文件组件,它的 <script> 部分在转译时将会被排除在外。为了确保 JS 的转译应用到 nodemodules 的 Vue 单文件组件,你需要通过使用一个排除函数将它们加入白名单:

    1. {

    2.  test: /\.js$/,

    3.  loader: 'babel-loader',

    4.  exclude: file => (

    5.    /node_modules/.test(file) &&

    6.    !/\.vue\.js/.test(file)

    7.  )

    8. }

    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替代,具体替代配置如下:

    1. //webpack.prod.conf.js

    2. optimization: {

    3.    //其他配置

    4.    runtimeChunk: {

    5.      name: 'manifest'

    6.    },

    7.    splitChunks:{

    8.      chunks: 'async',

    9.      minSize: 30000,

    10.      minChunks: 1,

    11.      maxAsyncRequests: 5,

    12.      maxInitialRequests: 3,

    13.      name: false,

    14.      cacheGroups: {

    15.        vendor: {

    16.          name: 'vendor',

    17.          chunks: 'initial',

    18.          priority: -10,

    19.          reuseExistingChunk: false,

    20.          test: /node_modules\/(.*)\.js/

    21.        },

    22.        styles: {

    23.          name: 'styles',

    24.          test: /\.(scss|css)$/,

    25.          chunks: 'all',

    26.          minChunks: 1,

    27.          reuseExistingChunk: true,

    28.          enforce: true

    29.        }

    30.      }

    31.    }

    32.  },

    由于CommonsChunkPlugin已经废弃,所以HtmlWebpackPlugin插件配置中的chunksSortMode也不再需要。

    1. plugins: [

    2.    //...

    3.    new HtmlWebpackPlugin({

    4.      filename: process.env.NODE_ENV === 'testing'? 'index.html': config.build.index,

    5.      template: 'index.html',

    6.      inject: true,

    7.      inlineSource:/(app\.(.+)?\.css|manifest\.(.+)?\.js)$/,

    8.      minify: {

    9.        removeComments: true,

    10.        collapseWhitespace: true,

    11.        removeAttributeQuotes: true

    12.        // more options: https://github.com/kangax/html-minifier#options-quick-reference

    13.      },

    14. -      chunksSortMode: 'dependency'

    15.    }),

    16. ]

    3.mini-css-extract-plugin(更多细节)(https://github.com/webpack-contrib/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这个插件。具体配置如下:

    1. //webpack.prod.conf.js

    2. const MiniCssExtractPlugin = require("mini-css-extract-plugin")


    3. plugins:[

    4.    //其他配置

    5.    new MiniCssExtractPlugin({

    6.      filename: utils.assetsPath('css/[name].[contenthash].css'),//"[name].css"

    7.      chunkFilename: utils.assetsPath('css/[id].css'),//"[id].css"

    8.    }),

    9. ]

    1. //webpack.base.conf.js

    2. const MiniCssExtractPlugin = require("mini-css-extract-plugin")

    3. const devMode = process.env.NODE_ENV === 'production'


    4. module: {

    5.    rules: [

    6.      //...

    7.      {

    8.        test: /\.css$/,

    9.        use: [

    10.          devMode ?  MiniCssExtractPlugin.loader : 'vue-style-loader',

    11.          {

    12.            loader: 'css-loader',

    13.            options: { importLoaders: 1 }

    14.          },

    15.          'postcss-loader'

    16.        ]

    17.      },

    18.    ]

    19. }

    再来压缩一下css和js

    1. //webpack.prod.conf.js

    2. const UglifyJsPlugin = require("uglifyjs-webpack-plugin")

    3. const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")


    4. optimization: {

    5.    minimizer: [

    6.      new UglifyJsPlugin({

    7.        cache: true,

    8.        parallel: true,

    9.        sourceMap: true // set to true if you want JS source maps

    10.      }),

    11.      new OptimizeCSSAssetsPlugin({})

    12.    ],

    13. }

    我在升级过程中大概升级了这些东西:

    1. "devDependencies": {

    2.    //...

    3.    "webpack": "^4.27.1",

    4.    "webpack-cli": "^3.1.2",

    5.    "webpack-dev-server": "^3.1.10",

    6.    "vue-loader": "^15.4.2",

    7.    "vue-style-loader": "^4.1.2",

    8.    "html-webpack-plugin": "^3.2.0",

    9.    "html-webpack-inline-source-plugin": "0.0.10",

    10.    "babel-loader": "^7.1.3",

    11.    "file-loader": "^2.0.0",

    12.    "mini-css-extract-plugin": "^0.5.0",

    13.    "ts-loader": "^5.3.1",

    14.    "url-loader": "^1.1.2",

    15.    "vue-html-loader": "^1.2.4",

    16. }

    因为不同的项目相关配置不同,所以接下来就可以npm run dev,看看有啥报错,哪个插件、loader有问题,升个级就好了。

    三、项目运行起来了

    640?wx_fmt=png

    咋回事样式乱了,看一眼控制台,发现:

    640?wx_fmt=png

    组件的模板没有识别,这是什么毛病?在翻阅了大量资料后,得知:

    在引入组件的时候,除了ES6的 import 之外,还可以用 webpack 的 require,比如,在vue文件里,就写了大量的如下代码:

    1. const KingKong = require('../BookHomeCommon/KingKong.vue');

    2. const BookList = require('../BookHomeCommon/BookList.vue');

    3. const HomeAlert = require('../BookHomeCommon/HomeAlert.vue');

    4. const DoubleElevenToast = require('../Activitys/DoudleEleven/DoubleElevenToast.vue');

    5. 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:

    1. 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:

    1. 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:

    1. // before

    2. const Foo = require('./Foo.vue')


    3. // after

    4. 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 语法

    1. 如果有通过 require 引入组件的话,全部改为 require(xxx).default

    2. 如果有异步引入组件的话,全部更新为动态 import 方式,() => import(xxx)

    但是在vue-loader v14.0.0中已经移除options里的esModule配置。无法关闭ES模块。那咋整?项目中已经有大量的const Foo = require('./Foo.vue')的用法。一个一个修改,太费时间,这时自定义loader就是一个很好的解决方案。代码如下:

    1. //compatible-es-module.js

    2. module.exports = function(content) {

    3.  return content.replace(new RegExp(/require\('\.[/\w\.]+[^(\.png|\.gif|\.jpg)]'\)(\.default)?/,'g'),function(res) {

    4.    return  /(\.default)$/.test(res)  ? res :res + '.default';

    5.  });

    6. };


    7. //


    8. module: {

    9.    rules: [

    10.      {

    11.        test: /\.(vue)$/,

    12.        loader: './compatible-es-module'

    13.      }

    14.    ]

    15. }

    四、总结

    费这么大劲升级,不能没有效果吧,下面看看编译时间对比,这是webpack3编译时长截图:

    640?wx_fmt=png

    这是webpack4的:

    640?wx_fmt=png

    51万ms和21万ms编译速度足足提高了50%多。(不同项目情况不同,请以实际情况为准)

    webpack4还有很多新的特性,有待继续学习。

    人们总是对未知的东西,感到恐惧。直面自己的恐惧,学习理解它,你就会进步。(手动耶)



    最后拉个投票,上周FE们在年会上表演了一个小品《回家过年》,大家顺手帮忙投个票支持下我们吧,万分感谢u1F602.png

    第16个节目《回家过年》 - 小品

    640?wx_fmt=jpeg


    640?wx_fmt=png

    展开全文
  • webpack4升级记录

    2019-06-19 16:39:36
    【各配置文件版本】 // package.json { "babel-polyfill": "^6.26.0", "vue-loader": "^15.7.0", "babel-core": "^6.26.3", "babel-loader": "^7.1.5", "babel-plugin-syntax-jsx": "6.18.0", ...
  • Webpack4升级指南

    2018-07-10 16:26:37
    =6.11.5,当然考虑到最佳的es6特性实现,建议node版本可以升级到V8.9.4或以上版本,具体更新说明部分可以见:webpack4更新日志"engines": { "node": "&gt;=6.11.5" // &gt;=...
  • webpack3升级webpack4

    2019-04-22 16:34:47
    webpack4出来有一段时间了,现在3升级到4 运行 npm i npm-check -g npm-check -u 选择要更新的依赖,loader之类都更新到最新 npm i webpack-cli --save-dev dev和prod 添加不同mode utils.js css 预编译处理 ...
  • 本篇文章主要介绍了详解webpack4升级指南以及从webpack3.x迁移,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • webpack3升级webpack4

    2019-10-04 15:14:55
    写在前面的话:为什么要升级,因为公司目前的项目使用webpack3,但是因为是多页应用,...后来听说webpack4优化了打包速度,于是就准备去尝试了。升级后速度直接变为热更新2秒。惊到我~ webpack3的配置 webpackCon...

空空如也

1 2 3 4 5 ... 20
收藏数 1,290
精华内容 516
关键字:

webpack4升级