Why do you need a build tool?

Conversion ES6 syntax conversion JSX CSS prefix completion/preprocessor compression confuses image compression

Why Webpack?

Community ecology rich configuration flexible and plug-in expansion official update iteration speed

Introduction to Webpack: Configuration file name

Webpack default configuration file: webpack.config.js Configuration file can be specified via webpack –config

// Initial Webpack: webpack configuration
module.exports = {
    entry: './src/index.js'.// Package the entry fileThe output:'./dist/main.js'.// Packaged output
    mode: 'production'./ / environment
    module: {
        rules: [{  / / a Loader configuration
            test: /\.txt$/, use: 'raw-loader'}},plugins: [  // Plug-in configuration
        new HtmlwebpackPlugin({
            template: './src/index.html',}})]What does zero configuration Webpack contain?
module.exports = {
    entry: './src/index.js'.// Specify the default entry as./ SRC /index.jsThe output:'./dist/main.js'.// Specify that the default output is./dist/main.js
    mode: 'production'.module: {
        rules: [{
            test: /\.txt$/, use: 'raw-loader'}},plugins: [
        new HtmlwebpackPlugin({
            template: './src/index.html',}})]// Run webpack from NPM script
{
  "name": "webpack-study"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1".// Run the build with NPM run build
    "build": "webpack" // Principle: Module partial installation creates soft links in node_modules/. Bin
  },
  "keywords": []."author": ""."license": "ISC"."dependencies": {},
  "devDependencies": {
    "webpack": "^ 4.31.0"."webpack-cli": "^ 3.3.2 rainfall distribution on 10-12"}}Copy the code

Core WebPack concepts

Entry

Entry is used to make the dependency diagram for webpack. Entry is used to make the dependency diagram for non-code such as images and fonts

Usage: Single entry: Entry is a string single interface application

module.exports = {
    entry: 'xxxxx',}Copy the code

Multi-entry: Entry is an object multi-interface application

module.exports = {
    entry: {
        app: 'xxx'.adminApp: 'xxxx',}}Copy the code

Output

Output tells WebPack how to Output the compiled file to disk.

Usage of Output: single entry configuration

module.exports = {
    entry: 'xxxx'.output: {
        filename: 'bundle.js'.path: __dirname + '/dist'}}Copy the code

Usage of Output: multi-entry configuration

module.exports = {
    entry: {
        app: 'xxx'.adminApp: 'xxx',},// There is no such thing as multiple exits
    output: {
        // Use placeholders to ensure that the file name is unique
        filename: '[name].js'.// name Specifies the name of the package
        path: __dirname + '/dist',}}Copy the code

Loaders

Webpack supports only JS and JSON file types out of the box, Loaders supports other file types and converts them into valid modules that can be added to dependency diagrams. Is itself a function that takes the source file as an argument and returns the result of the transformation.

What are the common Loaders?

The name of the describe
babel-loader Convert ES6, ES7 and other JS new feature syntax
css-loader Supports loading and parsing of. CSS files
less-loader Convert less files to CSS
ts-loader Convert TS to JS
file-loader Package pictures, fonts, etc
raw-loader Import the file as a string
thread-loader Multi-process package JS and CSS (normally one process)

The use of the Loaders

const path = require('path');

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            // test Specifies the matching rule
            // use Specifies the loader name to use
            test: /\.txt$/, use: 'raw-loader'}]}}Copy the code

Plugins

Plugins are used to optimize bundle files, manage resources, and inject environment variables. Apply to the entire build process

What are common Plugins?

The name of the describe
CommonsChunkPlugin Chunks of the same module code are extracted into common JS
CleanWebpackPlgin Cleaning up the build directory
ExtractTextWebpackPlugin Extract CSS from bunlde files into a separate CSS
CopyWebpackPlugin Copy files or folders to the output directory of the build
HtmlWebpackPlugin Create an HTML file to host the output bundle
UglifyjsWebpackPlugin Compression JS
ZipWebpackPlugin Generate a ZIP package from the packaged resources

The use of the Plugins

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.txt$/, use: 'raw-loader'}},plugins: [
        // Put it in the plugin array
        new HtmlwebpackPlugin({
            template: './src/index.html',}})]Copy the code

Mode

Mode is used to specify whether the current build environment is production, Development, or None. Webpack 4 didn’t have this concept before.

You can set mode using the built-in webpack function, which defaults to production.

The built-in functions of Mode

options describe
development Set process.env.node_env to development

Enable NameChunkPlugin and NameModulesPlugiin
production Set the value of process.env.node_env to production

Open FlagDependencyUsagePlugin,

FlagIncludeChunksPlugin ModuleConcatenationPlugin,

NoEmitOnErrorsPlugin OccurrenceOrderPlugin,

SideEffectsFlagPlugin, TerserPlugin
none Do not start any optimization options

Resource parsing

Parsing ES6

The configuration file for using Babel is.babelrc

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.js$/, use: 'babel-loader'}]}}Copy the code

Added ES6 Babel Preset configuration

{
    "presets": [
        // Add ES6 Babel Preset configuration
        "@babel/preset-env"]."plugins": [
        "@babel/proposal-class-properties"]}Copy the code

Parsing the React JSX

{
    "presets": [
        // Add ES6 Babel Preset configuration
        "@babel/preset-env".// Add React Babel preset configuration
        "@babel/preset-react"]."plugins": [
        "@babel/proposal-class-properties"]}Copy the code

Parsing the CSS

Css-loader is used to load. CSS files and convert them to CommonJS objects. Style-loader inserts the style into the head via the label.

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.css$/, use: [
                'style-loader'.'css-loader']]}}},Copy the code

Parse less and sass

Less-loader is used to convert less to CSS

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.css$/, use: [
                'style-loader'.'css-loader'.'less-loader']]}}},Copy the code

Parse images and fonts

Parse image/font file-loader

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.(png|svg|jpg|gif)$/, use: [
                'file-loader'.// Used to process files] {},test: /\.(woff|woff2|eot|tff)$/, use: [
                'file-loader'.// For processing fonts]]}}},Copy the code

Url-loader can also handle images and fonts, and internal file-loader can set smaller resources to automatically base64

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.(png|svg|jpg|gif)$/, use: [{
                loader: 'url-loader'.// Used to process files
                optins: {
                    limit: 10240  // Unit: bytes}}]}},}Copy the code

File listening in Webpack

File monitoring is the automatic reconstruction of a new output file when changes are detected in the source code.

How does WebPack turn on listening mode?

Two ways:

  • Start the webpack command with the –watch argument
  • Set watch: true in configuring webpack.config.js
// Listen to use
{
  "name": "webpack-study"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1".// Run the build with NPM run build
    "build": "webpack".// Principle: Module partial installation creates soft links in node_modules/. Bin
    "watch": 'webpack --watch'  // Only drawback: you need to manually refresh the browser each time
  },
  "keywords": []."author": ""."license": "ISC"."dependencies": {},
  "devDependencies": {
    "webpack": "^ 4.31.0"."webpack-cli": "^ 3.3.2 rainfall distribution on 10-12"}}Copy the code

Analysis of the principle of file monitoring

Polling determines whether the last edit time of the file has changed

Changes to a file are not immediately reported to listeners, but cached and waited for aggregateTimeout

module.export = {
    // Default is false, that is, not enabled
    watch: true.// watchOptions only make sense if listening mode is enabled
    watchOptions: {
        // The default is empty. Files or folders that are not listened on and support regular matching
        ignored: /node_modules/.// Wait 300ms for the change to occur before executing it. The default is 300ms
        aggregateTimeout: 300.// Check whether the file has changed by constantly asking the system whether the specified file has changed, the default is 1000 times per second
        poll: 1000}}Copy the code

Webpack hot update

Use the webpack – dev server. –

WDS don’t refresh the browser WDS output file, there is no disk IO, but in the memory use HotModuleReplacementPlugin plug-in

/ / hot update
{
  "name": "webpack-study"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1".// Run the build with NPM run build
    "build": "webpack".// Principle: Module partial installation creates soft links in node_modules/. Bin
    "watch": "webpack --watch".// Only drawback: you need to manually refresh the browser each time
    "dev": "webpack-dev-server --open"
  },
  "keywords": []."author": ""."license": "ISC"."dependencies": {},
  "devDependencies": {
    "webpack": "^ 4.31.0"."webpack-cli": "^ 3.3.2 rainfall distribution on 10-12"}}Copy the code

Use the webpack – dev – middleware

WDM transfers files from Webpack output to the server for flexible customization scenarios

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack('config');

app.use(webpackDevMiddleware(compiler, {
    publicPath:config.output.publicPath
}));

app.listen(3000.() = > {
   console.log('listen'); 
});

Copy the code

Principle analysis of thermal renewal

Compile JS into Bundle HMR Server: HMR Runtime: will be injected into the browser, update the Bundle. Js: will build the output file

File fingerprint

What is a document fingerprint? Output the suffix of the file name after packaging.

How is a file fingerprint generated? Hash: The Hash value of the entire project build will change whenever the project file is modified. Chunkhash: The Hash value of the entire project build will change whenever the project file is modified. Hash is defined based on the content of the file. Contenthash does not change if the content of the file does not change

Set output to filename using [chunkhash]

module.exports = {
    entry: './src/index.js'.output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name][chunkhash:8].js',}}Copy the code

CSS file fingerprint setting Set MiniCssExtractPlugin filename using [contenthash]

module.exports = {
    entry: './src/index.js'.output: {
        path: path.join(__dirname, 'dist'),
        filename: '[name][chunkhash:8].js',},plugins: [
        new MiniCssExtractPlugin(
            {
                filename: `[name][contenthash:8].css`}})]Copy the code

Set the name of file-loader to [hash]

Placeholder name meaning
[ext] Resource name extension
[name] The file name
[path] The relative path of the file
[folder] The folder where the file resides
[contenthash] The content of the file is hash. The default value is MD5
[hash] Hash of the file content, md5 generated by default
[emoji] A random emoj that refers to the contents of the file
module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.(png|svg|jpg|gif)$/, 
            use: [{
                loader: 'file-loader'.// Used to process files
                options: {
                    name: 'img/[name][hash:8].[ext]'.//8: the first eight bits of the hash}}]}},}Copy the code

Code compression

HTML compression CSS compression JS compression

JS file compression

The built-in uglifyjs webpack — the plugin

CSS compression

Optimize – CSS – Assets -webpack-plugin with CSsnano

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.(png|svg|jpg|gif)$/, 
            use: [{
                loader: 'file-loader'.// Used to process files
                options: {
                    name: 'img/[name][hash:8].[ext]'.//8: the first eight bits of the hash}}}}]],plugins: [
        new OptimizeCSSAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano'),})],}Copy the code

HTML file compression

Modify html-webpack-plugin to set compression parameters

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.(png|svg|jpg|gif)$/, 
            use: [{
                loader: 'file-loader'.// Used to process files
                options: {
                    name: 'img/[name][hash:8].[ext]'.//8: the first eight bits of the hash}}}}]],plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'src/search.html'),
            fileanme: 'search.html'.chunks: ['search'].inject: true.minify: {
                html5: true.collapseWhitespace: true.preserveLineBreaks: false.minifyCSS: true.minifyJS: true.removeComments: false,}})],}Copy the code

How do I automatically clean up build catalog artifacts?

Clean up the build directory with NPM Scripts

rm -rf ./dist && webpack

rimraf ./dist && webpack

Automatically clean up the build directory

Avoid manually deleting dist each time before a build

With the clean-webpack-plugin, the output directory specified by output is deleted by default

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        rules: [{
            test: /\.(png|svg|jpg|gif)$/, 
            use: [{
                loader: 'file-loader'.// Used to process files
                options: {
                    name: 'img/[name][hash:8].[ext]'.//8: the first eight bits of the hash}}}}]],plugins: [
        new CleanWebpackPlugin()
    ],
}

Copy the code

PostCSS plug-in Autoprefixer automatically adds cSS3 prefixes

Why are CSS3 attributes prefixed? Browser standards are inconsistent

IE Trident(-ms)

module.exports = {
    entry: './src/index.js'And the output:'./dist/main.js'.mode: 'production'.module: {
        
        rules: [{test: /.js$/,
                use: 'babel-loader'
            }, 
            {
                // Call order from right to left
                test: /.css$/,
                use: [
                    'style-loader'.'css-loader'] {},// Call order from right to left
                test: /.less$/,
                use: [
                    'style-loader'.'css-loader'.'less-loader', 
                    {
                        loader: 'postcss-loader'.options: {
                            plugins: () = > {
                                require('autoprefixer') ({
                                    browsers: ['last 2 version'.'> 1%'.'iOS 7'})}}}]}, {test: /\.(png|svg|jpg|gif)$/, use: [
                    'file-loader'.// Used to process files]},/ / {
            // test: /\.(png|svg|jpg|gif)$/, use: [{
            // loader: 'url-loader', // used to process files
            // optins: {
            // limit: 10240 // Unit: bytes
            / /}
            / /}]
            // },]},plugins: [
        new CleanWebpackPlugin()
    ],
}

Copy the code

Mobile px automatically converts to REM

CSS media query implements responsive layout

W3C defines REM as: font-size of the root element

Rem versus PX

Rem is the relative unit. Px is the absolute unit

Use px2rem – loaders

{
    // Call order from right to left
    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

Resources inline

meaning

Code level:

  • Initialization script for the page frame
  • Report relevant measures
  • The CSS is inlined to avoid page flashing

Request layer: Reduces the number of HTTP network requests

  • Inline small image or font (url-loader)

HTML and JS inline

Raw – loader inline HTML


Raw – loader inline js

CSS inline

Option 1: use style-loader option 2: HTml-inline-CSS-webpack-plugin

Multi-page application (MPA) concept

Each time a page jumps, the background server returns a new HTML document. This type of site is also called a multi-page site, also known as a multi-page application.

plan

Dynamically get entry and set the number of HTML-webpack-plugin

Using the glob. Sync

Use the source map

Use source Map to locate source development environment on, online environment off

Extract common resources

React and React-Dom base packages are imported through the CDN

Method: Use html-webpack-externals-plugin

Built-in in WebPack 4: Use SplitChunksPlugin for common script separation

Tree Shaking

Concept: A module may have many methods, and when one of them is used, the whole file will be sent into the bundle. Tree shaking is simply putting used methods into the bundle, while unused methods are erased during the Uglify phase.

Use: Webpack is supported by default, which is enabled by default if production mode is set to Modules: false in.babelrc

Requirements: must be ES6 syntax, CJS mode is not supported

Dead code elimination Does not take place. Code will not be executed. Non-reachable code affects only Dead variables.

if (false) {
    console.log('This code will never execute'); }Copy the code

The Tree – shaking principle

Using the features of ES6 module:

  • Can only appear as a statement at the top level of a module
  • The module name for import must be a string constant
  • Import binding is immutable

Code erasure: The Uglify phase removes useless code

Meaning of code segmentation

For large Web applications, having all of your code in one file is not efficient enough, especially if some of your code blocks are used at specific times. One feature of WebPack is to break up your code base into chunks and load them when the code runs and needs them.

Applicable Scenarios

  • Pull the same code into a shared block
  • The script loads lazily, making the initial download smaller

Lazy way to load JS scripts

  • CommonJS: the require. Ensure
  • ES6: Dynamic import (no native support yet, Babel conversion required)

How to use dynamic import?

NPM install @babel/plugin-syntax-dynamic-import –save-dev ES6: dynamic import

{
    "plugins": ["@babel/plugin-syntax-dynamic-import"],... }Copy the code

The necessity of ESLint

Excellent industry ESLint specification practices

Reality: eslint – config – reality, eslint – config – reality – base

Tencent:

  • Alloyteam team eslint – config – alloy (github.com/AlloyTeam/e…).
  • Ivweb Team: eslint-config-ivWeb (github.com/feflow/esli…)

Develop the team’s ESLint specification

Don’t duplicate wheels, based on ESLint: Recommend configuration and improved

  • Enable all rules that help you find code errors
  • Helps keep the team’s code style consistent, rather than limiting the development experience

summary

The above is the basis for us to learn the process of Webpack, on the basis of Webpack, optimization is an eternal topic, we will sum up the study of commonly used optimization methods.