[原簡書]webpack4的遷移

以前寫在簡書的文章

感受是忽然之間,webpack4的消息就滿天飛了,據說打包速度提升了不少,還有最大的噱頭是實現了零配置,leader有一天就吩咐我說,有時間把咱們的項目也升個級唄。好嘞。javascript

1.x到2.x

此次升級跨度比較大,咱們是從webpack1.x升級到4.x,由於1.x與2.x相差挺大,因此第一件事,就是先升到2.x,比較大的改動就是loader的配置方式css

// 1.x
preLoaders: [
    {
       test: /\.vue$/,
       loader: 'eslint',
       exclude: /node_modules/
     }, {
       test: /\.js$/,
       loader: 'eslint',
       exclude: /node_modules/
     }
],
loaders: [
    { test: /\.vue$/, loader: 'vue' },
    { test: /\.json$/, loader: 'json' },
    { test: /\.html$/, loader: 'html' },
...
]
//2.x
module: {
      rules: [
        {
            test: /.vue$/,
            use: 'eslint-loader',
            enforce: 'pre',   // 對應1.x的preLoaders
            exclude: /node_modules/
         }, {
            test: /.js$/,
            use: 'eslint-loader',
            enforce: 'pre',
            exclude: /node_modules/
         },
         { test: /\.vue$/, use: 'vue-loader' },
         { test: /\.json$/, use: 'json-loader' },
         { test: /\.html$/, use: 'html-loader' },
     ...
      ]
},

並且loader必定要寫完整,vue-loader若是隻寫vue會報錯。loader還能夠經過options進行配置。html

{
  loader: 'css-loader',
  options: {
       autoprefixer: false
   }
}

舊版的鏈式調用也用數組替代。vue

1.x
style!postcss!less

2.x
 use: [
       "style-loader",
       "css-loader",
       "less-loader"
 ]

webpack2.x默認支持es6的模塊,因此在編譯時候沒有必要將它們先轉換CommonJS模塊再處理,babel-preset-es2015-webpack已經支持不轉換模塊中的importexport,只須要設置.babelrcjava

"presets": [
  ["es2015", { "modules": false }]
]

另外就是插件的升級,運行時哪一個插件報錯就升級哪一個插件,屢試不爽。node

2.x到4.x

第一步:版本升級

  • 再也不支持node 4,能夠直接升級到8.x版本
  • webpack升級
npm install webpack@4 --save

npm install webpack-cli  --save  // 不要忘記這一點,用來啓動webpack的
  • 插件升級,同理,哪一個報錯就升級哪一個,除了html-webpack-plugin用下面的方法升級,緣由是做者還將來得及升級
npm i webpack-contrib/html-webpack-plugin --save-dev

extract-text-webpack-plugin只有最新的beta版本才支持,因此npm install extract-text-webpack-plugin@next --save-devwebpack

第二步 運行命令中添加 --mode development--mode production

PS:雖說webpack 4是零配置,入口默認是src/index.js,出口是dist/,但因爲項目是多頁面的,因此這一步並無省略,根據實際狀況來。es6

第三步 移除CommonsChunkPlugin

//替代方案
module: {
  rules: [
  ...
  ]
},
optimization: {
  splitChunks: {
    chunks: "all",            // 必須三選一:'initial' | 'all' | 'async'
    minSize: 0,              
    minChunks: 1,
    maxAsyncRequests: 1,
    maxInitialRequests: 1,
    name: () => {},
    cacheGroups: {
        vendor: {
          chunks: 'all',
          test: /node_modules/,      // 正則規則驗證,若是符合就提取chunks
          name: "vendor"            // 要緩存的分割出來的chunk名稱
        },
        default: {
          chunks: 'all',
          name: 'commons',
          reuseExistingChunks: true
        }
    }
  }
}

由於多個頁面,因此結合了html-webpack-pluginweb

new HtmlWebpackPlugin({
    template: 'index.html',
    chunks: ['vendor', 'commons', 'index']
 })

剛開始一直出錯,是由於我沒有複寫default,也沒有default:false,因此其實默認配置有將全部的模塊的公共部分分離到某個文件中,但我在HtmlWebpackPlugin中的chunks中又沒有添加,因此要麼覆寫原來的默認配置,要麼就關閉默認配置。npm

第四步:配置postcss autoprefixer

在根目錄下建立一個文件`postcss.config.js`
module.exports = {
    plugins: [
        require('postcss-inline-svg')({
            removeFill: false
        }),
        require('postcss-pxtorem')({
            replace: process.env.NODE_ENV === 'production',
            rootValue: 750 / 16,
            minPixelValue: 1.1,
            propWhiteList: [],
            unitPrecision: 5
        }),
        require('autoprefixer')({browsers: ['iOS>7', 'Android>4']})
    ]
};

...
 {
      test: /\.(css|less)$/,
      use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use:[{
            loader: 'css-loader',
            options: {
                autoprefixer: false
            }
          },
         {
            loader: 'postcss-loader',
            options: {
                sourceMap: true
            }
          },
          {
            loader: 'less-loader',
            options: {
                relativeUrls: true
            }
          }]
      })
  },
...

第五步:不須要UglifyJsPlugin插件

只須要設置optimization.minimize: true就行,production mode下面自動爲true

以上只是在原有項目的基礎上對webpack 4的升級,還有一些特性並無用到,因此沒有說起,好比sideEffectsjavascript/auto javascript/esm javascript/dynamicwebassembly/experimental等等,有機會再去探索。

相關文章
相關標籤/搜索