preface

As the current project in charge of the company is relatively old, I have to wait nearly two minutes for packaging and construction every time. This makes my short fuse unacceptable. And then I’m going to optimize it. Look at webpack version 3. So far it’s all five. It is said that the packing time will be improved. The main thing is support for new plug-ins and features. I set out to upgrade the larger version of WebPack. This is bound to be an earthquake for this project.

Look at the results

[23:20:42] Finished 'build' after 1.28min [23:20:42] Starting 'create:versionCatalog' . [23:20:42] Starting '<anonymous>'... [23:20:42] Finished '<anonymous>' after 36 ms [23:20:42] Finished 'default' after 1.3minCopy the code

Just looking at build this process took a total of 1.28 minutes. Let’s see what happens with the upgrade.

[21:59:37] Finished 'build' after 43 s
[21:59:37] Starting 'create:versionCatalog'...
[21:59:37] Finished 'create:versionCatalog' after 263 ms
......
[21:59:37] Starting '<anonymous>'...
[21:59:37] Finished '<anonymous>' after 31 ms
[21:59:37] Finished 'default' after 44 s
Copy the code

The build process took 43 seconds, so there was a slight increase in speed.

Upgrade process and key points

I won’t go into the details of the upgrade. You can refer to these two articles. I’m just going to pick a few key points.

  • Webpack3 Upgraded to Webpack5

  • Upgrade from WebPack3 to WebPack5 of old VUE Project (I)

Depend on the adjustment

The general tutorial recommends using NPm-check-updates for other adaptation updates, but I want to keep it memorable. I chose to upgrade one by one. The dependence of period adjustment is as follows. If you have any questions, you can add them.

The package name handling The new version number
webpack upgrade 5.37.0
webpack-dev-server upgrade ^ 4.7.4
webpack-cli upgrade ^ 4.9.2
webpack-merge upgrade ^ 5.8.0
html-webpack-plugin upgrade ^ 5.3.2
copy-webpack-plugin-cli upgrade ^ 10.2.4
css-loader upgrade ^ 6.7.1
svg-sprite-loader upgrade ^ 6.0.11
friendly-errors-webpack-plugin upgrade ^ 1.7.0
postcss-loader upgrade ^ 6.2.1
vue-loader upgrade ^ 15.9.8
url-loader delete
file-loader delete
vue-style-loader delete
style-loader new ^ 3.3.1
extract-text-webpack-plugin delete
mini-css-extract-plugin new ^ server
optimize-css-assets-webpack-plugin delete
css-minimizer-webpack-plugin new ^ 3.4.1 track

Changes in the way plugins and dependencies are used

I’m just going to record the common points that need to be adjusted. Specific how to adjust the above recommended article has been mentioned, do not repeat. Readers can go to the above article according to the points listed to find the corresponding specific modification.

  • The project webpack-dev-server has been upgraded to version 4 for webpack5, so the NPM run dev command needs to be changed to webpack serve
  • Add VueLoaderPlugin (vue-loader) to plugins
  • Extract -text-webpack-plugin and optimize- CSS -assets-webpack-plugin are obsolete and require mini-CSS -extract-plugin and CSS – minimizer-webpack-Plug Instead of in
  • Webpack5 has built-in resource parsing, so you don’t need any URl-loader,file-loader, etc., you can directly use assets to parse
  • Adjust the usage of copyWebpackPlugin (copy-webpack-plugin)
  • Const {merge} = require(‘webpack-merge’)
  • NamedModulesPlugin is obsolete and is replaced by Optimization’s moduleIds
  • The usage of the copy-webpack-plugin has changed
  • There are many changes to devServer that can be customized by referring to the devServer feature on the website
  • UglifyJsPlugin is out of date and you can use the TerserPlugin provided with webpack5 out of the box
  • Webpack.optimize.Com code split monsChunkPlugin outdated now use webpack5 provide optimization. SplitChunks attributes to implement the functions to achieve
  • Build – > util. Js file modified a MiniCssExtractPlugin. Loader. The ExtractTextPlugin (extract-text-webpack-plugin) is obsolete, replace it with the MiniCssExtractPlugin (mini-CSS-extract-Plugin).
  • Devtool has made some changes
  • Since vue-loader has been upgraded, CSS using /deep/ may fail before. I use /deep/ on the root node and then switch to ::v-deep and it works. If you have similar problems, you can adjust accordingly.

I have made my own adjustments in the following points.

  • The TerserPlugin removes comments when it compresses code. Corresponding to the website
new TerserPlugin({
  terserOptions: {
    format: {
      comments: false,}},extractComments: false
})
Copy the code

The vue-style-loader was removed and replaced with style-loader. The esModule of CSS-loader is enabled by default from VERSION V4. As a result, the CSS cannot be parsed by vue-style-loader. There are two solutions. Specific: github.com/vuejs/vue-l…

  • MiniCssExtractPlugin I adjusted the CSS generation location and name.
new MiniCssExtractPlugin({
  filename: utils.assetsPath('css/[name].css'),
  chunkFilename: utils.assetsPath('css/[id].[contenthash].css')}),Copy the code

The publicPath of the MiniCssExtractPlugin in utils.js should also be modified accordingly.

return [{
  loader: MiniCssExtractPlugin.loader,
  options: {
    publicPath: '.. /.. / '
  }
}].concat(loaders)
Copy the code
  • SplitChunks adjustment. I adjusted the cacheGroups a bit to consolidate all CSS into one CSS
SplitChunks: {...cacheGroups: {
    vendors: {
      name: 'vendors'.test({ resource }) {
        return /[\/]node_modules[\/]/.test(resource);
      },
      priority: -10
    },
    styles: {
      name: "styles".chunks: "all".type: "css/mini-extract".enforce: true.priority: 10,}}}Copy the code

Due to the use of the GLUP build tool for the project, some adjustments were made. Let me list the adjustments as well.

  • Because the manifest.js file was removed. So the process for dealing with replace:cdnUrl is removed. Instead, the solution to dynamic CDN should be adjusted using the webpack internal variable __webpack_public_path__. Specific methods. Can refer to carry on substitution.

Global variable for webpack public path Settingswebpack_public_path

  • Code obfuscation is different due to the use of the TerserPlugin. So adjust the replace: Version procedure to replace the matching target for the version number.

Old:

gulp.task('replace:version'.function () {
  return gulp.src(`${versionPath}/static/config/index-${env}.js`)
    .pipe($.replace(/window.SITE_CONFIG['version'] = '.*'/g.`window.SITE_CONFIG['version'] = '${version}'`))
    .pipe(gulp.dest(`${versionPath}/static/config/`))});Copy the code

New:

// Replace the ${versionPath}/static/config/index-${env}.js window.site_config ['version'] configuration variable
gulp.task('replace:version'.function () {
  return gulp.src(`${versionPath}/static/config/index-${env}.js`)
    .pipe($.replace(/window.SITE_CONFIG.version=".*"/g.`window.SITE_CONFIG['version'] = '${version}'`))
    .pipe(gulp.dest(`${versionPath}/static/config/`))});Copy the code

The entire gulpfile.js configuration is listed below.

var gulp = require('gulp');
var$=require('gulp-load-plugins') ();var path = require('path');
var del  = require('del');

var distPath    = path.resolve('./dist');
var version     = ' '; / / version number
var versionPath = ' '; // Version path
var env         = ' '; // Run the environment

// Create version number (year month day)
(function () {
  var d = new Date(a);var yy = d.getFullYear().toString().slice(2);
  var MM = d.getMonth() + 1> =10 ? (d.getMonth() + 1) : '0' + (d.getMonth() + 1);
  var DD = d.getDate() >= 10 ? d.getDate() : '0' + d.getDate();
  var h  = d.getHours() >= 10 ? d.getHours() : '0' + d.getHours();
  var mm = d.getMinutes() >= 10 ? d.getMinutes() : '0' + d.getMinutes();
  version = yy + MM + DD + h + mm;
  versionPath = distPath + '/'+ version; }) ();/ / compile
gulp.task('build', $.shell.task([ 'node build/build.js' ]));

// Create the version number directory
gulp.task('create:versionCatalog'.function () {
  return gulp.src(`${distPath}/static/**/*`)
    .pipe(gulp.dest(`${versionPath}/static/`))});// Replace the ${versionPath}/static/config/index-${env}.js window.site_config ['version'] configuration variable
gulp.task('replace:version'.function () {
  return gulp.src(`${versionPath}/static/config/index-${env}.js`)
    .pipe($.replace(/window.SITE_CONFIG.version=".*",/g.`window.SITE_CONFIG['version'] = '${version}', `))
    .pipe(gulp.dest(`${versionPath}/static/config/`))});${versionPath}/static/config/[index-${env}, init].js to ${distPath}/config/index.js
gulp.task('concat:config', gulp.series(function () {
  return gulp.src([`${versionPath}/static/config/index-${env}.js`.`${versionPath}/static/config/init.js`])
    .pipe($.concat('index.js'))
    .pipe(gulp.dest(`${distPath}/config/`))}));/ / to empty
gulp.task('clean'.function () {
  return del([versionPath])
});

gulp.task('getEnv'.function (cb) {
  // Get the environment configuration
  env = process.env.NODE_ENV || 'prod'
  cb()
})

gulp.task('default', gulp.series('clean'.'getEnv'.'build'.'create:versionCatalog'.'replace:version'.'concat:config'.function () {
  // Clear, compile/process files generated in the project
  return del([`${distPath}/static`.`${versionPath}/static/config`])}));Copy the code

conclusion

Then a set of upgrade process down the process is still fruitful. I recorded some of my stomping spots in there. Predecessors stepped on the pit to fill the pit, posterity walked on the road. I hope readers can click “like” and “favorites” if they have gained something.

The next step is to resize the webpack. Because I found that the JS files became bigger after packaging. I hope readers look forward to the author’s webpack5 optimization.

I heard that liking can lead to a raise, promotion, better looking, and better looking