What is Webpack?

Webpack is a front-end resource loading/packaging tool. It performs a static analysis based on the dependencies of modules, and then generates the corresponding static resources for those modules according to the specified rules.

Why use WebPack?

Many web pages today can be thought of as feature rich apps, with complex JavaScript code and a bunch of dependencies. In order to simplify the complexity of development, there are many good attempts on the front end:

  • Modularity, the refinement of complex programs into small modules;
  • A lightweight development language that extends JavaScript –TypeScript
  • CSS preprocessors such as Scss and LESS
  • .

These attempts have greatly improved the front-end development efficiency, but these files often require additional processing to be recognized by the browser, which is cumbersome to handle manually, and webPack-like packaging tools are available to solve this problem.

Start using WebPack

Webpack can be used on the terminal. The basic way to use webPack is as follows:

Webpack {entry file} {Destination for bundled file} // Entry file: Write path for entry files // Destination for bundled file: fill path for bundled filesCopy the code

Webpack has a number of other advanced features (such as loaders and plugins) that can be implemented from the command line, but it’s not easy and error-prone to perform complex operations in the terminal. A better approach is to define a configuration file. We can create a new webpack.config.js file in the same directory where we can put all the configuration related to packaging.

var webpack=require('webpack'); Module. exports = {entry: __dirname + "/app/main.js",// output: {path: }, mode: development, module: {rules: [{test: /\.css$/, use: ["style-loader","css-loader"]}]}, plugins:[new webpack.bannerPlugin ('webpack instance ')]}Copy the code

Entry: Specifies the entry that webPack depends on. An entry can be a string (single-entry file) or an object (multi-entry file).

/ / a single entrance const config = {entry: {main: '. / path/to/my/entry/file. The js'}}; // Filenames = {app: './ SRC/filenames. Js ', vendors: './ SRC/filenames. Js'}, output: {filename: '[name]. Js', / / use the name placeholder path: __dirname +'/dist '}};Copy the code

Output: Tells WebPack how to output the edited file to disk. Path in output indicates the path for storing the output file. Filename indicates the name of the output file. For multiple entry files, the output file name can use the placeholder [name].

Next, just type webpack (nodemodules/.bin/webpack for non-global installations) on the command line, which automatically references the configuration in the webpack.config.js file.

babel

Webpack originally supports JavaScript parsing, but for ES6 syntax, WebPack native does not support, so you need to use Babel-Loader to parse ES6 syntax.

Use babel-loader:

module: { 
    rules: [ 
        { test: /\.js$/, loader: "babel-loader" } 
    ]
},
Copy the code

Babel-loader is dependent on Babel, so you need to use the Babel configuration file. Babelrc in your project. Babel is a platform that compiles JavaScript. It compiles code for the following purposes:

  • Allows us to use the latest JavaScript code (ES6, ES7…) , regardless of whether the new standard is fully supported by currently used browsers;
  • Allows us to use javask-based extensions like React’s JSX

Two of the more important concepts in Babel are presets and plugins, which can be understood as a plugins for a function, and then presets are a set of Babel plugins. Here we need to support ES6 syntax, so we need to add @babel/preset-env presets for Babel in the.babelrc file. (@babel/preset-env is a collection of presets, including the latest syntax-conversions for ES2015, ES2016, ES2017, etc. that we use in Babel6, allowing us to use the latest JS syntax-let, const, arrow function, etc.) Similarly, if we need to support react parsing, we also need to add @babel/preset-react presets to the.babelrc file.

{ "presets": ["@babel/preset-env", @babel/preset-react", @babel/preset-react JSX syntax], "Plugins ":["@babel/proposal-class-properties"// to compile the class]}Copy the code

loaders

Webpack supports only JS and JSON file types out of the box. Loaders support other file types and convert them into valid modules that can be added to dependencies.

Loaders itself is a function that takes the source file as an argument and returns the converted result.

Webpack loadersUsage of loaders: test specifies the matching rule. Use specifies the name of the loader to be used

Parsing the CSS

To parse CSS in WebPack, you need to first load a.css file using a CSS-Loader, convert it to a CommonJS object, and then use a style-Loader to insert the style into the head with the

module: { 
    rules: [ 
        { test: /\.less$/, use: ["style-loader","css-loader" } 
    ]
},
Copy the code

Parsing the less

If webPack wants to parse less, it only needs to use less-Loader to convert less into CSS based on parsing CSS first.

module: { 
    rules: [ 
        { test: /\.less$/, use: ["style-loader","css-loader","less-loader"] } 
    ]
},
Copy the code

Parse images and fonts

Use file-Loader to process images (PNG/JPEG/JPG/GIF) and fonts. Url-loader can also handle images and fonts. Compared to file-Loader, URL-Loader can also set smaller resources to automatically convert to base64

The module: {rules: [{test: / \. (PNG | jpeg | JPG | GIF) $/, use: [" file - loader "]}, / / resolution picture {test: / \. (woff | woff2 | eot | the vera.ttf | otf) $/, use: [" file - loader "] {} / / parsing font test: / \. (PNG | jpeg | JPG | GIF) $/, / / use the url - loader parsing images use: [{loader: "file-loader", options: {limit: 10240 // Webpack will automatically base64}}]}]},Copy the code

plugins

Plug-ins are used to extend Webpack functionality, and they take effect throughout the build process to perform related tasks. Loaders and Plugins are often confused, but they are completely different things. Loaders are used to process source files during the packaging build process (JSX, Scss, Less..). One at a time, the plug-in does not directly operate on a single file, it directly contributes to the entire build process. Plugins are used to optimize the generated bundle files, manage resources, inject environment variables, etc., and are used throughout the build process. Anything that can’t be done by a loader, such as manually removing the dist directory before each build, can be done through plugins.

Common webPack plugins:Add our defined plugins to the plugins array in the webpack.config.js file.

Clear the build directory

Each build in Webpack results in a build folder, which can be cleared with the command rm rf. /dist && webpack/dimraf./dist && webpack during development. A more elegant solution is to use webPack’s plug-in: the Clean Webpack-plugin, which by default removes the directory specified by output, avoiding the need to manually remove dist each time before building

const CleanWebpackPlugin = require('clean webpack-plugin');
module.export = { 
    plugin: [ 
            new CleanWebpackPlugin(), 
        ] 
},
Copy the code

CSS Feature Enhancements

  • Use PostCSS plug-in autopreFixer to automatically complete the CSS prefixes

There are currently four cores: Trident (-ms), Geko(-moz), Webkit(-webKit), and Presto(-o), because browser standards are not completely uniform.

.box{
    -moz-border-radius: 10px; 
    -webkit-border-radius: 10px; 
    -o-border-radius: 10px; 
    border-radius: 10px;
}
Copy the code

How to write CSS without adding prefixes? Using autopreFixer, you can add prefixes to CSS properties after CSS files are pre-processed by csS-Loader.

module: { 
    rules: [ 
        { 
            test: /\.less$/, 
            use: [
                'style-loader',
                'css-loader', 
                'less-loader',
                {
                    loader: 'postcss-loader',
                    options: {
                        plugins:()=>{ 
                            require('autoprefixer')({ 
                                browsers: ['last 2 version','>1%','IOS 7'] 
                             }) 
                          }
                     }
                }
            ]
        }
    ]
},
Copy the code
  • Mobile CSS PX automatically converts to REM

Rem: font zise of THS root element. Rem is relative, px is absolute. Use px2REM-Loader to automatically convert CSS PX to REM

module: { 
    rules: [ 
        { 
            test: /\.less$/, 
            use: [
                'style-loader',
                'css-loader', 
                'less-loader',
                {
                    loader: 'px2rem-loader',
                    options: {
                        remUnit: 75, 
                        remPrecision: 8,
                     }
                }
            ]
        }
    ]
},
Copy the code

mode

Mode specifies whether the current build environment is Production, Development, or None. Webpack will enable some built-in functions by default for different build environments. Mode defaults to production.

File to monitor

Webpack needs to manually execute build commands after each source code change, which is inefficient and time-consuming in development, so automatic compilation of files is necessary in WebPack. File listening automatically reconstructs a new output file when it detects changes in the source code.

There are two ways for WebPack to enable listening mode

  • The webpack command is started with the –watch parameter.
  • Set watch: true in configuring webpack.config.js.

The idea behind file listening is that WebPack polls to see if the last compile time of a file has changed. When a file changes, the listener is not immediately notified. Instead, the file is cached and built with the changed file after the aggregateTimeout expires.

WatchOptions: {ignored:}} module. Export = {// Default: false, that is, disable watch: true, watchOptions: {ignored: watchOptions: {ignored: // node_modules/, // default is null, do not listen to files or folders, support regular match aggregateTimeout: 300, // listen to changes in the aggregateTimeout 300ms to compile, default poll 300ms: // The default value is 1000 times per second. // The default value is 1000 times per second.Copy the code

The only drawback: You need to manually refresh the browser each time. There is no need to refresh the browser — another method is HRM (Hot Module Replacement) based on WDS (Webpack-dev-server), which only needs to partially refresh the changed Module on the page, while retaining the current page state. For example, the status of check boxes, input boxes, and so on.

Implementing HMR in WebPack is also simple, requiring only two configurations

  1. Add the HMR plug-in to the WebPack configuration file;
  2. Add the “hot” parameter to Webpack Dev Server;
Module. export = {devServer: {contentBase: "./public", // historyApiFallback: true, // does not jump inline: True, hot: true}, plugins: [new webpack. HotModuleReplacementPlugin () / / thermal load plugins]}.Copy the code

Code compression

JavaScript compression: WebPack4 has built-in uglifyjs-Webpack-Plugin, which will automatically compress JS code during the packaging process.

CSS compression: Optimize – CSS-assets-Webpack-Plugin for CSS code compression, and use the CSS preprocessor: CSSNano.

HTML compression: Use the html-webpack-plugin to set the compression parameters.

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); //CSS compressing const HtmlWebpackPlugin = require('html-webpack-plugin'); Compression module. / / HTML export = {plugin: [new OptimizeCssAssetsWebpackPlugin ({assetNameRegExp: / \. CSS $/ g, cssProcessor: // require("cssnano")}), new HtmlWebpackPlugin({template: path.join(__dirname, 'SRC /search.html',// package template path: HTML ',// encapsulate the file name chunks:['search'], inject: true, minify: {html5: true, collapseWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments false, } }), ] },Copy the code

Extraction of public resources

In a project, there are many pages, all of which use the same basic library, and there may be some common modules between each page. If you type all the dependencies when packaging, it is actually more wasteful, and the volume of packaging is relatively large. How to do the separation of common resources between pages.

The first is the separation of the underlying libraries. Take React as an example in development. React, React-DOM and other basic libraries are often used in projects. We can introduce react and React-DOM basic packages through CDN instead of packaging them into bundle files, which can greatly reduce the volume of packaged files. The SplitChunksPlugin plug-in can also be used for common script separation. SplitChunksPlugin is a particularly powerful plug-in available in WebPack4 as an alternative to CommonsChunksPlugin.

new webpack.optimize.SplitChunksPlugin({ chunks: "all", minSize: 20000, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, name: true, cacheGroups:{ test: / (react | react. Dom) /, / / separation react, react - dom development package name: 'vendors', / / separate the filename chunks of the base package:' all '}})Copy the code

As you can see, the parameters of the SplitChunksPlugin plug-in are quite complex, which reflects the power of the plug-in. Focus on setting the chunks parameter. Chunks: async(separation of libraries that are entered asynchronously – default)/initial (separation of libraries that are introduced synchronously)/ all (so separation of libraries that are imported – recommended)

SplitChunksPlugin can also be used to extract the public files of the page. MinChunks sets the minimum number of references, and minuSize sets the size of the detached package.

new webpack.optimize.SplitChunksPlugin({ 
    cacheGroups:{ 
        minSize: 0, 
        commons: { 
            name: 'commons', 
            chunks: 'all', 
            minChunks: 2, 
        } 
    } 
})
Copy the code

Improve webPack packaging speed

  • Use higher versions of Webpack and Node.js. Software improves performance over iterations
  • Use the thread-loader to enable multi-process and multi-instance construction. How it works: Each time WebPack parses a module, thread-Loader assigns it and its dependencies to worker threads.
  • Parallel compression. Use the parallel-Uglify-plugin, uglify-webpack-plugin, terser-webpack-plugin (ES6 syntax supported) to enable the PARALLEL parameter
  • Use cache to improve the speed of secondary packaging: 1. Babel-loader enables cache. 2, terser-webpack-plugin enabled cache; 3. Use the cache-loader or hard-source-webpack-plugin
  • .

conclusion

This time, I have organized the knowledge points of webpack in the first two weeks. The content is not very comprehensive, and there are some places that I don’t understand deeply. I hope to deepen my master of Webpack and accumulate more practical experience in the future study.