preface

Some time ago, due to work needs and personal interests, I learned some webpack. After consulting many documents, I found that the update and iteration of each plug-in version is fast, and some errors will be reported during installation. Therefore, I want to write the latest version of Webpack for everyone to learn

Introduction to the

Webpack is a static module packaging tool for modern JavaScript applications. When WebPack works with an application, it internally builds a dependency graph that maps to each module required for the project and generates one or more bundles.

Webpack document

​​

The body of the

1. Initialize the project

Create a directory and initialize NPM

npm init
Copy the code

1.1 Installing the WebPack Package (It is recommended to install the three Packages at the same time)

npm i -D webpack webpack-cli webpack-dev-server
Copy the code
  • NPM I -d stands for NPM install –save-dev
  • NPM i-s stands for NPM install –save

1.2 configuration webpack. Config. Js

Create a new webpack.config.js to implement more custom configurations

webpack.config.js

const path = require('path')

module.export  ={
    entry:path.reslove(`__dirname,'./src/index.js'`) // Import file
    output: {// Merge all dependent modules into a bundle.js file
        filename:'bundle.js'.// The packaged file name
        path:path.resolve(__dirname,'./build') // The packaged directory}}Copy the code

1.3 Installing plug-ins

NPM i-d html-webpack-plugin uses html-webpack-plugin to create HTML pages and import the packed JS file into HTML. NPM i-d html-webpack-plugin uses this plugin to import the corresponding JS file// Create a new build folder public and create an index. HTML
Copy the code
Clean-webpack-plugin NPM I -d clean-webpack-plugin deletes all files from dist folderCopy the code

1.4 the introduction of CSS

We also need some loaders to parse our CSS when we import it

NPM i-d style-loader CSS -loader converts CSS modules into JS modules. NPM i-d less less-loader can be used to append CSS -loader modules to the page using the style tagCopy the code

The configuration file is as follows

// webpack.config.js

module.exports ={
/ /... Omit other configurations
module: {rules: [{// Use the re to match the CSS file to be converted with the loader
                test: /\.css$/,
                exclude: path.resolve(__dirname, 'node_modules'),
                use: [ 'style-loader'.'css-loader'.'postcss-loader'] // Remember to parse from right to left
            },
            {
                test:/.less$/, 
                use:['style-loader'.'css-loader'.'less-loader'] // Parse principles from right to left}}}]Copy the code

1.5 Adding a Browser prefix to the CSS

NPM I -d postcss-loader autoprefixer // Add this plug-in for compatibility with different browsersCopy the code

You need to create the postcss.config.js file in the root directory

Module. exports = {plugins: [require('autoprefixer')]}Copy the code

1.6 Extract CSS styles from JS files into separate CSS files

npm i -D mini-css-extract-plugin

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
        / /... Omit other configurations
        module: {   
        rules: [{test: /.less$/,   
        use: [   MiniCssExtractPlugin.loader,   
        'css-loader'.'less-loader']],}},plugins: [
        new MiniCssExtractPlugin({
        filename: "[name].[hash].css".chunkFilename: "[id].css",}})]// MiniCssExtractPlugin needs to be configured together


Copy the code

1.7 Babel escapes JS files

Note the relationship between versions

Es6/7/8 to ES5 code

Installing a plug-in

npm i -D babel-loader @babel/preset-env @babel/core @babel/plugin-proposal-decorators

npm i -D @babel/plugin-transform-arrow-functions @babel/plugin-transform-runtime
Copy the code
rules:[
            {
                test: /\.m? js$/,
                exclude: /node_modules/,
                use: {
                  loader: 'babel-loader'.options: {
                    // Cache to speed up babel-loader compilation
                    cacheDirectory: true.// A collection of plugins, including processing arrow functions, etc. Do you need to configure plugins after configuration? Back to see
                    Conclusion: No other plugins need to be configured
                    // useBuiltIns corejs resolves the issue that new es6 apis cannot compile (only syntax, such as arrow functions)
                    presets: [
                      // ['@babel/preset-env', { targets: 'defaults' }]
                      ['@babel/preset-env', { useBuiltIns: 'usage'.corejs: 3.targets: 'defaults'}]],plugins: [
                      // Compile the arrow function
                      '@babel/plugin-transform-arrow-functions'.// Compile the decorator
                      ['@babel/plugin-proposal-decorators', { legacy: true}].// Compile classes, loose true defines attributes using assignment, false uses Object.defineProperty, which is the default
                      ['@babel/plugin-proposal-class-properties', { loose: false}]}}},]Copy the code

1.8 Package picture fonts, etc

In Webpack5, SVG is an inline asset with a built-in loader

[{test:/\.svg$/,
                type:'asset/inline'.generator: {filename:"icons/[name]--[hash].[ext]"}}, {test:/\.(png|jpe? g|gif)(\? . *)? $/,
                type:'asset/resource'.generator: {
                  filename: 'imgs/[name]--[hash].[ext]'}}, {test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/,
                type: 'asset/resource'.generator: {
                  filename: 'media/[name]--[hash].[ext]'}}, {test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/,
                type: 'asset/resource'.generator: {
                  filename: 'fonts/[name]--[hash].[ext]'}}]Copy the code

2. Set up the VUE development environment

The following configurations are required to set up a VUE development environment with the above dependencies

2.1 Parsing vUE Files

NPM installs plug-ins

npm i -D vue-loader vue-template-compiler vue-style-loader

npm i -S vue
Copy the code

Vue-loader parses. Vue files

Vue-template-compiler is used to compile templates

For details about the configuration, see the following section

2.2 Configuring webpack-dev-server for hot Update

devServer:{
      port:3000.hot:trueTo open:true.contentBase:'./build'
    },
Copy the code

2.3 Configuring packaging Commands

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack --watch --config webpack.config.js"."dev": "webpack server "
  },
Copy the code

2.3.1 Creating index.js under SRC

import Vue from 'vue'
import App from './App.vue'
new Vue({
  render: h= > h(App)
}).$mount('#app')

Copy the code

2.3.2 new App. Vue

<template>
  <div class="style" id="app">
    {{ str }}

    <canvas id="myCanvas" width="600" height="400" ref="can"></canvas>
  </div>
</template>

<script>
console.log("Load");
export default {
    name:'App',
    data (){
    return{
        str:'hello'
          }
    },
    mounted (){
    console.log(Math.trunc(12.1))},method:{}
}
</script>
Copy the code

2.3.3 index. The new HTML

<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">
    <title>Document</title>
</head>

<body>
    <div id='app'>
       
    </div>
</body>

</html>
Copy the code

2.3.4 Complete Configuration

2.4 Distinguish between development environment and production environment

When applied to projects, the relationship between development environment and production environment needs to be distinguished

const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin') // Import the corresponding file
const webpack = require('webpack')
const { VueLoaderPlugin } = require('vue-loader')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
// Extract CSS styles from the JS file into a separate CSS file
// const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// The default path to place the entry prepath in this field
    // context:path.resolve(__dirname,'src'),
    entry:path.resolve(__dirname,'./src/index.js'),
    output: {// Merge all dependent modules into a bundle.js file
        filename:'[name].[hash:8].js'.path:path.resolve(__dirname,'./build')},devServer: {
        contentBase: path.join(__dirname, './build'),
        compress: true.port: 4000.hot: true.open: true
      },
      devtool: 'source-map'.module: {rules:[
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            // css-loader loads CSS into javascript; Style-loader is used to enable javascript to recognize CSS and mount CSS to style
            {
                // Use the re to match the CSS file to be converted with the loader
                test: /\.css$/,
                exclude: path.resolve(__dirname, 'node_modules'),
                use: [ 'style-loader'.'css-loader'.'postcss-loader'] {},test: /\.m? js$/,
                exclude: /node_modules/,
                use: {
                  loader: 'babel-loader'.options: {
                    // Cache to speed up babel-loader compilation
                    cacheDirectory: true.// A collection of plugins, including processing arrow functions, etc. Do you need to configure plugins after configuration? Back to see
                    Conclusion: No other plugins need to be configured
                    // useBuiltIns corejs resolves the issue that new es6 apis cannot compile (only syntax, such as arrow functions)
                    presets: [
                      // ['@babel/preset-env', { targets: 'defaults' }]
                      ['@babel/preset-env', { useBuiltIns: 'usage'.corejs: 3.targets: 'defaults'}]],plugins: [
                      // Compile the arrow function
                      '@babel/plugin-transform-arrow-functions'.// Compile the decorator
                      ['@babel/plugin-proposal-decorators', { legacy: true}].// Compile classes, loose true defines attributes using assignment, false uses Object.defineProperty, which is the default
                      ['@babel/plugin-proposal-class-properties', { loose: false}]}}}, {test:/\.svg$/,
                type:'asset/inline'.generator: {filename:"icons/[name]--[hash].[ext]"}}, {test:/\.(png|jpe? g|gif)(\? . *)? $/,
                type:'asset/resource'.generator: {
                  filename: 'imgs/[name]--[hash].[ext]'}}, {test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/,
                type: 'asset/resource'.generator: {
                  filename: 'media/[name]--[hash].[ext]'}}, {test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/,
                type: 'asset/resource'.generator: {
                  filename: 'fonts/[name]--[hash].[ext]'}}},plugins: [new htmlWebpackPlugin({
            filename:'index.html'.template:path.resolve(__dirname,'./src/index.ejs'),
            minify: {
              collapseWhitespace: true.removeAttributeQuotes: true.removeComments: true.minifyJS: true.minifyCSS: true}}),new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new VueLoaderPlugin()
    ]
}
Copy the code

Create two new folders

  • webpack.dev.jsDevelopment environment Usage
  • webpack.prod.jsUse in production environment
  • webpack.config.jsCommon configuration

2.4.1 Development Environment

  1. No need to compress the code
  2. Hot update required
  3. CSS does not need to be extracted into a CSS file
  4. Devtool use source – the map
  5. .

2.4.2 Production Environment

  1. The compression code
  2. Hot updates are not required
  3. Extract CSS and compress CSS files
  4. sourceMap
  5. Clear the contents of the last build before building
  6. .

2.4.3 Dependencies required for Installation

npm i optimize-css-assets-webpack-plugin mini-css-extract-plugin clean-webpack-plugin webpack-merge copy-webpack-plugin -D
Copy the code
  • webpack-mergeMerge configuration
  • copy-webpack-pluginCopying static Resources
  • optimize-css-assets-webpack-pluginCompress CSS
  • uglifyjs-webpack-pluginCompression js

Development Environment Configuration

// Development environment
const webpackConfig = require('./webpack.config.js')
const WebpackMerge = require('webpack-merge')
const webpack = require('webpack')

// webpack-merge provides a function that concatenates arrays and merges objects that create new objects. If it encounters functions, it executes them, runs the result through the algorithm, and again wraps the returned value in the function.

module.exports = WebpackMerge.merge(webpackConfig,{
mode:'development'.devtool:'source-map'.devServer: {port:3000.hot:true.contentBase:'./build' 
}, 
plugins: [new webpack.HotModuleReplacementPlugin()] 
}) 
Copy the code

Production Environment Configuration

const path = require('path')
const webpackConfig = require('./webpack.config.js')
const WebpackMerge = require('webpack-merge')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') / / compress CSS
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')       Js / / compression
module.exports = WebpackMerge.merge(webpackConfig,{
    mode:'production'.devtool:'cheap-module-source-map'.plugins: [new CopyWebpackPlugin({
        patterns: [{from:path.resolve(__dirname,'src'),
        to:path.resolve(__dirname,'build')})}]],optimization: {minimizer: [new UglifyJsPlugin({Js / / compression
          cache:true.parallel:true.sourceMap:true
      }),
      new OptimizeCssAssetsPlugin({})
      ],
      splitChunks: {chunks:'all'.cacheGroups: {libs: {
            name: "chunk-libs".test: /[\\/]node_modules[\\/]/,
            priority: 10.chunks: "initial" // Package only the third party that you originally relied on}}}}})Copy the code

Modify package.json configuration

{
  "name": "webpack-new"."version": "1.0.0"."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack --watch --config webpack.prod.js"."dev": "webpack-dev-server --config webpack.dev.js"
  },
  "author": ""."license": "ISC"."keywords": []."description": ""."devDependencies": {
    "@babel/core": "^ 7.14.6"."@babel/plugin-proposal-decorators": "^ 7.14.5"."@babel/plugin-transform-arrow-functions": "^ 7.14.5"."@babel/plugin-transform-runtime": "^ 7.14.5"."@babel/preset-env": "^ 7.14.7"."@intervolga/optimize-cssnano-plugin": "^ 1.0.6"."autoprefixer": "^ 10.2.6"."babel-loader": "^ 8.2.2"."clean-webpack-plugin": "^ 3.0.0"."copy-webpack-plugin": "^ 9.0.1"."css-loader": "^ 5.2.6." "."html-webpack-plugin": "^ 5.3.2." "."mini-css-extract-plugin": "^ 1.6.2"."optimize-css-assets-webpack-plugin": "^ the 6.0.1." "."postcss-loader": "^ 6.1.0"."style-loader": "^ 2.0.0." "."uglifyjs-webpack-plugin": "^ 2.2.0." "."vue": "^ 2.6.14"."vue-loader": "^ 15.9.7"."vue-router": "^ 3.5.2." "."vue-template-compiler": "^ 2.6.14"."vuex": "^ 3.6.2." "."webpack": "^ 5.40.0"."webpack-cli": "^" 3.3.12."webpack-dev-server": "^ 3.11.2"."webpack-merge": "^ 5.8.0"}}Copy the code

Gitee address

discussion

After reading the article, students can build it, the process of building will meet many pits, students can leave a message below. Want to get more front-end information, pay attention to the public number: front-end small du backstage message pull you into the front and back end communication group