Development environment optimization

Hot Module replacement (HMR) Hot module replacement

  • What it does: Changes to a module will only repackage the module (otherwise unchanged), increasing build speed
  • Style files: You can use the HMR functionality because it is implemented internally using style-loader
  • Js file: HMR function cannot be used by default — need to modify Js code, add code supporting HMR function

Note: the HMR function can only handle JS files that are not entry JS files.

  • HTML files: HMR cannot be used by default, and this causes problems: HTML files cannot be hot updated. Solution: Modify the entry entry to import the HTML file
const webpack = require('webpack')

module.exports = {
   ...
   devServer:{
      hot:true,
      hotOnly:true
   },
   plugins:{
     new webpack.HotModuleReplacementPlugin()
   }
   
}
Copy the code

source map

Source Map: A technique that provides source-to-build code mapping (mapping to trace source code errors if errors occur after a build)

module.exports = {
   ....
   devtool:'source-map'
}
Copy the code

Production environment optimization

oneOf

  • A file cannot be matched by multiple loaders
  • Note: You cannot have two configurations that handle the same type of file

For example, for eslint-loader and babelLoader for JS files, you can place the eslint-loader that executes first above oneOf

module.exports = {
  ...
  rules:[
   {
     test:/\.js$/,
     loader:'eslint-loader',
   }
   oneOf:[
     {
       test:/\.js$/,
       loader:'babel-loader',
     }
   ]
  ]
}

Copy the code

The cache

  • Babel Cache: cacheDirectory: True — makes the second packaged build faster
module.exports = { ... Rules :[{test:/\.js$/, loader:'babel-loader', options:{// enable Babel cache, cacheDirectory:true}}]}Copy the code
  • File resource cache

Hash: a unique hash value is generated each time a Webpack is built. Problem # 1: Since js and CSS use the same hash value at the same time, repackaging will invalidate all caches. Solution: chunkhash, hash value generated based on chunk. But there is still a problem: JS and CSS still have the same hash value, because CSS was introduced in JS, so it belongs to the same chunk. Solution: Contenthash: Generates hash values based on file contents. Different files have different hash values. –> Make the code run online cache easier to use

module.exports = {
   ...
   entry:'./src/index.js',
   output:{
     filename:'js/built.[contenthash:10].js'
   },
   ...
   plugins:[
     new MiniCssExtractPlugin({
        filename:'css/built.[contenthash:10].css'
     })
   ]
  
}
Copy the code

tree shaking

Condition: You must use Es6 modularization to enable the Production environment

Configure "sideEffects" in package.json :false all code has no sideEffects Possible removal of CSS /@babel/polyfill "sideEffects":[".css",".less"]Copy the code

The separation of

  • Code split

What it does: You can separate code into bundles to load files on demand or in parallel. Code separation can be used to obtain smaller bundles and control resource loading priorities to improve load times.

  • bundle split

Process: Create multiple smaller files and load them in parallel for better caching. Function: enable the browser to download in parallel, improve the download speed. With the browser cache, whenever the code is modified and the hash value in the file name is changed, it will be reloaded.

PWA(Progressive Web Application) offline access technology

The Webpack configuration uses the workbox-webpack-plugin to generate a serviceWorker profile

NPM I worker-webpack-plugin const worboxWebpackPlugin = require('worker-webpack-plugin') module.exports = { ... Plugins: [new WorkboxWebpackPlugin GenerateSW ({/ / generates a serviceworker clientsClaim configuration file: true, / / help serviceworker fast start SkipWaiting: true, If (' serviceworker 'in navigator){// Delete old serviceworker})]} window.addEventListener('load',()=>{ navigator.serviceWorker.register('/service-worker.js') .then(()=>{ // do something }).catch(()=>{// do something})})} Modify the eslintConfig configuration in package.json (because eslint does not recognize global variables like window,navigator, etc.) "eslintConfig":{ "Env ":{"browser":true,// supports browser global variables}} serviceWorker must be running on the server and needs to start the server 1: run via nodejs 2: Install NPM I serve-g serve-s build to start the server and expose all resources in the build directory as static resourcesCopy the code

externals

Prevent packages from being packaged into bundles and instead obtain these extension dependencies externally at run time

module.exports = { ... Externals :{// refuse to import jquery when packaging :' jquery ',}} but need to be imported manually in the index.html fileCopy the code