原创

vue-cli2升级webpack版本

升级相关依赖

这里建议使用yarn add 或者是npm install 来升级依赖包,这样升级之后的版本信息会写入package.json里面

这里列出我升级依赖包对应的版本

  • webpack 2.2.1 => 4.43.0
  • vue 2.3.4 => 2.6.11
  • "vue-loader": "^12.2.1" => "vue-loader": "^15.9.1" vue-loader升级去掉了部分属性,更改了部分api名
  • vue-template-compiler 2.3.4 => 2.6.11 注意这里的compiler的版本跟vue的版本是有对应关系的,如果安装出错的话,运行的时候会报错的

因为loader和plugin的版本跟webpack的也是对应的,所以升级webpack也必须升级loader和plugin,否则会出现兼容的问题,运行起来一堆错误

  • "copy-webpack-plugin": "^4.0.1" => "^5.1.1",
  • "css-loader": "^0.28.4" => "css-loader": "^3.5.3"
  • "file-loader": "^0.11.0" => "file-loader": "^6.0.0"
  • "friendly-errors-webpack-plugin": "^1.6.1" => "friendly-errors-webpack-plugin": "^1.7.0"

  • "mini-css-extract-plugin": "^0.9.0"这个是新添加的,webpack4建议使用这个插件来提取css文件。

  • "optimize-css-assets-webpack-plugin": "^1.3.2" => "optimize-css-assets-webpack-plugin": "^5.0.3"
  • "url-loader": "^0.5.9" => "url-loader": "^4.1.0"
  • "webpack-dev-server": "^3.10.3" 这个依赖也是新添加的,我创建该项目的时候使用的vue-cli版本很老,还是使用express的版本。
  • "webpack-merge": "^2.6.1" => "webpack-merge": "^4.2.2"

除了升级依赖以外,我还修改了package.json文件,更改的地方只是启动方式,如果你的项目是后面的启动方式,就无需做更改。

  "scripts": {
    "dev": "node build/dev-server.js",
    "start": "node build/dev-server.js",
    "build": "node --max_old_space_size=4096 build/build.js"
  },

=>

"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  "build": "node --max_old_space_size=4096 build/build.js"
},

完整的package.json在这里

我觉得有部分改动无关升级,我也是参照着其他的博客来进行升级的。但是大多数都是从vue-cli2.9.x所创建项目来进行升级的,此时的webpack是3.x,我的比较早,webpack是2.x版本。

{
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node --max_old_space_size=4096 build/build.js"
  },
  "dependencies": {
    "axios": "^0.16.2",
    "happypack": "^5.0.1",
    "iview": "^3.4.2",
    "js-base64": "^2.5.1",
    "js-cookie": "^2.2.1",
    "mint-ui": "^2.2.7",
    "qiniu-js": "^2.5.3",
    "qrcode": "^1.2.0",
    "tempfile": "^2.0.0",
    "v-charts": "^1.6.2",
    "vue": "^2.6.11",
    "vue-qr": "^1.5.2",
    "vue-resource": "^1.3.4",
    "vue-router": "^2.7.0",
    "vuex": "^2.3.1",
    "wangeditor": "^3.1.1",
    "xlsx": "^0.15.6"
  },
  "devDependencies": {
    "@vue/component-compiler-utils": "1.3.1",
    "autoprefixer": "^7.1.1",
    "babel-core": "^6.24.1",
    "babel-loader": "^7.0.0",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-env": "^1.5.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-2": "^6.24.1",
    "babel-register": "^6.24.1",
    "chalk": "^1.1.3",
    "connect-history-api-fallback": "^1.3.0",
    "copy-webpack-plugin": "^5.1.1",
    "css-loader": "^3.5.3",
    "eventsource-polyfill": "^0.9.6",
    "express": "^4.14.1",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^6.0.0",
    "friendly-errors-webpack-plugin": "^1.7.0",
    "html-webpack-plugin": "^4.2.0",
    "http-proxy-middleware": "^0.17.4",
    "less": "3.9.0",
    "less-loader": "5.0.0",
    "mini-css-extract-plugin": "^0.9.0",
    "opn": "^5.0.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "ora": "^1.1.0",
    "rimraf": "^2.6.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.7",
    "style-loader": "^1.2.0",
    "uglifyjs-webpack-plugin": "^2.2.0",
    "url-loader": "^4.1.0",
    "vue-html5-editor": "^1.1.1",
    "vue-loader": "^15.9.1",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.6.11",
    "webpack": "^4.43.0",
    "webpack-bundle-analyzer": "^2.8.2",
    "webpack-cli": "^3.3.11",
    "webpack-dev-middleware": "^1.10.2",
    "webpack-dev-server": "^3.10.3",
    "webpack-hot-middleware": "^2.18.0",
    "webpack-merge": "^4.2.2"
  },
  "engines": {
  "node": ">= 4.0.0",
  "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

改动config下的index.js文件

//使用了webpack-dev-server之后代理的形式需要更改
dev:{    
     cacheBusting: true,
     devServer: {
       proxy: {
         '/api':'http://ip:port'
       }
     }
}

改动build下的vue-loader.conf.js


var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'

module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: isProduction
      ? config.build.productionSourceMap
      : config.dev.cssSourceMap,
    extract: isProduction
  }),
  // +++begin
  cacheBusting: config.dev.cacheBusting,
  // +++ end
  transformAssetUrls: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: ['xlink:href','href']
  }
}

=>


var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'
// +++begin
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
// +++end
module.exports = {
  loaders: utils.cssLoaders({
  sourceMap: isProduction
    ? config.build.productionSourceMap
    : config.dev.cssSourceMap,
    extract: isProduction
  }),
  // +++begin
  cssSourceMap: sourceMapEnabled,
  cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  }
  // +++end
}

更改build下的webpack.base.conf.js

// +++begin
const { VueLoaderPlugin } = require('vue-loader') 在头部添加
// +++ end
module.exports = {
    //+++begin
    mode: process.env.NODE_ENV,//为了更cli创建的环境一直,这里添加这一句
    devServer: config.dev.devServer,
    // +++end

    //+++begin
     plugins: [
         new VueLoaderPlugin()// 添加使用vue-loader的plugin,vue-loader升级之后更以前的使用方式有点儿不同,需要添加这么一句
    ]
    // +++ end
}

更改build下的webpack.dev.conf.js文件

  new HtmlWebpackPlugin({
    filename: 'index.html',
    template: 'index.html',
    inject: true,
    // +++begin
    hash: true,
    chunksSortMode: 'none'
    // +++end
  }),

更改build下的webpack.prod.conf.js文件

// var ExtractTextPlugin = require('extract-text-webpack-plugin')
// +++ begin
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
//+++end
// ---begin
//  new webpack.optimize.UglifyJsPlugin({
//   compress: {
//     warnings: false
//   },
//   sourceMap: true
// }),


// new ExtractTextPlugin({
//   filename: utils.assetsPath('css/[name].[contenthash].css')
// }),


// new webpack.optimize.CommonsChunkPlugin({
//   name: 'vendor',
//   minChunks: function (module, count) {
//     // 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',
//   chunks: ['vendor']
// }),
// --- end

// +++ begin
new MiniCssExtractPlugin({
  filename: utils.assetsPath('css/[name].[chunkhash:8].css')
}),
//+++end

new HtmlWebpackPlugin({
  filename: config.build.index,
  template: 'index.html',
  inject: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
    // more options:
    // https://github.com/kangax/html-minifier#options-quick-reference
  },
  // necessary to consistently work with multiple chunks via CommonsChunkPlugin
  // chunksSortMode: 'dependency' 这里注释掉或者是把值改为auto,因为默认值就是auto,升级后的html-webpack-plugin似乎是没有dependency这个选项了,进行打包时会报错
}),

//在plugins的同级添加,webpack4去掉了之前的optimize.CommonsChunkPlugin改用来optimization.splitChunks的形式
plugins: [
  //...
],
// +++ begin
optimization: {
  splitChunks: {
    chunks: 'all',
    minSize: 30000,
    minChunks: 1,
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        priority: 10
      },
      manifest: {
        test: /[\\/]src[\\/]/,
        minSize: 0,
        minChunks: 2,
        priority: 9
      }
    }
  }
}

// +++end

还需要更改build下的utils.js文件

// 头部添加
// +++begin
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
//+++end

// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
  // --- begin
  // return ExtractTextPlugin.extract({
  //   use: loaders,
  //   fallback: 'vue-style-loader',
  //   publicPath: '../../'
  // })
  // ---end
  // +++ begin
  return [{
    loader: MiniCssExtractPlugin.loader,
    options: {
      publicPath: '../../', // 这里是重要的一点,很多博客都没提到这里,如果不添加这个options的话,css里面图片url及字体的url转换路径会有问题,到时候浏览器会提示一堆404
    }
  }].concat(loaders)
  // +++ end
} else {
  return ['vue-style-loader'].concat(loaders)
}
正文到此结束