Basic introduction to

introduce

Webpack is one of the most popular and active packaging tools, and a “soft skill” that senior programmers must master when interviewing. This paper mainly introduces the entrance and output of Webpack and the use of various loaders and plugins as well as the construction of development environment.

Webpack concept

Website definition

In essence, Webpack is a static Module bundler for modern JavaScript applications. When WebPack works with an application, it recursively builds a Dependency graph containing every module the application needs, and then packages all of those modules into one or more bundles.

  • First, WebPack is a packer of static modules, so called static modules, including scripts, style sheets, images, and so on.
  • When WebPack is packaged, it first iterates through all static resources and builds a dependency graph based on resource references.
  • Modules are then divided into one or more bundles.

The core concept

  • Entry: Indicates which module WebPack should use as a starting point for building its internal dependency graph
  • Output: Where do I export the bundles it creates
  • Loader: Enables Webpack to handle non-javascript files
  • Plugins: Used to perform a wider range of tasks

packaging

Imperative packing

/*webpack <entry> [<entry>] -o <output> * entry and output are corresponding to the entry and input */ webpack index.js -o dist/bundle.jsCopy the code

But only for simple projects

Configuration file packaging

webpack [--config webpack.config.js]
Copy the code

The default name of the configuration file is webpack.config.js, but in the basic project configuration of Vue, it is divided into three configuration files based on the project environment. With the configuration of the config file, you can run the -config command to switch the configuration of the environment during packaging.

// Production environment configuration webpack --config webpack.prod.config.js // development environment configuration webpack --config webpack.dev.config.jsCopy the code

Config Configuration type

There are many configuration attributes in the config file. In addition, this topic describes how to export the configuration file.

A configuration object

The exported content is a configuration object, which is configured by property key value pairs.

module.exports = {
  entry:"".output:{}
}
Copy the code

Configuration function

The exported content is in the form of a function. You can pass in parameters such as environment variables that are imported from the command line, facilitating the processing of environment variables in functions.

module.exports = function(env,argv){
  return {
    entry:"".output: {}}}Copy the code

Promise asynchronous configuration

The exported content is returned in the Promsie form in the function, which is used to load the configuration asynchronously and can load the file dynamically.

module.exports = () = >{
  return new Promise((resolve,reject) = >{
    resolve({
        entry:"".output: {},})})}Copy the code

Content analysis

Packaging entrance

The packaging entry is the starting point of the entire packaging process.

According to the content form of projects, they can be roughly divided into three types:

  • Single page single module
  • Third-party Resource Integration
  • Multiple page

Single page single module

This is the most common module for daily development

module.exports = {
    entry:"./index.js"./* Is equivalent to entry:{main:"./index.js"} * */
}
Copy the code

Third-party Resource Integration

Consolidate third-party resource files during packaging and merge them into one file after packaging.

module.exports = {
  entry: {app: './src/app.js'.vendors: ['react'.'react-dom'.'react-router'].}}Copy the code

Multiple page

Multi-page projects require each page file to be packaged

module.exports = {
  entry: {pageOne: './src/pageOne/index.js'.pageTwo: './src/pageTwo/index.js',}}Copy the code

Packaging output

The Output option controls how WebPack outputs the compiled file modules.

Although there can be multiple entries, only one output can be configured. Therefore, there are two types of packaging entries.

Single entry package output

module.exports = {
    entry:"./index.js".output: {path: path.resolve(__dirname,"dist"),
        filename:"bundle.js".publicPath:"/"}}Copy the code

After packaging, the project starting with index.js is packaged into a bundle.js file.

Multiple entry package output

Different from single entry packing output, single entry packing form, there is only one starting point before packing, and only one output file after packing; The multi-entry packaged output should have multiple entry properties before packaging and multiple output files with different names after packaging.

So, WebPack provides placeholders to ensure file name differences in packaged output.

module.exports = {
  entry: {home: "./index.js".person: "./index2.js"
  },
  output: {path: path.resolve(__dirname,"dist"),
      filename:"[name].bundle.js",}}Copy the code

The webPack files are then packaged into two different bundles according to the name of the entry file

Noun interpretation and noun analysis

A placeholder

A placeholder describe
[hash] Hash value of the module identifier
[chunkhash] Hash value of chunk content
[name] The name of the module
[id] Module identifier
[query] Modules of query

Hash, Chunkhash, and Contenthash

  • Hash: Is related to the construction of the entire project. Whenever a file changes in the project, the hash value of the entire project will change and all files will share the same hash value.
  • Chunkhash: it is related to the construction of the import file. The corresponding chunk is constructed based on the import file and the hash for each chunk is generated. When the entry file changes, the hash value of the corresponding chunk changes.
  • Contenthash: Creates a unique hash based on the content of the file. That is, when the content of the file changes, the hash changes.

Module, Chunk, and Bundle

  • Module: We write source code, whether commonJS or AMdJS, can be understood as a module
  • Chunk: When the module source files we wrote are sent to Webpack for packaging, Webpack will generate chunk files based on the file reference relationship. Webpack will perform some operations on these chunk files
  • Bundle: After processing the chunk files, webpack finally outputs the bundle file. This bundle file contains the final source file that has been loaded and compiled, so it can be run directly in the browser.

Packaging mode

Depending on the environment in which the project is packaged, there are also different packaging patterns.

module.exports = {
    mode:"development" // production
}
/ / equivalent to
module.exports = {
    plugins: [new UglifyJsPlugin(),   // Compress the code
        new webpack.DefinePlugin({   // Define environment variables
            "process.env.NODE_ENV": JSON.stringify("development")})]}Copy the code

DefinePlugin uses json.stringify (“production”) instead of “producetion” when defining environment variables The DefinePlugin should be interpreted as replacing all of the process.env.node_env in the code with the contents of the string, but we may not have defined the production variable in our code, so the code will report an error directly. So we need to wrap a layer with json.stringify.

Pattern classification

Mode is also an attribute provided by WebPack to make development easier and more efficient, and can be used to modify the packaging Settings for different environments. Patterns can be tentatively divided into two types: development patterns and production patterns.

  • Development mode: In the development state, it is required that the packaged content should be development-friendly, convenient for code debugging and real-time update of the browser.
  • Production mode: Focus only on the performance of packaging and generating smaller bundles.

Loader parsing

Loader role

Loader is used to convert the source code of the module module. By default, WebPack can only recognize commonJS code, but we will introduce files such as vue, TS, less in the code, webPack can not process it. Loader extends webPack’s ability to handle multiple file types and convert these files into JS and CSS that browsers can render.

Loader configuration

Module. rules allows you to configure multiple loaders and clearly see which loaders are applied to the current file type

module: {rules: [{test:/.js$/,
            use:{
                loader:"babel-loader".options: {}}}, {test:/.css$/,
            use:[
                { loader:"style-loader" },
                { loader:"css-loader"}]}]}Copy the code
  • The rules property value is an array, and each array object represents a different matching rule;
  • The test attribute is a regular expression that matches different file suffixes;
  • Use indicates what loader to call to process the file. When there are multiple Loaders, use requires an array.

Loader features

  • Chain processing: Multiple Loaders support chain transfer and pipeline processing of resources. The return value of the previous processing is passed to the next loader.
  • Priority: Loader processing has a priority, from right to left, from bottom to top;

In the above demo, the CSS processing follows this priority, CSS-loader first, and then to style-loader; Therefore, we should pay attention to the sequence when writing loader.

The plugins parsing

The plugins work

Plugins are used to extend the functionality of WebPack and are more useful for listening to and handling webPack-triggered events.

The difference between

  • Loader: Since WebPack can only recognize JS, Loader acts as a translator to help WebPack preprocess the translation of other types of resources.
  • Plugins: Plugins extend the functionality of WebPack by broadcasting many events while WebPack is running. Plugins can listen for these events and then change the output through the API provided by WebPack.

Server service

After writing the code each time through the command line to carry out the packaging process, very inconvenient. If you want to automate the packaging after editing, you need a front-end local server.

webpack-dev-server

Webpack-dev-server is such a simple server that can be loaded in real time.

Webpack-dev-server ties webPack and Express servers together. You can set the server to the devServer property in webpack.dev.config.js.

module.exports = {
    devServer: {// Start port
        port:9000.// The default value is lcoalhost
        host:'0.0.0.0'.// Automatically open the browser
        open:false.// Enable module hot update
        hot:true.// Enable gzip compression
        compress:true
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin({})
    ]
}
Copy the code

Start the server with the command line webpack-dev-server. After starting the server, we find that the root directory does not generate any files because webpack is packaged in memory. The reason for not generating files is that accessing code in memory is faster than accessing code in files.

Hot update

(Hot Module Replacemen (HMR)) after the code is modified and saved, Webpack repackages the code and sends the new Module to the browser. The browser replaces the old Module with the new Module, so that the page can be updated without refreshing the browser.

The principle is that the browser and webpack-dev-server are connected through a Webscokt, and the client saves a packaged hash value during initialization. During each update, the server listens for file changes, generates the latest hash value and pushes it to the client through websocket again. The client compares the hash value twice and sends a request to the server to return the updated module file for replacement.

source-map

Through webPack module encapsulation, it is difficult to understand the meaning of the original code, so we need to map the compiled code back to the source;

Different configurations in Devtool have different effects and speeds. After combining performance and quality, we used cheap-module-eval-source-Map in development and source-Map in production.

devtool: 'cheap-module-eval-source-map'
Copy the code