Basic configuration of webpack5+vue3+vant

Some basic knowledge points of webpack

Core concept

  • Entry: an entry that performs the first step of the build
  • Module: it will recursively find out all dependent modules from the configured Entry
  • Chunk: used for code splitting and merging
  • Loader: module converter
  • Plugin: an extension that injects extension logic at a specific time to change the build result
  • Output: output results

webpack is a tool for packaging jacascript. It can't recognize other files, so it needs to configure loader for recognition

Foreword project directory structure

├─build
│  ├─webpack.base.conf.js    //Operational profiles are available in both development and production environments
│  ├─webpack.dev.conf.js     //Development environment profile
│  ├─webpack.prod.conf.js    //Production environment profile
│  ├─webpack.rules.conf.js   //Module matching rules
├─node_modules               //Dependent file
├─public                     //Static file storage location
|  |-index.html             //Project template file
└─src                 
|  ├─plugins
|  ├─router
|  ├─store
|  ├─views
|  |-App.vue
|  |-main.ts
|  |-shims-vue.d.ts
|-.env.dev               //Environmental documents
|-.env.test
|-.env.prod
|-.gitigore
|-babel.config.js        //bable profile
|-package.json           
|-postcss.config.js     //Adaptation rules
|-tsconfig.json     

1. Step 1: initialize the project

yarn init -y Initialize project  //-y yes yes yes one click initialization

2. Step 2: install the webpack three piece set

// Installing the webpack Three Piece Kit
yarn add webpack webpack-cli webpack-dev-server -D  
// -D is equivalent to the dependency of -- save dev development environment
// -S is equivalent to the dependency of -- save production environment

//use http://localhost:8080/webpack -Dev server / can access the files generated in memory by the webpack dev server command

3. Create configuration files by function

├─build
│  ├─webpack.base.conf.js   //Public configuration
│  ├─webpack.dev.conf.js    //mode is configured for development
│  ├─webpack.prod.conf.js   //mode is configured for production
│  ├─webpack.rules.conf.js  //loader configuration
3.1 create src folder and create main.js file in it
3.2 writing entry path and output path
//webpack.base.conf.js
const path = require("path")

module.exports = function (proMode) {
    return {
        // JavaScript execution entry file
        entry: path.resolve(__dirname, "../src/main.ts"),
        output: {
             // The output files are placed in the dist directory
            path: path.resolve(__dirname, "../dist"),
            // Merge all dependent modules and output them to a bundle.js file
            filename: "./js/[name].[chunkhash].js",
            // publicPath: ". /", / / used in production environment
            clean: true
        },
    }
}

4 create environment files

.env.dev
.env.test
.env.prod
4.1 content of writing environment
//.env.dev
NODE_ENV="development"
VUE_APP_BASE_API="/api"
VUE_APP_API_USER="/user"
VUE_APP_SHOWCONSOLE=true
4.2 configuring environment variables
//Dotenv is a zero dependency module that loads variables in environment variables from the. env file into process.env
// Installing dotenv
yarn add dotenv -D
yarn add cross-env -D

//webpack.base.conf.js
const webpack = require("webpack")
const envMode = process.env.envMode
require("dotenv").config({
    path: `.env.${envMode}`
})
const prefixRE = /^VUE_APP_/
let env = {}
for (const key in process.env) {
    if (key == "NODE_ENV" || key == "BASE_URL" || prefixRE.test(key)) {
        env[key] = JSON.stringify(process.env[key])
    }
}

module.exports = function (proMode) {
    return {
        
        plugins: [
            new webpack.DefinePlugin({ // Define environment and variables
                'process.env': {
                    ...env
                }
            }),

        ],
    }
}
4.3 modify package.json startup command
"scripts": {
"dev": "cross-env envMode=dev webpack serve --config ./build/webpack.dev.conf.js  --color",
"build": "cross-env envMode=prod webpack --config build/webpack.prod.conf.js  --color",
"build:test": "cross-env envMode=test webpack --config build/webpack.prod.conf.js  --color"
},
  • Cross env: run scripts that set up and use environment variables across platforms
  • – config: which configuration file to use
  • – color: turns on the console color

5 es6=>es5

//Installing babel
yarn add @babel/core @babel/preset-env babel-loader -D
yarn add core-js -S
5.1 matching js for conversion
//webpack.rules.conf.js
module.exports = function (proMode) {
    return [{
            test: /\.(t|j)s$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader",
                options: {
                    cacheDirectory: true
                }
            }
        },
    ]
}
5.2 install TypeScript and convert using babel
//Install ts
yarn add typescript -D
// Parsing babel pre for typescript
yarn add @babel/preset-typescript -D
//polyfill arrow function
yarn add @babel/plugin-transform-runtime -D
//Support the writing of ts class
yarn add @babel/plugin-proposal-class-properties -D
//Support three-point expansion
yarn add @babel/plugin-proposal-object-rest-spread -D
yarn add @babel/runtime @babel/runtime-corejs3 core-js -S
5.3 create babel.config.js
const presets = [
    [
        "@babel/preset-env", {
            "useBuiltIns": "usage",
            "corejs": "3.19.1"
        }
    ],
    [
        '@babel/preset-typescript', // Reference Typescript plugin
        {
            allExtensions: true, // All file extensions are supported, otherwise using ts in vue file will report an error
        },
    ],
]
const plugins = [
    //Introducing vant components on demand
    [
        "import",
        {
            "libraryName": "vant",
            "libraryDirectory": "es",
            "style": true
        }, "vant"
    ],
    [
        '@babel/plugin-transform-runtime',
        {
            corejs: 3,
        },
    ],
    '@babel/proposal-class-properties',
    '@babel/proposal-object-rest-spread',

]
module.exports = {
    plugins,
    presets
}

6 automatically generate HTML files

yarn add html-webpack-plugin -D
6.1 HTML webpack plugin configuration
//webpack.base.conf.js
const HtmlWebpackPlugin = require("html-webpack-plugin");

const cdn = {
    dev: {
        css: [],
        js: []
    },
    prod: {
        css: [],
        js: [
            'https://lib.baomitu.com/vue/3.0.11/vue.runtime.global.prod.js',
            "https://lib.baomitu.com/vue-router/4.0.6/vue-router.global.prod.min.js",
            "https://lib.baomitu.com/vuex/4.0.0/vuex.global.prod.min.js"
        ]
    }
}

module.exports = function (proMode) {
    return {
        plugins: [
            new HtmlWebpackPlugin({
                template: path.resolve(__dirname, "../public/index.html"),  //Reference template location
                filename: "index.html",  //The generated html path is relative to output.path
                title: "webpack+vue3",
                minify: {

                    collapseWhitespace: true,  //Collapse blank
                    preserveLineBreaks: false,  
                    minifyCSS: true,	//Compress
                    minifyJS: true,
                    removeComments: false
                },
                files: proMode ? cdn.prod : cdn.dev  
            }),
        ],
    }
}
6.2 create a public folder and create index.html in it
// public/index.html
//The content in the < title > tag in the template needs to be changed to 
<%= htmlWebpackPlugin.options.title %>
    
    
//CDN introduction js
<% for (var i in
htmlWebpackPlugin.options.files&&htmlWebpackPlugin.options.files.js) { %>
<script src="<%= htmlWebpackPlugin.options.files.js[i] %>"></script>
<% } %>

7 add css support and less support

//css loader extracts the contents of. css    
//Style loader stores the content of. css according to the string in javascript. When the web page executes javascript, it dynamically inserts the style tag into the HTML HEAD tag through DOM operation

yarn add style-loader css-loader -D
yarn add less less-loader -D
yarn add autoprefixer postcss-loader -D 
7.1 using loader configuration
//webpack.rules.conf.js
module.exports = function (proMode) {
    return [
        {
            test: /\.less/,
            use: [MiniCssExtractPlugin.loader,
                "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            ident: "postcss",
                            plugin: () => {
                                require("postcss-preset-env")()
                            }
                        }
                    }
                }, "less-loader"
            ]
        },
        {
            test: /\.css$/,
            use: [
                // "style-loader",
                MiniCssExtractPlugin.loader,
                "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            ident: "postcss",
                            plugin: () => {
                                require("postcss-preset-env")()
                            }
                        }
                    }
                },
                // "less-loader"
            ]
        }
    ]
}

The loader executes from back to front

8. Configure alias alias and extension

//webpack.base.conf.js
resolve: {
    alias: {
        "@": path.resolve(__dirname, "../src")
    },
        
         //Extension writing
 		//Write all the extensions in the project, otherwise an error will be reported
        extensions: [".js", ".vue", ".ts"]
},                 

9. Clear the dist directory last built during packaging

//webpack.base.conf.js
output: {
            clean: true
        },

10 identify. vue files

yarn add vue-loader@next @vue/compiler-sfc -D
yarn add vue@next -S
  • vue loader: parse and transform the. vue file and extract the js/style/html template
  • @Vue / compiler SFC and Vue loader are called to convert the file content into webpack modular import form and AST abstract syntax tree
10.1 configuring matching rules
// webpack.rules.conf.js
rules: [
    {
        test: /\.vue$/,
        use: [
            'vue-loader'
        ]
    }
]

//webpack.base.conf.js
const { VueLoaderPlugin } = require('vue-loader/dist/index');
plugins: [
    new VueLoaderPlugin()
]

10.2 add App.vue
<template>
    <div id="app">
        <div id="nav" v-if="!$route.meta.hide">
            <router-link to="/">Home</router-link>|
            <router-link to="/about">About</router-link>
        </div>
        <keep-alive>
            <router-view
                v-if="$route.meta.keepAlive"
                class="router"
            ></router-view>
        </keep-alive>
        <router-view v-if="!$route.meta.keepAlive" class="router"></router-view>
    </div>
</template>
<script>
import { defineComponent, computed } from "vue";
import { useStore } from "vuex";
export default defineComponent({
    setup() {
        const store = useStore();
        return {
            title: computed(() => store.state.title),
        };
    },
});
</script>
<style lang="less">
// @import "style/_variables.scss";
#app {
    // font-family: "Avenir", Helvetica, Arial, sans-serif;
    // -webkit-font-smoothing: antialiased;
    // -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
}
#nav {
    padding: 20px 0;
    a {
        font-weight: bold;
        color: #2c3e50;
        font-size: 32px;
        &.router-link-exact-active {
            color: red;
        }
    }
}
h3 {
    font-size: 18px;
}
a {
}
</style>
10.3 modify main.ts
import { createApp } from 'vue' // Vue 3.x introduces vue
import App from './App.vue' // Introduce APP page setup
 
const app = createApp(App) // Initialize app through createApp
app.mount('#app ') / / mount the page to the root node
10.4 create vue type declaration file
 src/shims-vue.d.ts
declare module "*.vue" {
  import type { DefineComponent } from "vue";
  const component: DefineComponent<{}, {}, any>;
  export default component;
}
10.5. Vue documents always report errors and declare that the documents are not effective
//tsconfig.js
//If you add the path of the declaration file to include, you will not report an error

"types": ["./src/shims-vue.d.ts"],  

11. Install vue bucket

 yarn add vue-router@4 vuex@next axios -S

12. Integration Vant

yarn add vant@next -S

//On demand import
yarn add babel-plugin-import -D

// babel.config.js
const plugins = [
    ['import', {
        libraryName: 'vant',
        libraryDirectory: 'es',
        style: true
    }, 'vant']
]

//At the same time of scaffolding, we should distinguish between css files and less files 
//The vant component cannot be identified by using less loader, and an error will be reported

13. Identification picture

//webpack.conf.rules.js
module.exports = function (proMode) {
    return [
        {
            test: /\.(png|jpg|svg|gif)$/,
            type: "asset/resource",
            generator: {
                filename: "assets/[hash:8].[name][ext]"
            }
        },
    ]
}

optimization

1. Output the static file to the packaging directory
//When using the copy webpack plugin, the folder to be copied cannot be empty, otherwise an error will be reported

yarn add copy-webpack-plugin -D

//webpack.prod.conf.js
const copyWebpackPlugin = require("copy-webpack-plugin");
const webpackConfigProd = {
    mode: "production",
    plugins: [
        new copyWebpackPlugin({
            patterns: [{
                from: path.resolve(__dirname, "../public"),
                to: "./",
                globOptions: {
                    dot: true,
                    gitignore: true,
                    ignore: ["**/index.html"],
                }
            }]
        }),
    ],
}
2. Extract style file
yarn add mini-css-extract-plugin -D

//webpack.base.conf.js
const miniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = function (proMode) {
    return {
        plugins: [
            new miniCssExtractPlugin({
                filename: "./css/[name].[contenthash].css",
            }),
        ],
    }
}



//webpack.rules.conf.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = function (proMode) {
    return [
        {
            test: /\.less/,
            use: [MiniCssExtractPlugin.loader,
                "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            ident: "postcss",
                            plugin: () => {
                                require("postcss-preset-env")()
                            }
                        }
                    }
                }, "less-loader"
            ]
        },
        {
            test: /\.css$/,
            use: [
                // "style-loader",
                MiniCssExtractPlugin.loader,
                "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            ident: "postcss",
                            plugin: () => {
                                require("postcss-preset-env")()
                            }
                        }
                    }
                },
                // "less-loader"
            ]
        }
    ]
}
3. vw adaptation
yarn add postcss-loader postcss-px-to-viewport -D

//Create a new postcss.config.js file
const path = require("path")
module.exports = ({
    file
}) => {
    const designWidth = file.includes(path.join("node_modules", "vant")) ? 375 : 750;
    return {
        plugins: {
            autoprefixer: {
                overrideBrowserslist: [
                    "Android 4.1",
                    "iOS 7.1",
                    "Chrome > 31",
                    "ff > 31",
                    "ie >= 8"
                ]
            },
            "postcss-px-to-viewport": {
                unitToConvert: 'px', // The unit to be converted is "px" by default
                viewportWidth: designWidth, //  Viewport width of the design
                unitPrecision: 5, // Precision retained after unit conversion
                propList: ['*'], // List of attributes that can be converted to vw
                viewportUnit: 'vw', //  The viewport units you want to use
                fontViewportUnit: 'vw', // The viewport units used by the font
                selectorBlackList: ['.ignore', '.hairlines', '.ig-'], // CSS selectors that need to be ignored
                minPixelValue: 1, // The smallest conversion value. If it is 1, only values greater than 1 will be converted
                mediaQuery: false, // Does the unit in the media query need to be converted
                replace: true, // Whether to directly replace the attribute value without adding an alternate attribute
                include: undefined, // If include is set, only the matched files will be converted, for example, only the files under 'src/mobile' (include: /\/src\/mobile \ / /)
                landscape: false, // Add media query condition @ media (orientation: landscape) generated according to landscape width
                landscapeUnit: 'vw', // Units used when horizontal screen
                landscapeWidth: 568 // The width of the viewport used when the screen is horizontal
            }
        }
    }
}
4. Remove the console from the production environment
//webpack.prod.conf.js
const TerserPlugin = require('terser-webpack-plugin');
const webpackConfigProd = {
    mode: "production",
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                parallel: true,
                extractComments: false,
                terserOptions: {
                    compress: {
                        drop_console: true,
                        drop_debugger: true
                    }
                }
            }),

        ]
    }
}
5. Cache
//webpack.base.conf.js
module.exports = function (proMode) {
    return {
         cache: {
            type: "filesystem",
             buildDependencies: {
                 config: [__filename]
             }
         },
    }
}

Tags: Javascript Front-end Vue.js Webpack

Posted on Sat, 06 Nov 2021 07:48:11 -0400 by rbudj