banner
cos

cos

愿热情永存,愿热爱不灭,愿生活无憾
github
tg_channel
bilibili

Youth Training Camp | "Building a Webpack Knowledge System"

Key Content of This Lesson#

  • Understand the concept, tools, and goals of "engineering" in frontend development
  • A team should have a few members familiar with Webpack, which can become a core competitive advantage for individuals
  • A necessary path for advanced frontend development

Course Objectives:

  • Understand the basic usage of Webpack
  • Establish a knowledge system by introducing Webpack's features, Loader, and Plugin component design
  • Not cover every detail, but introduce all aspects of Webpack
  • Not delve into the source code, but explain the underlying implementation principles

What is Webpack#

What constitutes a frontend project? — Resources

image.png

In the old days, these resources were managed manually, but there were several significant drawbacks that greatly affected development efficiency:

  • Manual dependencies, for example, if there are 50 JS files... The operation process is cumbersome
  • When there are dependencies between code files, they must be written strictly in dependency order
  • Consistency between development and production environments makes it difficult to integrate new TS or JS features
  • It is relatively difficult to integrate tools like Less, Sass, etc.
  • Inconsistent resource management models for JS, images, and CSS

Later, many frontend engineering tools emerged, especially Webpack.

image.png

The essence of the web is a frontend resource compilation and packaging tool.

  • Multiple resource files are packaged into a single Bundle
  • Supports
    • Babel, Eslint, TS, CoffeeScript, Less, Sass
  • Supports modular processing of CSS, images, and other resource files
  • Supports HMR + development server
  • Supports continuous listening and continuous building
  • Supports code splitting
  • Supports Tree-shaking
  • Supports Sourcemap
  • ...

Core Process of Webpack Packaging#

Example#

  1. Install (make sure to open the command line with administrator privileges)

    npm i -D webpack webpack-cli
    

    image.png

  2. Edit the configuration file webpack.config.js

    module.exports = {
        entry: 'main.js',   // Define the entry file for the current project
        output: {   // Define the output file for the current project
            filename: "[name].js",
            path: path.join(__dirname, "./dist"),
        },
        module: {// Define some loader-related content, as will be seen below
            rules: [{
                test: /\.less$/i,
                use: ['style-loader', 'css-loader', 'less-loader']
            }]
        }
    }
    
  3. Execute the compile command

    npx webpack
    

Steps#

Entry => Dependencies Lookup => Transform => Bundle => Output

A highly simplified version:

image.png

  1. Start the compilation from the entry file in entry
  2. Dependency resolution: Find the required resources based on require or import statements
  3. According to the module configuration, call resource transformers to compile non-JS resources into JS content until all resources are processed
  4. Resource merging and packaging: Merge the transpiled resource content into a JS file that can be run directly in the browser

Modularity + Consistency

  • Multiple file resources are merged into one, reducing the number of HTTP requests
  • Supports modular development
  • Supports advanced JS features
  • Supports TypeScript, CoffeeScript dialects
  • Unifies the processing model for images, CSS, fonts, and other resources
  • Etc...

Key Configuration Items (How to Use?)#

The usage of Webpack is primarily centered around configuration, which can be roughly divided into two categories:

  • Process-related: Configuration items that affect certain or several stages of the process and directly influence the packaging effect
  • Tool-related: Configuration items that provide more engineering capabilities outside the main process

ps: The official documentation is indeed hard to understand ()

Configuration overview:

image.png

Based on usage frequency, the main configuration items are as follows:

  • entry/output — program input and output, necessary

  • module/plugins

    • For example, if my project needs to load less files, I need to import the following loaders, etc.

      image.png

  • mode

  • watch/devServer/devtool

Official Webpack Configuration Documentation

Using Webpack to Handle CSS/Less, etc.#

  1. Install Loaders

    npm add -D css-loader style-loader
    
  2. Add module to handle CSS files

image.png

Thought Questions#

  • What is the role of Loaders? Why do we need to use css-loader and style-loader here?
  • Compared to the old days of maintaining CSS in HTML files, what are the advantages and disadvantages of this method?
  • Have you encountered CSS pre-compilation frameworks like Less, Sass, or Stylus? How to integrate these tools into Webpack?
    • Answer: I have encountered Less.

Reference Materials:

Using Webpack with Babel#

  1. Install dependencies

    npm -D @babel/core @babel/preset-env babel-loader
    
  2. Declare entry entry & output output

  3. Add module to handle JS files

    module:{
        rules:[
        {
            test:/\.js?$/,
            use:[{
                loader: 'babel-loader',
                options: {
                    presets: [
                        [
                            '@babel/preset-env'
                        ]
                    ]
                }
            }]
        }
    ]
    }
    
  4. Execute npx webpack

Thought Questions#

  • What specific functions does Babel provide?
  • What problems do Babel and Webpack solve respectively? How do they work together?

Reference Materials:

Using Webpack to Generate HTML#

  1. Install dependencies

    npm i -D html-webpack-plugin
    
  2. Configuration

const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
   entry: "./src/index",
   output: {
       filename: "[name].js",
       path: path.join(__dirname, "./dist"),
   },
   plugins: [new HtmlWebpackPlugin()]
};
  1. Execute npx webpack

Thought Questions#

  • Compared to manually maintaining HTML content, what are the advantages and disadvantages of this automated generation method?

Reference Materials:

Using Webpack — HMR#

Hot Module Replacement — modules are hot-replaced (the code written will be updated immediately in the browser~)

  1. Enable HMR

    module.exports={
    	// ...
    	devServer: {
            hot:true; // Required
        }
    };
    
  2. Start webpack

The principle can be referenced: Webpack Principles Series Ten: Full Analysis of HMR Principles (qq.com)

Using Webpack — Tree-Shaking#

Tree-Shaking - used to remove Dead Code

Dead Code

  • Code that is not used and unreachable
  • The execution result of the code will not be used
  • Code that is read-only and not writable

Tree-Shaking

  • Modules are exported but not used by other modules

Steps to enable?

  • mode: "production"
  • optimization: {usedExports: true}
  module.exports = {
  	entry: "./src/index",
  	mode: "production",
  	devtool: false,
  	optimization: {
  		usedExports: true, 
  	},
  };

ps: This is particularly effective for utility libraries like Lodash, which can greatly reduce the size of the output.

Other Tools#

  • Caching
  • Sourcemap (mentioned in previous courses)
  • Performance monitoring
  • Logging
  • Code compression
  • Code splitting
  • ...

Thought Questions#

  • Besides the above-mentioned content, what other configurations can be classified as "process-related"?
  • What are the specific functions of tool-related configurations? Including devtool/cache/stat, etc.

Understanding Loaders#

The core function of Loaders: Convert non-JS resources into JS resources

  1. Install Loaders

    npm add -D css-loader style-loader less-loader
    
  2. Add module to handle Less files

module.exports = { 
    module: {
        rules: [
            {
                test: /\.less$/i,
                use:[
                    "style-loader",
                    "css-loader",
                    "less-loader",
                ],
            },
        ],
    },
};

Understanding Loaders: Chaining#

  • less-loader: Implements the conversion from less => css
  • css-loader: Implements the conversion from css => js, wrapping CSS into content like module.exports = "${css}", which conforms to JavaScript syntax
  • style-loader: Wraps the CSS module in a require statement and calls functions like injectStyle at runtime to inject the content into the page's style tag

image.png

Understanding Loaders: Other Features#

Characteristics

image.png

module.exports = function(source, sourceMap?, data?) {
	// source is the input for the loader
	// It could be file content or the result of the previous loader
	return source;
};

Common Loaders#

From a usage perspective, it is recommended to master the functions and configuration methods of these common Loaders.

image.png

Thought Questions#

  • What is the input for a Loader? What is the expected output?
  • What does the chaining of Loaders mean? How to chain multiple Loaders together?
  • How to handle asynchronous scenarios in Loaders? How to throw an exception?

Understanding Plugins#

What is a Plugin#

  • Many well-known tools, such as:
    • VS Code, Web Storm, Chrome, Firefox
    • Babel, Webpack, Rollup, Eslint
    • Vue, Redux, Quill, Axios
  • And so on, have designed a so-called "plugin" architecture. Why?

Plugins can enhance the extensibility of the entire application.

Assuming an application has no plugins, the entire process becomes particularly complex, then:

  • Newcomers need to understand the details of the entire process, high onboarding cost
  • The cost of feature iteration is high, one change affects everything
  • Functionality becomes rigid, lacking growth potential as an open-source project

High mental cost => Low maintainability => Weak vitality
The essence of the plugin architecture: Open for extension, closed for modification, which is essentially the Open/Closed Principle.

image.png

In fact, many of Webpack's functionalities are also implemented based on plugins.

image.png

How to Write a Plugin#

First: Plugins revolve around hooks.

class SomePlugin {
    apply(compiler) {
    	compiler.hooks.thisCompilation.tap('SomePlugin', (compilation) => {
    	})
    }
}

Hooks#

  1. Timing: Specific nodes in the compilation process where Webpack will notify plugins about what is happening at that moment;

  2. Context: The context information is passed as parameters through the callback mechanism provided by tapable;

  3. Interaction: The context parameter object contains many interfaces with side effects, and plugins can use these interfaces to change things.

    image.png

    Timing: compiler.hooks.compilation

    Parameters: compilation, etc.

    Interaction: dependencyFactories.set

Thought Questions#

  • What are the differences between Loaders and Plugins?
  • What is the role of "hooks"? How to listen to hook functions?

Reference Materials:

How to Learn Webpack#

Beginner Level: Learn to Apply Flexibly#

  • Understand the packaging process
  • Master the usage of common configuration items, Loaders, and Plugins, and be able to flexibly build a Webpack environment that integrates Vue, React, Babel, Eslint, Less, Sass, image processing, and other tools
  • Master the usage of common scaffolding tools, such as: Vue-cli, create-react-app, @angular/cli

image.png

Advanced Level: Learn to Extend Webpack#

  • Understand the Loader and Plugin mechanisms, and be able to develop Webpack components independently
  • Understand common performance optimization techniques and be able to apply them to solve practical problems
  • Understand the concepts of frontend engineering and the current ecosystem

Master Level: Source-level Understanding of Webpack Packaging and Compilation Principles#

  • Read the source code, understand the principles of Webpack compilation and packaging, and even be able to participate in co-construction.

Summary and Reflections#

This lesson detailed the role of Webpack, its configuration structure, and key configuration items. It also discussed the chaining of loaders, the implementation principles of plugins, and some other features. It is evident that the teacher's research on Webpack is very thorough and detailed, with direct debugging into the loader internals during the class to help us understand. The teacher also summarized the Webpack knowledge system: Webpack 5 Knowledge System - GitMind.

Q&A#

Q: What level of understanding is required for interviews?

A: There are many online interviews primarily focused on three themes:

  • What is the role of Loaders? How to write a loader? What are common loaders?
    • Common loaders: css-loader, style-loader, vue-loader, file-loader, eslint-loader, babel-loader, etc.
  • What is the use of plugins? How to write plugins? What are the compilation principles?
  • What do Bundle, chunk, and module mean?

Some resources: In-depth Understanding of Webpack

Most of the content referenced in this article comes from Teacher Fan Wenjie’s class. Feel free to follow the teacher's public account: Tecvan.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.