The previous two projects were generated by create-React-app scaffolding, so you don’t need to pay attention to configuration, just write the business. Now there is a new project, if you want to configure yourself, you can only look at the official website, then look at the analysis tutorial and so on, and first have a brief understanding of the foundation of Webpack.

1. What is

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

Webpack is a static module packaging tool that generates bundler files in js format for images, CSS, js, etc. This is the central role of the foundation.

The core process of building

Initialization phase:

  1. Initialization parameters: Read from the configuration file, configuration object, and Shell parameters, and combine with the default configuration to obtain the final parameters
  2. Create the compiler object: Creates parameters obtained in the previous stepCompilerobject
  3. Initialize the compilation environment: this includes injecting built-in plug-ins, registering various module factories, initializing RuleSet collections, loading configured plug-ins, and so on
  4. Begin to compile: performcompilerThe object’srunmethods
  5. Determine the entrance: According to the configurationentryFind out all the entry files and callcompilition.addEntryConvert the entry file todependenceobject

Construction phase:

  1. Build module (make): according to theentryThe correspondingdependencecreatemoduleObject, callloaderTranslate the module into standard JS content, call JS interpreter to convert the content into AST object, find out the module that the module depends on, and then recurse this step until all the entry dependent files have been processed by this step
  2. Complete module compilation: The previous step recursively processed all accessible modules, resulting in the translated content of each module and the dependency diagram between them

Generation stage:

  1. Output Resource (SEAL): assemblies containing multiple modules according to the dependencies between the entry and modulesChunkAnd then take eachChunkConvert to a separate file and add to the output list. This step is the last chance to modify the output
  2. Writing to the file system (emitAssets) : After the output content is determined, the output path and file name are determined according to the configuration, and the file content is written to the file system

2. Core concepts

1. There is no entry for me.

Based on this configuration, WebPack finds the starting point for building its internal dependency graph. The default value is./ SRC /index.js and you can configure one or more different entry points.

A single entry

module.exports = {
  entry: './path/to/my/entry/file.js',
};

module.exports = {
  entry: {
    main: './path/to/my/entry/file.js',
  },
};
Copy the code

Multiple entries

module.exports = {
  entry: ['./src/file_1.js', './src/file_2.js'],
  output: {
    filename: 'bundle.js',
  },
};

module.exports = {
  entry: {
    app: './src/app.js',
    adminApp: './src/adminApp.js',
  },
};
Copy the code

Configurable object properties

  • DependOn: The entry on which the current entry depends. They must be loaded before the entry can be loaded.

  • Filename: specifies the name of the file to be exported.

  • Import: modules to be loaded during startup.

  • Library: Specifies the Library option to build a library for the current entry.

  • Runtime: Name of chunk at runtime. If set, a new runtime chunk is created. This can be set to false after WebPack 5.43.0 to avoid a new runtime chunk.

  • PublicPath: Specifies a public URL for the output files of this entry when they are referenced in the browser. Check output.publicPath.

One caveat

  • Runtime and dependOn should not be used on the same entry

  • Make sure that Runtime cannot point to an existing entry name

  • DependOn cannot be looping

Usage scenarios

1. Separate the entry of APP (application) and Vendor (third-party library)

module.exports = {
  entry: {
    main: './src/app.js',
    vendor: './src/vendor.js',
  },
};
Copy the code

In this way, you can save the necessary library or files (such as Bootstrap, jQuery, images, etc.) in Vendor.js and package them together into a single chunk. Content hashes remain unchanged, allowing browsers to cache them independently, reducing load times.

2. Multipage applications

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

In a multi-page application, the server pulls a new HTML document to your client. The page reloads the new document, and the resources are redownloaded. However, this gives us a special opportunity to do a lot of things, such as using optimity.splitchunks to create bundles for application code shared between pages. As the number of entry points increases, multi-page applications can greatly benefit from these technologies by reusing large amounts of code/modules between entry points.

(2) The output of the computer is not good.

Where there is an entry, there is an output, and the Output property tells WebPack where to output the bundles it creates and how to name them. The default value for the main output file is./dist/main.js, and the other build files are placed in the./dist folder by default.

Only one output configuration can be specified, even though multiple entry starting points can exist.

In a webpack configuration, the minimum requirement for the output property is to set its value to an object and then configure the filename for the output file to be an output.filename

module.exports = {
  output: {
    filename: 'bundle.js',
  },
};
Copy the code

Multiple entry points

If more than one “chunk” is created in the configuration (for example, using multiple entry points or using plug-ins such as CommonsChunkPlugin), substitutions should be used to ensure that each file has a unique name

module.exports = { entry: { app: './src/app.js', search: './src/search.js', }, output: { filename: '[name].js', path: __dirname + '/dist', }, }; // write to the hard disk:./dist/app.js,./dist/search.jsCopy the code

Senior advanced

Complex example of using CDN and hash on resources

module.exports = {
  //...
  output: {
    path: '/home/proj/cdn/assets/[fullhash]',
    publicPath: 'https://cdn.example.com/assets/[fullhash]/',
  },
};
Copy the code

If you don’t know what the publicPath address of the final output file is at compile time, you can leave it blank and set it dynamically at run time via __webpack_public_path__ in the entry starting file.

__webpack_public_path__ = myRuntimePublicPath; // The rest of the application entryCopy the code

3.loader

Webpack can only understand JavaScript and JSON files, which is a built-in capability available out of the box. Loader enables WebPack to process other types of files and convert them into valid modules for use by applications and to be added to the dependency graph

const path = require('path');

module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
};
Copy the code

The test attribute identifies which files will be converted, and the use attribute defines which loader should be used for the conversion.

4. Plugins

Plug-ins can be used to perform a wider range of tasks. These include: packaging optimization, resource management, injecting environment variables.

Plug-ins are the backbone of WebPack. Webpack itself is built on top of the same plugin system you use in your WebPack configuration! Plug-ins are designed to solve other things that the Loader cannot do.

const HtmlWebpackPlugin = require('html-webpack-plugin'); // install const webpack = require('webpack'); Exports = {module: {rules: [{test: /\.txt$/, use: 'raw-loader'}],}, plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], };Copy the code

5.

Set the mode parameter by selecting one of development, production, or None, which defaults to production

module.exports = {
  mode: 'production',
};
Copy the code

3. Configuration

The basic configuration

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js',
  },
};
Copy the code

4. Project practice

First, divide the configuration file into three parts: webpack.dev.js (development), webpack.prod.js (production) and webpack.config.js (public).

webpack.dev.js

const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const common = require('./webpack.config.js');
const path = require('path');

module.exports = webpackMerge.merge(common, {    mode: 'development', 
    entry: {
        app: './src/index.js' 
    },
    output: {
        path: path.resolve(__dirname, 'dev'), 
        filename: 'app.js', 
        publicPath: '/'  
    },
    devServer: {
        contentBase: './dev',
        historyApiFallback: {
            index: 'index.html'
        },
        hot: true,
        inline: true,
        port: 8888
    },
    plugins: [
        new webpack.DefinePlugin({
            "NODE_ENV": JSON.stringify('development')
        }),
        new webpack.HotModuleReplacementPlugin()
    ]
});
Copy the code

webpack.prod.js

const webpack = require('webpack');
const {merge} = require('webpack-merge');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const common = require('./webpack.config.js');
const path = require('path');

module.exports = merge(common, {
    devtool: 'source-map',
    mode: 'production',
    entry: {
        app: './src/index.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist/'),
        filename: 'bundle/[name].[chunkhash].js',
        publicPath: '/'
    },
    optimization: {
        splitChunks: {
            chunks: "all",
        }
    },
    plugins: [
        new webpack.DefinePlugin({
            "NODE_ENV": JSON.stringify('production')
        }),
        new CleanWebpackPlugin({
                cleanOnceBeforeBuildPatterns: [
                    'bundle/*',
                ]
            }),
        new HtmlWebpackPlugin({
            title: '',
            inject: true,
            template: 'dev/index.html',
            filename: 'index.html'
        }),
    ]
});
Copy the code

webpack.config.js 

const path = require('path');
module.exports = {
    module: {
        rules: [
            {
                test: /\.(js)$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env', '@babel/preset-react'],
                    plugins: [
                        '@babel/plugin-transform-runtime',
                        '@babel/plugin-proposal-class-properties',
                        '@babel/plugin-transform-named-capturing-groups-regex'
                    ]
                },
            },
            {
                test: /\.(css)$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(scss)$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(less)$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /\.(png|jpg|gif)$/,
                use: ['file-loader']
            },
            {
                test: /\.(html)$/,
                use: ['html-loader']
            }
        ]
    },
};
Copy the code

The current version does not represent the final online version, later will increase or decrease according to the specific situation, encountered will not, Baidu to find solutions, learn, after all, is a tool.

References:

zhuanlan.zhihu.com/p/363928061