HMR hot module replacement / module hot replacement
Function: when a module changes, it will only update the module (not package all) to improve the speed
Style file: you can use the HRM function because the style loader is implemented internally
js file: no HRM by default
html file: there is no HRM by defau lt, and the html file cannot be hot updated (local code cannot be recompiled) < just one file, no HMR function is required >
- Solution: modify the entry entry and import html files
const {resolve}=require('path'); const HtmlWebpackPlugin=require('html-webpack-plugin'); module.export={ entry:['./src/index.js','./src/index.html'], output:{ filename:'built.js', path:resolve(_dirname,'build') }, module: { rules: [ module: { rules: [ //Detailed loader configuration { //Handling css resources test:/\.css$/, use:[ 'style-loader',//(it's a package) 'css-loader',//(it's a package) ] }, { //Handling less resources test:/\.less$/, use:[ 'style-loader',//(it's a package) 'css-loader',//(it's a package) 'less-loader' ] }, { //Processing picture resources test:/\.(jpg|png|gif)$/, loader:'url-loader' options:[ limit:8*1024 name:'[hash:10].[ext]', //Turn off es6 modularization esModule:false, outputPath:'imgs'//Change output path ] }, { test:/\.html$/, //Processing img images of html files loader:'html-loader' name:'[hash:10].[ext]' }, { //Package other resources exclude:/\.(css|js|html|less|jpg|png|gif)$/, loader:'file-loader', //Modify name options:{ name:'[hash:10],[ext]' }, ] }, //Configuration of plugin plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html' }) ], //pattern mode:'development' devServer:{ //Path after project construction contentBase:resolve(_dirname,'build'), //Start gzip compression compress:true, //Port number port:3000, //Open browser automatically open:true, //Turn on HMR function //When the webpack configuration is modified, be sure to restart the webpack service hot:true } }
js thermal module
Write in the index.js file
For non portal files js import print from './print'; if(module.hot){ //Once module.hot is true, the HMR function is enabled -- > to make the HMR function code take effect module.hot.accept('./print.js',function(){ //Method listens for changes in the print.js file. Once changes occur, other modules will not be repackaged and built, and the following callback functions will be executed print(); }
Debugging code in development environment (source map)
A technology that provides source code to post build code to mapping (if the post build code is wrong, it can be traced to the directory of source code through mapping)
[inline-|hidden-|eval-][nosources-][cheap-[module]]source-map
- Source map: Outreach
Prompt the accurate information of the error code and the error location of the source code - Inline source map: inline: only one source map is generated
Prompt the accurate information of the error code and the error location of the source code - Hidden source map: Outreach
Prompt the error code and error reason, but there is no error location, and the source code error cannot be traced - Eval source map: inline: each file generates a corresponding source map in the eval function
Prompt the accurate information of the error code and the error location of the source code - Mosources source map: Outreach
Prompt the accurate information of the error code, and there is no source code error location - Soap source map: Outreach
Prompt the accurate information of the error code and the error location of the source code, which can only be accurate to the line - Soap module source map: Outreach
Prompt the accurate information of the error code and the error location of the source code
1. Production environment: fast and friendly debugging (inlining will make the code large, so it is excluded) source map
2. Development environment: source code hiding? Mode friendly? eval-source-map
Differences between inline and extranet 1. Files are generated externally, but not inline 2. Inline construction is faster
const {resolve}=require('path'); const HtmlWebpackPlugin=require('html-webpack-plugin'); module.export={ entry:['./src/index.js','./src/index.html'], output:{ filename:'built.js', path:resolve(_dirname,'build') }, module: { rules: [ module: { rules: [ //Detailed loader configuration { //Handling css resources test:/\.css$/, use:[ 'style-loader',//(it's a package) 'css-loader',//(it's a package) ] }, { //Handling less resources test:/\.less$/, use:[ 'style-loader',//(it's a package) 'css-loader',//(it's a package) 'less-loader' ] }, { //Processing picture resources test:/\.(jpg|png|gif)$/, loader:'url-loader' options:[ limit:8*1024 name:'[hash:10].[ext]', //Turn off es6 modularization esModule:false, outputPath:'imgs'//Change output path ] }, { test:/\.html$/, //Processing img images of html files loader:'html-loader' name:'[hash:10].[ext]' }, { //Package other resources exclude:/\.(css|js|html|less|jpg|png|gif)$/, loader:'file-loader', //Modify name options:{ name:'[hash:10],[ext]' }, ] }, //Configuration of plugin plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html' }) ], //pattern mode:'development' devServer:{ //Path after project construction contentBase:resolve(_dirname,'build'), //Start gzip compression compress:true, //Port number port:3000, //Open browser automatically open:true, //Turn on HMR function //When the webpack configuration is modified, be sure to restart the webpack service hot:true }, //Add something devtool:'eval-source-map' }
oneOf
Improve construction speed
//When a file is processed by multiple loaders, it is necessary to specify the order of execution of loaders in js (execute eslint first and then babel) const {resolve}=require('path'); const HtmlWebpackPlugin=require('html-webpack-plugin'); const MiniCssExtractPlugin=require('mini-css-extract-plugin'); const OptimizeCssAssetsWebpackPlugin=require('optimize-css-assets-webpack-plugin'); //Reuse loader const commonCssLoader=[ MiniCssExtractPlugin.loader, 'css-loader', {//For compatibility, define browserlist in package.json loader:'postcss-loader', //Modify configuration potions:{ ident:'postcss', plugins:()=>[ //postcss plug-in require('postcss-preset-env')() ] } } ]; module.export={ entry:'./src/index.js', output:{ filename:'built.js', path:resolve(_dirname,'build') }, module: { rules: [ { test:/.js$/, exclude:/node_modules/, loader:'eslint-loader', //Meaning of priority implementation enforce:'pre' options:{ //Automatically fix eslint errors fix:true }, oneOf:[//Only one of the following loader s will match. Two configurations cannot process files of the same type { test:/\.css$/, use:[commonCssLoader] }, { test:/\.less$/, use:[...commonCssLoader, 'less-loader'] }, {//Eslintconfig -- > airbnb in package.json test:/.js$/, exclude:/node_modules/, loader:'eslint-loader', options:{ presets:[ [ '@babel/preset-env', { useBuiltIns:'usage', //Specify corejs version corejs:{ version:3 }, //Which version of browser is compatible targets:{ chrome:'60', firefox:'60', ie:'9', safari:'10', edge:'17' } } ] ] ] } }, { test:/\.(jpg|png|gif)$/, loader:'url-loader', options:{ limit:8*1024, name:'[hash:10].[text]', outputath:'imgs', esModule:false } },//img in html { test:/\.html$/, loader:'html-loader' }, { //Package other resources exclude:/\.(css|js|html|less|jpg|png|gif)/, loader:'file-loader', options:{ outputPath:'media', name:'[hash:10],[ext]' } }, }, //Configuration of plugin plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html', //Compress the html code, which compresses the configuration minify:{ //Collapse spaces collapseWhitespace:true, //Remove comment removeComments:true } }), new MiniCssExtractPlugin({ //If you want to enter / rename into the css directory filename:'css/built.css' }), //Compressing css: will run faster new OptimizeCssAssetsWebpackPlugin(), ], //Automatic compression of js code in production mode mode:'production' }
cache
- babel: CacheDirectory:true – > make the second package build faster
- File resource modify file name hash: a unique hash value is generated each time the webpack is built and packaged
Problem: because js and css use the same hash value, repackaging will invalidate all caches
Chunk hash: the hash value generated by chunk. If the package comes from the same trunk, the hash value is the same
Problem: the hash values of js and css are the same. Because css is introduced in js, it belongs to the same trunk
What is a trunk? All js and css imported according to the entry file will use a trunk, which is a code block
contenthash: the hash generated according to the contents of the file. The hash values of different files must be different – > make the code run online and cache faster
//When a file is processed by multiple loaders, it is necessary to specify the order of execution of loaders in js (execute eslint first and then babel) const {resolve}=require('path'); const HtmlWebpackPlugin=require('html-webpack-plugin'); const MiniCssExtractPlugin=require('mini-css-extract-plugin'); const OptimizeCssAssetsWebpackPlugin=require('optimize-css-assets-webpack-plugin'); //Reuse loader const commonCssLoader=[ MiniCssExtractPlugin.loader, 'css-loader', {//For compatibility, define browserlist in package.json loader:'postcss-loader', //Modify configuration potions:{ ident:'postcss', plugins:()=>[ //postcss plug-in require('postcss-preset-env')() ] } } ]; module.export={ entry:'./src/index.js', output:{ filename:'built.[hash:10].js', //The generated resource has a hash value path:resolve(_dirname,'build') }, module: { rules: [ { test:/.js$/, exclude:/node_modules/, loader:'eslint-loader', //Meaning of priority implementation enforce:'pre' options:{ //Automatically fix eslint errors fix:true }, oneOf:[//Only one of the following loader s will match. Two configurations cannot process files of the same type { test:/\.css$/, use:[commonCssLoader] }, { test:/\.less$/, use:[...commonCssLoader, 'less-loader'] }, {//Eslintconfig -- > airbnb in package.json test:/.js$/, exclude:/node_modules/, loader:'eslint-loader', options:{ presets:[ [ '@babel/preset-env', { useBuiltIns:'usage', //Specify corejs version corejs:{ version:3 }, //Which version of browser is compatible targets:{ chrome:'60', firefox:'60', ie:'9', safari:'10', edge:'17' } } ] ], //Enable babel cache //On the second build, the previous cache is read CacheDirectory:true ] } }, { test:/\.(jpg|png|gif)$/, loader:'url-loader', options:{ limit:8*1024, name:'[hash:10].[text]', outputath:'imgs', esModule:false } },//img in html { test:/\.html$/, loader:'html-loader' }, { //Package other resources exclude:/\.(css|js|html|less|jpg|png|gif)/, loader:'file-loader', options:{ outputPath:'media', name:'[hash:10],[ext]' } }, }, //Configuration of plugin plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html', //Compress the html code, which compresses the configuration minify:{ //Collapse spaces collapseWhitespace:true, //Remove comment removeComments:true } }), new MiniCssExtractPlugin({ //If you want to enter / rename into the css directory filename:'css/built.css' }), //Compressing css: will run faster new OptimizeCssAssetsWebpackPlugin(), ], //Automatic compression of js code in production mode mode:'production' }
tree shaking
Remove code that is not used in the application
Prerequisites: 1. You must use es6 modularization. 2. Start the production environment
Function: reduce code volume
Configure in package.json
"sideEffects":false;//All codes have no side effects (tree shaking can be performed) //Problem: can you kill the css/ @babel/polyfill file "sideEffects":["*.css","*.less"];//solve
code split
module.export={ //Single entry // entry:'./src/index.js', entry:{ //Multiple entries: with one entry, the final output will have a bundle main:'./src/index.js', test:'./src/test.js', } output:{ //[name] get file name filename:'built.[name].[hash:10].js', //The generated resource has a hash value path:resolve(_dirname,'build') }, //Configuration of plugin plugins:[ ], //Node can be_ The code in modules is packaged separately into a chunk final output //Automatically analyze whether there are public files in multi entry files. If there are, they will be packaged into a separate trunk optimzation:{ splitChunks:{ chunks:'all' } } //Automatic compression of js code in production mode mode:'production' }
The third way is to package a file into a trunk through js code
On the index.js page
Import dynamic import syntax: a file can be packaged separately
import('./test') .then(()=>{ //File loaded successfully }) .catch(()=>{ //File loading failed })
Lazy loading and preloading
Lazy loading of js files (only when certain conditions are triggered)
//Lazy loading -- it is placed in the function and loaded when the function is called: it is loaded only when it needs to be loaded //Preload prefetch: the js file will be loaded in advance //Normal loading can be considered as parallel loading (loading multiple files at one time) preloading: when other resources are loaded and the browser is idle, download them secretly //'/ * webpackChunkName:'test',webpackPrefetch:true * /' split into two files import('/*webpackChunkName:'test'*/'./test').then(()=>{ console.log('Loading succeeded after a period of time') }
PWA (progressive network development application)
It can also be accessed offline
workbox download package
//When a file is processed by multiple loaders, it is necessary to specify the order of execution of loaders in js (execute eslint first and then babel) const {resolve}=require('path'); const HtmlWebpackPlugin=require('html-webpack-plugin'); const MiniCssExtractPlugin=require('mini-css-extract-plugin'); const OptimizeCssAssetsWebpackPlugin=require('optimize-css-assets-webpack-plugin'); const WorkboxWebpackPlugin=require('workbox-webpack-plugin'); //Reuse loader const commonCssLoader=[ MiniCssExtractPlugin.loader, 'css-loader', {//For compatibility, define browserlist in package.json loader:'postcss-loader', //Modify configuration potions:{ ident:'postcss', plugins:()=>[ //postcss plug-in require('postcss-preset-env')() ] } } ]; module.export={ entry:'./src/index.js', output:{ filename:'built.[hash:10].js', //The generated resource has a hash value path:resolve(_dirname,'build') }, module: { rules: [ { test:/.js$/, exclude:/node_modules/, loader:'eslint-loader', //Meaning of priority implementation enforce:'pre' options:{ //Automatically fix eslint errors fix:true }, oneOf:[//Only one of the following loader s will match. Two configurations cannot process files of the same type { test:/\.css$/, use:[commonCssLoader] }, { test:/\.less$/, use:[...commonCssLoader, 'less-loader'] }, {//Eslintconfig -- > airbnb in package.json test:/.js$/, exclude:/node_modules/, loader:'babel-loader', options:{ presets:[ [ '@babel/preset-env', { useBuiltIns:'usage', //Specify corejs version corejs:{ version:3 }, //Which version of browser is compatible targets:{ chrome:'60', firefox:'60', ie:'9', safari:'10', edge:'17' } } ] ], //Enable babel cache //On the second build, the previous cache is read CacheDirectory:true ] } }, { test:/\.(jpg|png|gif)$/, loader:'url-loader', options:{ limit:8*1024, name:'[hash:10].[text]', outputath:'imgs', esModule:false } },//img in html { test:/\.html$/, loader:'html-loader' }, { //Package other resources exclude:/\.(css|js|html|less|jpg|png|gif)/, loader:'file-loader', options:{ outputPath:'media', name:'[hash:10],[ext]' } }, }, //Configuration of plugin plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html', //Compress the html code, which compresses the configuration minify:{ //Collapse spaces collapseWhitespace:true, //Remove comment removeComments:true } }), new MiniCssExtractPlugin({ //If you want to enter / rename into the css directory filename:'css/built.css' }), //Compressing css: will run faster new OptimizeCssAssetsWebpackPlugin(), new WorkboxWebpackPlugin.GenerateSW({ //Help service worker start quickly //Delete old serviceworker //Generate a serviceworker configuration file clientsClaim:true, skipWaitting:true }) ], //Automatic compression of js code in production mode mode:'production' }
Register serviceworker
In the entry file
//Note: 1.eslint doesn't know window. navigator global variable Solution: repair required package.json in eslintConfig to configure 2.sw The agent must run on the server-->nodejs -->npm i serve -g serve -s build Start the server, and the build All resources in the directory are exposed as static resources "env":{ "browser":true//Support browser side global variables }// //Register serviceworker //Handling compatibility issues if('serviceworker' in navigator){ window.addEventListener('load',()=>{ navigator.serviceworker.register('/service-worker.js') .then(()=>{ console.log('Registration succeeded') }) .catch(()=>{ console.log('Registration failed') }) }
Multi process packaging
Download thread loader, usually for Babel loader
{//Eslintconfig -- > airbnb in package.json test:/.js$/, exclude:/node_modules/, use:[ //Start multi process packaging. The process has time to start, about 600ms. The process communication also has overhead //Only when the work takes a long time, multi process packaging is required 'thread-loader', //Modify configuration options:{ workers:2//2 processes } { loader:'babel-loader', options:{ presets:[ [ '@babel/preset-env', { useBuiltIns:'usage', //Specify corejs version corejs:{ version:3 }, //Which version of browser is compatible targets:{ chrome:'60', firefox:'60', ie:'9', safari:'10', edge:'17' } } ] ], //Enable babel cache //On the second build, the previous cache is read CacheDirectory:true ] } } ], },
externals and dill (Dynamic Link Library)
The difference is: dill packages the library separately, some do not package, and some split and package into multiple libraries
const {resolve}=require('path'); const HtmlWebpackPlugin=require('html-webpack-plugin'); const webpack=require('webpack'); const AddAssetHtmlWebpackPlugin=require('add-asset-html-webpack-plugin'); module.export={ entry:'./src/index.js', output:{ filename:'built.[hash:10].js', //The generated resource has a hash value path:resolve(_dirname,'build') }, module: { rules: [] }, //Configuration of plugin plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html', }), //Tell webpack which libraries do not participate in packaging, and change their names when using them new webpack.DillPlugin({ mainfes:resolve(_dirname,'dill/mainfest.json'), //Package and output a file and introduce the resource into html new AddAssetHtmlWebpackPlugin({ filepath:resolve(_dirname,'dill/jquery.json'), }) ], //Automatic compression of js code in production mode mode:'production', externals:{//fast //Reject package package -- npm package jquery:'jQuery' } } stay index.js Page introduction
Dill package, create webpack.dill.js
Use dill technology to package some libraries separately (jQuery, react, vue...)
Run – > webpack -- config webpack.dill.js
const {resolve}=require('path'); const webpack=require('webpack'); module.export={ entry:{//The final package generates [name] -- > jQuery //['jquery '] -- > the library to package is jQuery jquery:['jquery'] }, output:{ filename:'[name].js', path:resolve(_dirname,'dill'), libiary:'[name]_[hash]',//The name of the content exposed to the outside in the packaged library }, plugins:[ new webpack.DillPlugin({ name:'name_[hash]',//The exposed content name of the mapping library path:resolve(_dirname,'dill/mainfest.json'),//Output file path ], mode:'production' }