GitHub address: github.com/qiyu99/w5v3…

Create a new project folder and initialize the Git repository

md w5v3 && cd w5v3
git init
yarn init -y
Copy the code

Install webpack

yarn add -D webpack webpack-cli webpack-merge
Copy the code

Configure configuration files for different modes for WebPack

In the build folder of the project root directory, create webpack.base.config.js, webpack.dev.config.js, and webpack.prod.config.js.

Webpack.base.config.js holds the common configuration code

// webpack.base.config.js
const path = require('path')

module.exports = {
  entry: './src/main.js',
  output: {
    filename: 'app.[contenthash:8].js',
    path: path.resolve(process.cwd(), 'dist')
  }
}
Copy the code

Create a new SRC folder in the project root directory and create the main.js project entry file inside SRC

Webapck.dev.config.js stores the development environment configuration code

// webapck.dev.config.js
module.exports = {
  mode: 'development',
}
Copy the code

Webapck.prod.config.js stores the production environment package configuration code

// webapck.prod.config.js
module.exports = {
  mode: 'production',
}
Copy the code

Consolidating configuration files

Create a new webpack.config.js file in the root directory and consolidate the three configuration files in the build folder

// webpack.config.js
const { merge } = require('webpack-merge')
const baseConfig = require('./build/webpack.base.config')
const devConfig = require('./build/webpack.dev.config')
const proConfig = require('./build/webpack.prod.config')

let config = process.env.NODE_ENV === 'development' ? devConfig : proConfig

module.exports = merge(baseConfig, config)
Copy the code

Installation of cross – env

yarn add -D cross-env
Copy the code

Modify package.json to add build script

"scripts": {
  "build": "cross-env NODE_ENV=production webpack",
}
Copy the code

Package file cleaning

Since the packaged files are hashed, the dist directory will be retained for each packaged file. Installing and configuring the clean-webpack-plugin helps us to clean up the previous packaged files before each packaged file.

yarn add -D clean-webpack-plugin
Copy the code

Modify the webpack. Prod. Config. Js

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

......
plugins: [
  new CleanWebpackPlugin()
]
Copy the code

Convert ES6 ES5

If your project does not need to be converted to ES5, you can use esbuild instead of Babel-Loader

Install Babel – loader

yarn add -D @babel/core @babel/preset-env babel-loader
Copy the code

Modify the webpack. Base. Config. Js

. module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }, ] } ...Copy the code

Parse font and image resources

Webpack5 provides built-in static resource building capabilities. We do not need to install additional loaders, and only need simple configuration to realize the packaging and directory storage of static resources. As follows: Resources that match the rule can be stored in the assets folder.

Modify the webpack. Base. Config. Js

Rules: [... {test: / \. (PNG | JPG | SVG | GIF) $/, type: 'asset/inline, the generator: {/ / / ext front cabin. "" filename: 'assets/[hash:8].[name][ext]', }, }, { test: /\.(ttf|svg|eot|woff|woff2)$/, type: 'asset/resource', generator: { filename: 'assets/[hash:8].[name][ext]', }, } ]Copy the code

Type can be:

  • Asset/Source – functions as raw-loader.
  • Asset /inline – Functions as urL-loader. If you want to set the encoding rules, you can set the dataUrl in the generator. For details, see the official documentation.
  • Asset/Resource – Functions equivalent to file-loader.
  • Asset — The default type is selected based on the file size, asset/inline is used when the file is smaller than 8 KB, otherwise asset/ Resource is used. You can also manually set thresholds. For details, see the official documents

Open source – the map

Usually, we want to enable the Source Map function during development to facilitate code error detection, while the code packaged in production environment is turned off source Map function to avoid exposure of source code. So enable devtool to set source map only in webpack.dev.config.js

// webpack.dev.config.js module.exports = { mode: 'development', devtool: 'eval-cheap-module-source-map',// webpack5 modified validation rules}Copy the code

Note: Webpack5 has modified the devTool regex verification rule. Webpack4’s scheme will report an error in Webpack5

Create an HTML file template

Create a public folder in the project root directory and create the index.html template file in it and write the following:

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" /> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong> We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue. </strong> </noscript> <div id="app"></div> </body> </html>Copy the code

To automatically insert packed JS files into HTML template files, you need to install the html-webpack-plugin

yarn add -D html-webpack-plugin
Copy the code

Modify the webpack.dev.config.js file to add plugins configuration items

// webpack.dev.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')

......
plugins: [
  new HtmlWebpackPlugin({
    title: 'W5V3',
    template: './public/index.html'
  }),
]
Copy the code

Modify the webpack.prod.config.js file to add plugins as well

Note: FOR production configuration, HTML file compression is turned on

// webpack.prod.config.js const HtmlWebpackPlugin = require('html-webpack-plugin') ...... plugins: [ new HtmlWebpackPlugin({ title: 'W5V3', filename: 'index.html', template: './public/index.html', favicon: './public/favicon.ico', minify: {// collapseWhitespace: true, minifyCSS: True // Compress inline CSS}, cache: true}),Copy the code

Install webpack-dev-server and configure the development server

yarn add -D webpack-dev-server@4
Copy the code

Modify webpack.dev.config.js to add devServer configuration

// webpack.dev.config.js
  devServer: {
    hot: true,
    open: true,
    port: 1024,
  },
Copy the code

Modify the package.json file scripts and add the serve command script

// package.json
"scripts": {
  "serve": "cross-env NODE_ENV=development webpack serve",
  "build": "cross-env NODE_ENV=production webpack",
}
Copy the code

Parse Less and CSS files

Install the following dependencies

yarn add -D less less-loader postcss postcss-loader css-loader style-loader
Copy the code

Development and production environments have slightly different requirements for CSS style parsing:

  • Development environment configurations tend to quickly parse resources and build quickly;
  • The production environment configuration requires CSS code tree shaking, code compression, and extracting individual files.

Modify the webpack.dev.config.js file to add the following configuration

// webpack.dev.config.js
...
module: {
  rules: [
    {
      test: /\.css$/,
      use: ['style-loader', 'css-loader', 'postcss-loader']
    },
    {
      test: /\.less$/,
      use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
    },
  ]
},
...
Copy the code

In the development environment, after layer upon layer of CSS style code, the style-loader will insert the <style> tag into the <head> tag of the HTML file.

The production environment needs to compress and extract separate CSS files, so the style-loader is not used. Instead, the csS-minimizer-webpack-plugin should be installed to compress CSS code. Install the mini-CSS-extract-plugin for CSS code extraction

Note: Optimize – CSS-assets-webpack-plugin for CSS compression In Plugin Github home page also clearly indicates that after Webpack5, the use of official Webpack csS-Minimizer-webpack-plugin is preferred

yarn add -D css-minimizer-webpack-plugin mini-css-extract-plugin cssnano
Copy the code

Modify the webpack.prod.config.js file

const { CleanWebpackPlugin } = require('clean-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') module.exports = { mode: 'production', module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: "../" } }, 'css-loader', 'postcss-loader', ] }, { test: /\.less$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: "../"}}, 'css-loader', 'postcss-loader', 'less-loader']},]}, optimization: {// Unlock code compression: true, minimizer: [ new CssMinimizerPlugin() ] }, plugins: [ new HtmlWebpackPlugin({ title: 'W5V3', filename: 'index.html', template: // public/index.html', favicon: './public/favicon.ico', minify: {// collapseWhitespace: True, minifyCSS: true // Compress inline CSS}, cache: true}), // Extract separate CSS file new MiniCssExtractPlugin({filename: 'css/[name]-[contenthash:6].css' }), new CleanWebpackPlugin() ] }Copy the code

Note: PurifyCSS-Webpack is not working because the Compiler. Plugin API is removed from Webpack5

Configuration postcss

For CSS resources, postCSS-Loader is used for development and production configuration. We hope to standardize the processing of CSS code through PostCSS, where we need to use the autoprefixer plug-in

yarn add -D autoprefixer
Copy the code

Create the.postcsrc. Js file in the root directory of the project and write the following content

module.exports = {
  plugins: [
    require('autoprefixer')({
      overrideBrowserslist: ['last 2 versions', '>1%']
    }),
  ]
}
Copy the code

Configuring JS code tree shaking with JS code compression

So far, the production environment’s WebPack configuration has the following capabilities:

  1. HTML file compression
  2. CSS and Less resource conversion, normalization, tree shaking, extracting individual files, code compression

Also missing is the compression of JS files. Install terser-webpack-plugin for JS code compression

yarn add -D terser-webpack-plugin
Copy the code

Modify the optimization item in webpack.prod.config.js

// webpack.prod.config.js const TerserWebpackPlugin = require('terser-webpack-plugin') ...... Optimization: {+ usedExports: true, // Open code compression minimizer: true, minimizer: [ + new TerserWebpackPlugin() new CssMinimizerPlugin() ] },Copy the code

usedExports: True, tree shaking is enabled. In order to avoid removing.less and.css files from tree shaking, you need to modify package.json file and add sideEffects

"sideEffects": [
  "*.less",
  "*.css"
],
Copy the code

Identify.vue files

Install dependencies

yarn add vue@next
yarn add -D vue-loader@next @vue/compiler-sfc
Copy the code

Modify the webpack. Base. Config. Js

const { VueLoaderPlugin } = require('vue-loader/dist/index');

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          'vue-loader'
        ]
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ]
}
Copy the code

Create a new app. vue file in the SRC folder

// App.vue <template> <div> <h1>webpack5+Vue3</h1> <p>{{name}}</p> </div> </template> <script lang="ts"> import { defineComponent, ref } from "vue"; Export default defineComponent({setup() {const name = ref(" Parse Vue file "); return { name, }; }}); </script>Copy the code

Modify the main.js file

// main.js
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#app')
Copy the code

Rem layout adaptation

Install dependencies

yarn add amfe-flexible
yarn add -D postcss-pxtorem
Copy the code

Modify the.postcsrc. Js file

// .postcssrc.js module.exports = { plugins:[ require('autoprefixer')({ overrideBrowserslist: ['last 2 versions', '>1%'] }), + require('postcss-pxtorem')({ + rootValue: // selectorBlackList: ['vant'] // The selector to ignore and keep as px. ['*'], // Can be changed from px to rem property +}),],}Copy the code

Introduce amFE-flexible in the first line at the top of the project entry file SRC /main.js

// src/main.js import 'amfe-flexible'; / /...Copy the code

To optimize the

Packing Friendly Tips

Webpack-dev-server4 is currently in beta, and the clientLogLevel property can be exported to the administration console during development, but this is not yet available.

Use the friendly-errors-webpack-plugin with stats: ‘errors-warnings’ to remove unnecessary output from the packaging console each time and output only errors and warnings. Webapck-dev-server3 uses the overlay attribute to pass error messages to the browser screen, but overlays are not supported in version 4, where node-Notifier first casts error messages to the browser.

Install dependencies

yarn add -D friendly-errors-webpack-plugin node-notifier
Copy the code

Modify the webpack. Base. Config. Js

// webpack.base.config.js const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const notifier = require('node-notifier') // ...... plugins: [ new VueLoaderPlugin(), + new FriendlyErrorsPlugin({ + onErrors: (severity, errors) => {+ notifier. Notify ({+ title: 'webpack failed to compile ~', + message: `${severity} ${errors[0].name}`, + subtitle: errors[0].file || '', + icon, + }) + }, + }) ], + stats: 'errors-warnings'Copy the code

Specification of project code and catalog

Configuration eslint

You don’t need to configure ESLint in your project because the VSCode editor provides the ESLint plugin. If you download the plugin, you can automatically check vsCode configuration files. Vscode is an editor, and plugins are just tools to help you edit code, whereas vscode eslint plugins are tools to help you write code, and they will only prompt you and have no effect on your program.

Webpack Static module Bundler, which will stop compiling if you don’t follow the esLint specification when you use it, will prompt you when you open your browser and check console, and will actually have an impact on your application.

Eslint-webpack-plugin (eslint-webpack-plugin is officially recommended instead of eslint-loader, eslint-loader will be deprecated)

yarn add -D eslint eslint-plugin-vue eslint-webpack-plugin
Copy the code

Modify the webpack. Dev. Config. Js

// webpack.base.config.js
const ESLintPlugin = require('eslint-webpack-plugin')

// ......
plugins: [
    new VueLoaderPlugin(),
+   new ESLintPlugin(),
]
Copy the code

Create the.eslintrc.js file in the root directory

Module. exports = {extends: ['plugin:vue/vue3-recommended', // 'plugin:vue/recommended' // Vue2 uses this configuration], "env": {"browser": true, // "node": true //}, // !!!! If the alias is not used, do not configure !!!!! settings: { 'import/resolver': { webpack: { config: 'webpack.config.js' } } }, rules: { // override/add rules settings here, such as: // 'vue/no-unused-vars': 'error' } }Copy the code

Note: If an alias is configured in webpack and an alias is used when importing, an additional installation of eslint-import-resolver-webpack is required

Create a.eslintignore file

build
dist
node_modules
public
src/assets
src/icons
Copy the code

EditorConfig

The root directory creates the.editorConfig file

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
Copy the code

Standardize the project directory structure

GitHub address of the project

Refer to this article Webpack5 new feature service implementation