webpack5 learning notes

Posted by Mr_Pancakes on Wed, 26 Jan 2022 23:56:34 +0100

webpack5 learning notes

Watching the video of Qianfeng education in station b feels very good

Qianfeng course video

cdn resources cdn resources

webpack official website

webpack plugin

webpack notes

Resolve scope issues

Quick execution function

;(function(){

.....

})

Solve code splitting problem

node

commonjs

modularization

Resolve browser support issues

requirejs

If you want the main js to call other js, you need to introduce it before the main js

hello.js

export hello()

main.js

hello()

import hello.js

import main.js

Install webpack

Install node first

Then install the global installation of webpack cli (not recommended, the version will be locked)

npm install webpack webpack-cli --global

Local installation

npm init 
npm install webpack webpack-cli --save-dev 

cmd cls clear screen

webpack packaging

webpack

webpack --stats detailed view packaging details

npx awesome

Configuration entry file (instructions cannot be saved)

webpack --entry xxx

Add -- mode production production environment

Configuration exit

output

File configuration

webpack.config.js file

The absolute path uses require('path ')

path.resolve(__dirname,'xxx')

module.exports = {
	entry:'',
	
	output:{
		filename: '',
		path: 'Pairing path''
	}
	
	
}

Automatic introduction of resources

Plug in HTML webpack plugin

npm install html-webpack-plugin

introduce

const HtmlWebpackPlugin = require('html-webpack-plugin') 

Under root {}

plugins:[
	new HtmlWebpackPlugin()
]

to configure HtmlWebpackPlugin
new HtmlWebpackPlugin({
	template: './index.html', template file
	filename: 'app.html', Generate file name
	inject: 'body' In which label
})

Clean dist (clean up old packaging)

In the output option

output:{
		filename: '',
		path: 'Pairing path'',
		clean: true
	}

Build development environment

mode option

Positioning error

Better display of code positioning errors

devtool: 'inline-source-map',

Monitor code changes

webpack --watch

Using webpack dev server

npm install webpack-dev-server

Plus-D runs in the local development environment

In the configuration file

devServer: {
	devServer: {
		static: './dist'  //Pay attention to here/ dist is the path
	}
}

On the console, click webpack dev server

Resource module

module: {
		rules: [
			{
				test: /\.png$/,
				type: 'asset/resource'
			}
		]
	}

Import in js file

import imgsrc from './assets/img-1.png'

const img = document.createElement('img') Create a photo element
img.src = imgsrc Add path
document.body.appendChild(img) Add photos to page

Webpack dev server -- Open plus -- open is on by default

Define the export path and name in output

output: {
		filename: 'bundle.js',
		path: path.resolve(__dirname,'./dist'),
		clean: true,
		assetModuleFilename: 'images/test.png'
	},

assetModuleFilename: 'images/contenthash.png'

contenthash can automatically generate the file name according to the hash

assetModuleFilename: 'images/contenthash'

contenthash can automatically generate file name and extension based on hash

If configured in module rules generator

Then the generator is higher than the output

inline configure resources to turn images into base64 resources

Turn pictures into base64 resources

test: /\.svg$/,
type: 'asset/inline'

Configure source

test: /\.txt$/,
type: 'asset/source

Configure asset

test: /\.jpg$/,
type: 'asset'

Automatically select the url or file base64. Generally, base64 will be generated if it is less than 8k

It can be controlled by appending parser

test: /\.jpg$/,
type: 'asset',
parser: {
    dataUrlCondition: {
        maxSize: 4*1024  //Default size 4 * 1024 
    }
}

loader usage

Install CSS loader and style loader

implement

npm install css-loader -D

npm install style-loader -D

to configure

{
    test: /\.css$/,
    use: ['style-loader','css-loader']
}

In index JS introduction

import './style.css'

Execute CSS loader first and then style loader

Install and configure less loader CSS loader

npm install less-loader less -D

to configure

{
    test: /\.(css|less)$/,
    use: ['style-loader','css-loader','less-loader']
}

In index JS introduction

import './style.less'

Extracting and compressing css

Install plug-ins

npm install mini-css-extract-plugin -D

On webpack JS introduction

const MiniCssExtract = require('mini-css-extract-plugin')

Add in plugins

new MiniCssExtract()

to configure

{
    test: /\.(css|less)$/,
    use: [MiniCssExtract.loader','css-loader','less-loader']
}

Replace style loader with minicssextract loader

Style loader is used to connect css to the page

In order to extract, it is changed to minicssextract loader

Custom generated file name

new MiniCssExtract({

filename: 'styles/[contenthash].css'

})

compress

Install plug-ins

npm install css-minimizer-webpack-plugin -D

introduce

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

Configure in optimized configuration

webpack configuration root level

optimization: {
	minimizer: [
		new CssMinimizerPlugin()
	]
}

Note that code compression will fail after this item is configured. You need to configure terser separately

And the mode is changed to the production environment

mode: 'production',

Load images

Picture priority

.block-bg{

background-image: url(./assets/webpack-logo.svg) !important;

}

! important make the highest priority

Load font

Configure webpack

{
    test: /\.(woff|woff2|eot|ttf|otf)$/,
    type: 'asset/resource'
}

Import font file in css file

@font-face {
    font-family: 'iconfont';
    src: url('./assets/iconfont.ttf');
}

.icon{
    font-family: 'iconfont';
    font-size: 30px;
}

In index JS import font

const span = document.createElement('span')

span.classList.add('icon')
span.innerHTML = ''
document.body.appendChild(span)

Loading data CSV loader XML loader

install

npm install csv-loader xml-loader -D

to configure

{
    test: /\.(csv|tsv)$/,
    usr: 'csv-loader'
},

{
    test: /\.xml$/,
    usr: 'xml-loader'
}

Import data in index js

import Data from './assets/data.xml'
import Notes from './assets/data.csv'

Convert xml to js object

Convert csv to array

Custom JSON parser, such as toml yaml json5

install

npm install toml yaml json5 -D

Configure webpack

const toml = require('toml')
const yaml =require('yaml')
const json5 = require('json5')
{
	test: /\.toml$/,
	type: 'json',
	parser: {
		parse: toml.parse
	}
},

{
	test: /\.yaml$/,
	type: 'json',
	parser: {
		parse: yaml.parse
	}
},

{
	test: /\.json5$/,
	type: 'json',
	parser: {
		parse: json5.parse
	}
}

Use file

babel-loader

Convert es6 to es5

Babel loader: parsing es6 in webpack

@babel/core:babel core module

@babel / preset env: babel reservation, a collection of babel plug-ins

install

npm install -D babel-loader @babel/core @babel/preset-env

to configure

{

test: /\.js$/,
exclude: /node_modules/,
use: {
	loader: 'babel-loader',
	options: {
		presets: ['@babel/preset-env']
	}
}

}

Resolve the error regeneratorRuntime

Reason babel is produced for async/await compatibility

Install plug-in @ babel/runtime

npm install @babel/runtime -D

Install plug-in @ Babel / plugin transform runtime

npm install @babel/plugin-transform-runtime -D

to configure

{
	test: /\.js$/,
	exclude: /node_modules/,
	use: {
		loader: 'babel-loader',
		options: {
			presets: ['@babel/preset-env'],
			plugins: [
				['@babel/plugin-transform-runtime']
			]
		}
	}
}

Separation code

If there are multiple entry files

entry: {
	index: './src/index.js',
	another: './src/another-module.js'
},

Exportable filename: '[name].bundle.js',

However, this will lead to repeated packaging

Avoid repetition

Scheme I sharing
entry: {
	index: {
		import: './src/index.js',
		dependOn: 'shared'
	},
	another: {
		import: './src/another-module.js',
		dependOn: 'shared'
	},

	shared: 'lodash'
},
Scheme 2: configure splitChunks

optimization: {

splitChunks: {
	chunks: 'all'
}

}

Dynamic (asynchronous) import

as follows

function getComponent() {
    return import('lodash')
        .then(({default: _})=>{
            const element = document.createElement('div')
            element.innerHTML = _.join(['hello','webpack'],' ')
            return element
        })
}

getComponent().then((element)=>{
    document.body.appendChild(element)
})


const button = document.createElement('button')
Lazy loading
button.textContent = 'Click addition'
button.addEventListener('click',()=>{
    import(/* webpackChunkName: 'math' */'./math').then(({add})=>{
        console.log(add(4,5))
    })
})

document.body.appendChild(button)

import(/ webpackChunkName: 'math' /'./math') Magic annotation can set the package file name

Preload prefetch

prefetch browser loads when idle

import(/ webpackPrefetch: true /

preload is similar to lazy loading

import(/ webpackPreload: true /

cache

Output file name

filename: 'name.contenthash.js',

Cache third-party libraries

optimization: {
	minimizer: [
		new CssMinimizerPlugin()
	],

	splitChunks: {
		cacheGroups: {
			vendor: {
				test: /[\\/]node_modules[\\/]/,
				name: 'vendors',
				chunks: 'all'
			}
		}
	}
}

js into a folder

output: {

	filename: 'scripts/[name].[contenthash].js',
	....

Development configuration

Public path

In output

Join publicPath: 'http://localhost:8080/ '

environment variable

module.exports = (env) => {

console.log(env)
return {
    webpack Configuration items can be env Parameter configuration
}

}

such as

mode: env.production ? 'production' :'development'

webpack --env production

Can pass parameter a = 1

The compressed code uses terser webpack plugin - D

npm install terser-webpack-plugin -D

use

optimization: {
		minimizer: [
			new CssMinimizerPlugin(),
			new TerserPlugin()
		],
...

Split profile

Development environment and production environment

development environment

Create a new webpack from the project root directory config. Dev.js development environment

Change mode to development environment

Remove compressed code and public paths or include cache

start-up

webpack -c ./config/webpack.config.dev.js

-c can be replaced by - config

Note the path of the generated file

production environment

Create a new webpack.exe in the config directory config. Prod.js file

Change mode to production environment

Delete debug devtool dev server

start-up

webpack -c ./config/webpack.config.prod.js

Extra webpack serve (webpack dev server)

You can use webpack serve - C/ config/webpack. config. dev.js

npm script

Under the project root directory, package json

{
  "scripts": {
    "start": "npx webpack server -c ./config/webpack.config.dev.js",
    "build": "npx webpack -c ./config/webpack.config.prod.js"
  }
}

Ignore performance optimization tips

Under webpack configuration root {}

performance: {

hints: false

}

Extract public configuration

Create webpack.com from the project root directory config. common. JS file

Remove the same configuration from dev prod

Merge profiles using webpack merge

install

npm install webpack-merge -D

Create wenpacj. Config directory config. js

const { merge } = require('webpack-merge')

const commonConfig = require('./webpack.config.common')
const productionConfig = require('./webpack.config.prod')
const developmentConfig = require('./webpack.config.dev')

module.exports = (env) => {
    switch (true) { //Key value judgment can be defined
        case env.development:
            return merge(commonConfig,developmentConfig)

        case env.production:
            return merge(commonConfig,productionConfig)

        default:
            return new Error('No matching configuration was found')
    }
}

source-map

New directory npm init initialization

Install NPM install webpack cli webpack dev server HTML webpack plugin - D

The default devtool is eval

'source-map'

Can produce main js. Map and produced main The sourceurl main.js comment will be displayed js. Map (display rows and columns) and associated

Can you find code problems

'hidden-source-map'

Can produce main js. Map and produced main Sourceurl main.js comment will not be displayed js. Map and not associated

Code problems cannot be found directly

'inline-source-map'

Will not produce main js. Map but produced main The sourceurl main.js comment will be displayed js. Map and Association

Can you find code problems

'eval-source-map'

Instead of generating a sourcemap file, it is placed after eval

Can you find code problems

'cheap-source-map'

Generate map file mappings with rows and no columns

Can you find code problems

'soap module source map 'recommended development environment

Generate map file mappings with number of rows, no columns and module s

Can you find code problems

Webpack server configuration

devServer: {
	static: path.resolve(__dirname, './dist'),
	compress: true, //Add gzip for code compression
	port: 3000, //Port number
	host: '0.0.0.0', //Accessible under LAN

	headers: {
		'X-Access-Token': 'abc123'
	},

	proxy: { //Agent configuration
		'/api': 'http://localhost:9000'
	},

	// https: true, / / enable https
	// {
	//     cacert: './server/pem',
	//     pfx: './server.pfx',
	//     key: './server.key',
	//     cert: './server.crt',
	//     passphrase: 'webpack-dev-server',
	//     requestCert: true
	// }



	http2: true, //Enable http2 https default self signature

	historyApiFallback: true //Historical path

}

Module hot replacement and hot loading

Hot replacement

hmr does not need complicated configuration in webpack 5, and it can be used out of the box

devServer: {
    hot: true    
}

Modify js hot update

On app js

if(module.hot){
    module.hot.accept('./input.js', () => {
        
    })
}

Thermal loading

devServer: {
    liveReload: true
}

Code specification eslint

install
npm i eslint -D
eslint ./src
Project use
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: 'development',

    entry: './src/app.js',

    module: {
        rules: [
            {
                test: /\.js$/,
                usr: ['babel-loader','eslint-loader'] //'eslint loader' first
            },
        ],
    },

    plugins: [
        new HtmlWebpackPlugin()
    ]
};

Error reporting can be closed after opening

devServer: {
    client: {
        overlay: false //Error reporting overlay
    }
}

Githooks--Husky

Detection code before submission

Basic principles

. git / hooks / pre commit file

Document content

eslint ./src
 perhaps
npx eslint ./src
custom

Create a new directory mygithooks

Documents The content of mygithooks / pre commit is the same

git configuration

git config core.hooksPath .mygithoosk

Husky
npm husky install -D

huxky install


package.json
 "main": "index.js",
  "scripts": {
    "prepare": "husky install"
  },

Yes/ New pre commit file in husky directory

Remember to give pre commit file permission (+ x)

Write NPX eslint src

implement

git add.

git commit -m 'xxx'

If the code is wrong, you will be prompted

Explore the principles of webpack

Resolve absolute directory

Alias configuration

Use @ to point to src

webpack.js

resolve: {
  alias: {
    '@': path.resolve(__dirname,'./src')
  }
}

Priority configuration default JS > JSON

to configure

resolve: {
  alias: {
    '@': path.resolve(__dirname,'./src')
  },
  extensions: ['.json','.js','vue']
}

Configure external resource import (link import)

Mode 1

wepack configuration file

externals: {
  jquery: 'jQuery'
}

Add in html template file

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
Mode 2

wepack configuration file

externalsType: 'script', //Expose as script tag
externals: {
  jquery: [
    'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js', / / link
    '$' //Exposure label
  ]
}

Dependency graph

install

npm i webpack-bundle-analyzer -D

introduce

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')

plugins: [
    new BundleAnalyzerPlugin()
  ]

Start webpack serve and a pop-up message will pop up

PostCSS and CSS modules handle browser CSS compatibility issues

install

npm i postcss-loader -D

npm i autoprefixer -D

Configure webpack

module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      }
    ]
  }

Configure postcss config. js

Create files in the root directory

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

use

In package JSON directory root {}

"browserslist": [
    "> 1%", //Global browser usage should be greater than 1%
    "last 2 versions" //The last two versions of each browser
  ]

Plug in postcss nested

Support such as div under body

install

npm i postcss-nested -D

Configure postcss config. js

module.exports = {
  plugins: [
    require('autoprefixer'),
    require('postcss-nested')
  ]
}

Turn on css modularization

use: ['style-loader',
  {
    loader: 'css-loader',
    options: {
    modules: true  //Turn on css modularization
  }
 }
, 'postcss-loader'],
exclude: [path.resolve(__dirname,'..','node_modules')] //Exclude external modules

Two configurations can be set, one global and one local

The configuration is as follows in webpack

Global configuration

{
  test: new RegExp(`^(?!.*\\.global).*\\css`),
    use: ['style-loader',
      {
        loader: 'css-loader',
        options: {
        modules: true  //Turn on css modularization
      }
     }
    , 'postcss-loader'],
    exclude: [path.resolve(__dirname,'..','node_modules')] //Exclude external modules
}

Local configuration

{
  test: new RegExp(`^(.*\\.global).*\\css`),
    use: [
      {
        loader: 'style-loader'
      },
      {
        loader: 'css-loader'
      },
      {
        loader: 'postcss-loader'
      }
      ],
    exclude: [path.resolve(__dirname,'..','node_modules')] //Exclude external modules
}

WebWorks

Create a worker

const worker = new Worker(new URL('./work.js',import.meta.url))

Receive main thread information

self.onmessage = () => {

}

The main thread receives information

worker.onmessage = (message) => {

console.log(message)

}

Send information to the main thread

self.postMessage({

answer: 1111

})

Main thread sends information

worker.postMessage({

question: 'hi, the worker thread over there, please tell me today's lucky number?'

})

Integrated typescript

install

npm i typescript ts-loader -D

Configure webpack

const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
  mode: 'development',
  entry: './src/app.ts',
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },


  resolve: {
    extensions: ['.ts', '.js']  //Set priority ts extension
  },

  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist')
  },
  
  plugins: [
    new HtmlWebpackPlugin()
  ]

}

Initialize ts configuration file

tsc --init

Modify ts configuration

rootDir: "./src"

outDir: "./dist"

ts usage module

website https://www.typescriptlang.org/dt/search?search=

Query requirements module installation

entry configuration

Configuration one

entry: [
    './src/app.js',
    './src/app2.js'
  ]

Configuration II

// entry: [
  //   './src/app.js',
  //   './src/app2.js',
  //   'lodash'
  // ],

  entry: {
    main: ['./src/app2.js', './src/app.js'],
    lodash: 'lodash'
  },

Configuration III

entry: {
    main: {
      import: ['./src/app2.js', './src/app.js'],
      dependOn: 'lodash' //rely on
    },
    lodash: 'lodash'
  },

index.html template configuration

Configure a basic configuration

webpack

 plugins: [
    new HtmlWebpackPlugin({
      title: 'Multi page application', //parameter
      template: './index.html',
      inject: 'body', //Where js is introduced
      chunks: ['main'] //Specify the js to be introduced
    })
  ]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>

</body>
</html>

Configuration II

Multi page configuration

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',

  // entry: [
  //   './src/app.js',
  //   './src/app2.js',
  //   'lodash'
  // ],

  entry: {
    main: {
      import: ['./src/app2.js', './src/app.js'],
      dependOn: 'lodash',
      filename: 'chanel1/[name].js'
    },
    main2: {
      import: './src/app3.js',
      dependOn: 'lodash',
      filename: 'chanel2/[name].js'
    },
    lodash: {
      import: 'lodash',
      filename: 'common/[name].js'
    }
  },

  output: {
    clean: true
  },


  plugins: [
    new HtmlWebpackPlugin({
      title: 'Multi page application',
      template: './index.html',
      inject: 'body',
      filename: 'chanel1/index.html',
      chunks: ['main', 'lodash'],
      publicPath: 'http://www.b.com'
    }),

    new HtmlWebpackPlugin({
      template: './index2.html',
      inject: 'body',
      filename: 'chanel2/index2.html',
      chunks: ['main2', 'lodash'],
      publicPath: 'http://www.a.com'
    })
  ]


}

Tree Shaking

Remove unused modules

Configure a usedExports

es2015 features

However, additional modules cannot be

Configure webpack

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'production',
  entry: './src/app.js',
  plugins: [
    new HtmlWebpackPlugin()
  ],

  optimization: {
    usedExports :true //open here 
  }
}

Configure two sideEffects

In packages JSON configuration

{
  "sideEffects": true, //true will be loaded and false will not be loaded
  "sideEffects": ["*.css"], //All css files are loaded, and others are not loaded
  "sideEffects": ["*.css", "*.global.js"],//For all css files and global.js files are loaded, others are not loaded
}

Run in offline environment

Run in non offline environment

Packaging complete

Install HTTP server

npm i http-server -D

Configure packages json

"scripts": {
    "start": "http-server dist"
  },

Make the webpack serve runtime change packaging instead of memory

webpack configuration

devServer: {
    devMiddleware: {
      writeToDisk: true
    }
  }

Add workbox to implement pwa

install

npm i workbox-webpack-plugin -D

to configure

const HtmlWebpackPlugin = require('html-webpack-plugin')
const WorkboxPlugin = require('workbox-webpack-plugin')

module.exports = {
  mode: 'production',
  entry: './src/app.js',
  plugins: [
    new HtmlWebpackPlugin(),
    new WorkboxPlugin.GenerateSW({
      clientsClaim: true,
      skipWaiting: true
    })
  ],

Browser registration

Entry file

app.js

if ('serviceWorker' in navigator) { //Does the browser support
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
      .then(registration => {
        console.log("SW login was successful")
        console.log(registration)
      })
      .catch(registrationError => {
        console.log("SW login has failed", registrationError)
      })
  })
}

shimming global variable

webpack configuration

const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  plugins:[
    new HtmlWebpackPlugin(),
    new webpack.ProvidePlugin({
      _: 'lodash'
    })
  ]
}

Use index js

// import _ from 'lodash' / / no need to import

console.log(_.join(['hello', 'webpack'], ' '))

Fine particle size shimming

this problem imports loader

install

npm i imports-loader -D

Configure webpack

const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  plugins:[
    new HtmlWebpackPlugin(),
    new webpack.ProvidePlugin({
      _: 'lodash'
    })
  ],
  module: {
    rules: [
      {
        test: require.resolve('./src/index.js'),
        use: 'imports-loader?wrapper=window' //Let this in the bag point to window
      }
    ]
  }
}

Global exports

Plug in exports loader

npm i exports-loader -D

Configuring with webpack

module: {
    rules: [
      {
        test: require.resolve('./src/index.js'),
        use: 'imports-loader?wrapper=window'
      },
      {
        test: require.resolve('./src/global.js'),
        use: 'exports-loader?type=commonjs&exports=file,multiple|helpers.parse|parse' //Equivalent to exposing parse: helper parse
      }
    ]
  }

polyfills gasket

Simple principle

It cannot be introduced like this

Install @ babel/polyfill

npm i @babel/polyfill -D
import '@babel/polyfill' //The gasket is introduced into X in this way

console.log(Array.from([1, 2, 3], x => x + x))

Further optimization

Install babel environment

npm i babel-loader @babel/core @babel/preset-env -D

Configure webpack

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  entry: './src/index.js',

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
                {
                  targets: [
                    'last 1 version', //The latest version of the browser
                    '> 1%' //Code usage exceeds 1%
                  ],
                  useBuiltIns: 'usage',
                  corejs: 3
                }
              ]
            ]
          }
        }
      }
    ]
  }

}

Additional installation

npm install --save core-js@3

library

Packaged and configured as different modules

const path = require('path')

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  experiments: {
    outputModule:true // module to enable this configuration
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'mylib.js',
    library: {
      // Name: 'mylib', / / cancel this configuration when module
      type: 'module'  // window/commonjs/module
    }
  }
}

Packaged as a general module

const path = require('path')

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  // experiments: {
  //   Outputmodule: true / / enable this configuration when module
  // },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'mylib.js',
    library: {
      // Name: 'mylib', / / cancel this configuration when module
      type: 'umd'  // window/commonjs/module/umd
    },
    globalObject: 'globalThis' //Global this instead of self
  }
}

Building small wheels

to configure

const path = require('path')

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'webpack-numbers.js',
    library: {
      name: 'webpackNumbers',
      type: 'umd'
    },
    globalObject: 'globalThis'
  },
  externals: { //Optimization dependency
    lodash: {
      commonjs: 'lodash',
      commonjs2: 'lodash',
      amd: 'lodash',
      root: '_'
    }
  }

}

Publish as NPM package

implement

npm config get registry

Ensure for

"https://registry.npmjs.org/"

If not, switch npm set registry“ https://registry.npmjs.org/"

npm adduser add user

npm publish

Module Federation multi project sharing module

ModuleFederationPlugin using webpack

Prepare two modules first

Module nav

Component JS header js

const Header = () =>{
  const header = document.createElement('h1')
  header.textContent = 'Public header content'
  return header
}

export default Header

webpack configuration item

const HtmlWebpackPlugin = require('html-webpack-plugin')
const { ModuleFederationPlugin } = require('webpack').container


module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [
    new HtmlWebpackPlugin(),

    new ModuleFederationPlugin({
      name: 'nav', //Module name
      filename: 'remoteEntry.js', //Module file name
      remotes: {}, //Introduced module
      exposes: { //Exported module
        './Header': './src/Header.js' //Module path
      },
      shared: {} //Shared package
    })
  ]

}

nav module home introduction

webpack configuration item

const HtmlWebpackPlugin = require('html-webpack-plugin')
const { ModuleFederationPlugin } = require('webpack').container

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [
    new HtmlWebpackPlugin(),

    new ModuleFederationPlugin({
      name: 'home', //Module name
      filename: 'remoteEntry.js', //Module file name
      remotes: { //Introduced module
        nav: 'nav@http://localhost:3003/remoteEntry.js' / / network location
      },
      exposes: {}, //Exported module
      shared: {} //Shared package
    })
  ]
}

Use Header under nav

Asynchronous loading

import HomeList from "./HomeList";

import('nav/Header').then((Header)=>{
  const body = document.createElement('div')
  body.appendChild(Header.default())
  document.body.appendChild(body)
  document.body.innerHTML += HomeList(5)
})

The module search introduces two resources

Expose the homeList component of home

new ModuleFederationPlugin({
      name: 'home',
      filename: 'remoteEntry.js',
      remotes: {
        nav: 'nav@http://localhost:3003/remoteEntry.js'
      },
      exposes: {
        './HomeList': './src/HomeList.js'
      },
      shared: {}
    })

Import in webpack configuration item

const HtmlWebpackPlugin = require('html-webpack-plugin')
const { ModuleFederationPlugin } = require('webpack').container

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [
    new HtmlWebpackPlugin(),

    new ModuleFederationPlugin({
      name: 'search',
      filename: 'remoteEntry.js',
      remotes: {
        nav: 'nav@http://localhost:3003/remoteEntry.js',
        home: 'home@http://localhost:3001/remoteEntry.js'
      }
    })
  ]
}

Introduce index. In search js

Promise.all([import('nav/Header'),import('home/HomeList')])
  .then(([
    {
      default: Header
    },
    {
      default: HomeList
    }
  ]) => {
    document.body.appendChild(Header())
    document.body.innerHTML += HomeList(3)
  })

Promise.all() can perform multiple asynchronous operations

optimization

Use the latest version

webpack and the latest version of nodejs

Built in optimization

Apply the loader to the minimum number of necessary modules

Analyze the necessary information and improve the packaging speed

{
  test: /\.js$/,
  include: 'xxxxxx',
  loader: 'xxx'
}

You don't need to boot without loader and plugin

analysis

Reduce resolve, modules, resolve extensions,resolve. mainFiles,resolve. Number of entries in descriptionfiles

To reduce the number of system file calls

If you do not use symlinks, set resolve symlinks: false

If you customize the resolve plugin rule and do not specify a context, you can set resolve cacheWithContext:false

Small is fast

Use fewer or smaller libraries

Use splitChunksPlugin in multi page applications and start async

Remove unreferenced code

Compile only the code currently under development

Persistent cache

Use the cache option in the webpack configuration and use package "postinstall" in JSON clears the cache directory

Setting the cache type to memory or file system memory option is simple. It tells webpack to store the cache in memory

cache: {

type: 'memory'

}

Custom plugin/loader

Profile them to avoid introducing performance issues here

Weigh the pros and cons of progress plugin

General build optimization dll

Generate package into dll

const path = require('path')
const webpack = require('webpack')

module.exports = {
  mode: 'production',
  entry: {
    jquery: ['jquery']
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dll'),
    library: '[name]_[hash]'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_[hash]',
      path: path.resolve(__dirname, 'dll/manifest.json')
    })
  ]
}

introduce

const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const path = require('path')

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [
    new HtmlWebpackPlugin(),
    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, './dll/manifest.json')
    })
  ]
}

It cannot be used at this time

Additional configuration

const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const path = require('path')
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  plugins: [
    new HtmlWebpackPlugin(),
    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, './dll/manifest.json')
    })
    ,
    new AddAssetHtmlPlugin({
      filePath: path.resolve(__dirname, './dll/jquery.js'),
      publicPath: './'
    })
  ]
}

worker pool

Note that multiple loader s run from bottom to top

Using thread loader

For very time-consuming loader s

Because worker s also consume resources

// const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  entry: './src/index.js',

  module: {
    rules:[
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options:{
              presets: ['@babel/preset-env']
            }
          },
          {
            loader: 'thread-loader',
            options: {
              workers: 2
            }
          }
        ]
      }
    ]
  }


}

Development environment improves build performance

Use the watch mode of webpack

cpu load caused by excessive listening

Available watchoptions Poll to increase the polling interval

Compile in memory

webpack-dev-server

webpack-hot-middleware

webpack-dev-middleware

stats. Tojason acceleration

devtool

eval performs best but cannot be translated

The soap source map is a slightly worse map, but the performance is good

Eval source map incremental compilation

In most cases, it is Eval heap module source map

Avoid using tools from the production environment

such as

TerserPlugin compression and obfuscation

fullhash/chunkhasn/contenthash

AggressiveSplittingPlugin

AggressiveMergingPlugin

ModuleConcatenationPlugin

Minimize entry chunk

optimization: { runtimeChunk: true }

Avoid additional optimization steps

optimization: { 
  removeAvailableModules: false,
  removeEmptyChunks: false,
  splitChunks: false
}

Output results without path information

output: {
  pathinfo: false
}

nodejs version

v8.9.10-v9.11.1 performance fallback

ts-loader

plus

use: [
  {
    loader: 'ts-loader',
     options: {
      transpileOnly: true
    }
  }
]

Production environment improves build performance

Do not enable SourceMap

Topics: Webpack