webpack5 learning notes
Watching the video of Qianfeng education in station b feels very good
cdn resources cdn resources
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
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