# Basic use of webpack s ## Style Resource Introduction import"index.css"
{ test: /\.css$/, use: [ // Create a style tag that adds style resources from js to the header and does not write directly to html, but through js execution 'style-loader', // //Load css into commonjs module into js, which contains style strings 'css-loader' ] }
file-loader, url-load for processing pictures in css and js
{ test: /\.(png|jpg|jpeg)$/, use: 'url-loader', options: { // When the picture size is less than 8KB, turn the picture to Base64, which will make the picture bigger limit: 8 * 1024 } }
- Package other resources
Font files, such as those in css, will be changed to MD5 after packaging
{ exclude: /\.(css|js|html)$/, loader: 'file-loader', options: { name: '[hash:10].[ext]' } }
Separate css files
The plugin min-css-extract-plugin used needs to be MinCssExtractPlugin instead of style-loader. Loader
{ test: /\.css$/, // Execution order in use is bottom to top use: [ MinCssExtractPlugin.loader, // Extract css from js and separate it into separate files // Load the css into commonjs module into js, which contains the style string 'css-loader', ] }, new MinCssExtractPlugin({ filename: 'public/index.css' })
Modify css compatibility
Introducing loader, postcss-loader, and plugin postcss-preset-env in loader
Help postcss in package. Configuration found in browserlist in JSON and related configuration found on postcss's official website
{ test: /\.css$/, // Execution order in use is bottom to top use: [ MinCssExtractPlugin.loader, // Extract css from js and separate it into separate files // Load the css into commonjs module into js, which contains the style string 'css-loader', { loader: 'postcss-loader', plugin: () => [ require('postcss-preset-env')() ] } ] },
package.json
"browserlist": { "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], "production": [ ">0.2%", "not dead", "not op_mini all" ] }
Environment variables are not environment variables in webpack, but environment variables in node, procss.env.NODE_ENV
Compress css
Plug-ins used
optimize-css-assest-webpack-plugin
Use
new OptimizeCssAssetsWebpackPlugin()
js grammar check
Dependent on eslint-loader eslint airbnb eslint-config-airbnb-base eslint-plugin-import
To configure
{ test: /\.js$/ loader: "eslint-loader", exclude: /node_modules/ options: { fix: ture // Automatically fix errors } }
Rules set in package. eslintConfig in JSON
There are rules on airbnb github
Ready-made eslint-config-airbnb on npm
es6 is commonly used, so use eslint-config-airbng-base
JavaScript Compatibility Processing
Use the plug-ins babel-loader, @babel/core
Basic compatibility handling
@babel/preset-env
{ loader: 'babel-loader', exclude: /node_modules/, options: { preset: ['@babel-preset-env'] } }
All Compatibility Processing
@babel/profill
import'@babel/profile'can be introduced in js, but it's all introduced
core-js introduced for on-demand loading
{ loader: 'babel-loader', exclude: /node_modules/, options: { preset: [ '@babel-preset-env', { useBuildIns: 'usage', // Specify coreJS version corejs: { version: 3 }, targets: { chrome: '60', firefox: '60', ie: '9', edge: '17' } } ] } }
Compress HTML
new HtmlWebpackPlugin({ template: './src/index.html', minify: { //Remove spaces collapseWhitespace: true, // Remove Comments removeCommnets: true } })
webpack performance optimization
overview
development environment
- Packaging build speed
- Optimize Code Debugging
production environment
- Optimize build packing speed
- Optimize running speed
HMR Module Thermal Replacement
A module change, a module change only updates the changed module
devServer: { content: resolve(__dirname, 'build'), compress: true, port: 3000, // open: true, hot: true // Turn on HMR mode },
Style file, need to use style-loader, style-loader internal implementation of HMR mode
js file, not in HMR mode by default
js code needs to be modified to add functionality for HMR
if(module.hot) { module.hot.accept('./print.js', function() { console.log('loader print.js'); }); }
HTMl file: no change
Solution introduced in entry, html changes, the whole will refresh
Debugging code source-map in development environment
In webpack. Config. Configuration under JS root object
{ devtool: 'inline-source-map' }
- source-map
Provides the exact location of error code and source code - inline-source-map inline to end of file
Basic agreement with source-map, just inline - hidden-source-map is outlined and generated separately. Map file
Hint error is the computer built and the cause of the error - eval-source-map Each produces a corresponding source-map, which is executed in the eval function
Consistent with inline-source-map - Outside nosources-source-map
Accurate information about the code was found, but no information about the source code was found - cheap-source-map external
It's similar to inline, but cheap just goes to the line of code, and inline finds the exact location - cheap-module-source-map external
The exact location of the error code, and the exact location of the source code, go home to loader's source-map to join
These can be combined in two groups
development environment
Speed Eval > inline > cheap
Fast
- eval-cheap-source-map
- eval-source-map (this is usually selected)
Debugging friendlier - source-map
- cheap-module-source-map
- cheap-source-map
oneOf
Modify rule in webpack
Only one loader will match, colleague
{ module: { rules: [ { test: /\.js$/ exclude: /node_modules/, enforce: 'pre', // Priority Execution loader: 'eslint-loader', options: { fix: true } }, { oneOf: [ ] } ] } }
// eslint-disable-next-line
Ignore warn for eslint check
cache
{ output: { filename: 'build.[hash:10].js', path: resolve(__dirname, 'build') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new MinCssExtractPlugin({ filename: 'public/index.[hash:10].css' }), new OptimizeCssAssetsWebpackPlgin() ], }
All are rebuilt when changes occur, and the associated hash changes because js and css use the same hash
babel cache catchDireactory:true
{ output: { filename: 'build.[chunkhash:10].js', path: resolve(__dirname, 'build') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new MinCssExtractPlugin({ filename: 'public/index.[chunkhash:10].css' }), new OptimizeCssAssetsWebpackPlgin() ], }
Rebuild all associations as well
Separate hash from file using contenthash
{ output: { filename: 'build.[contenthash:10].js', path: resolve(__dirname, 'build') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new MinCssExtractPlugin({ filename: 'public/index.[contenthash:10].css' }), new OptimizeCssAssetsWebpackPlgin() ], }
Code Tree Shake
Prerequisites must be es6, production environment, webpack automatic tree shaking
In package. Write sideEffects: false in json, all code can be tree shaking, which will erase the css file file
sideEffects:['*.css']
Code Split
Multi-entrance
{ entry: { index: './src/index.js', test: './src/test.js' }, output: { filename: './js/[name].[contenthash:10].js', path: resolve(__dirname,'dist') } }
Single entry
webpack.config.js root
Automatically analyze common files in multiple entries
optimization: { // Put node_ Code in modules is packaged separately into a chunk splitChunks: 'all' }
Package a file into a single chunk using js
import('./simple.js').then(() => { console.log('load success!'); });
Lazy load
import in code
btn.onclick = () => { import(/* webpackChunkname: 'test'*/).then(() => { console.log('load success!'); }); }
Preload
btn.onclick = () => { import(/* webpackChunkName: 'test', webpackPrefetch: true */).then(() => { console.log('load success!'); }); }
Offline Progressive Development of PWA
Using workbox Technology
Plug-in workbox-webpack-plugin
const WorkWebpackPlugin = require('work-webpack-plugin'); { Plugins: [ new WorkWebpackPlugin({ /* Help service worker get started quickly, delete old service worker Generate a serviceworker file */ clientClaim: true, skipWwaiting: true }); ] }
In code
if('serviceWorker' in navigater) { navigater.serviceWorker.register('./serviceworker.js').then(() => { console.log('regist successful'); }).catch(() => { console.log('regist error!'); }); }
Multiprocess Packaging
Used loader:thread-loader
Used in babel-loader
{ test: /\.js$/ exclude: /node_modules/, use: [ 'thread-loader', { loader: 'thread-loader', options: { workder: 2 // Two processes } }, { loader: 'babel-loader', exclude: /node_modules/, options: { preset: [ '@babel-preset-env', { useBuildIns: 'usage', // Specify coreJS version corejs: { version: 3 }, targets: { chrome: '60', firefox: '60', ie: '9', edge: '17' } } ] } ] }
There are both advantages and disadvantages
Opening also takes time, and communication between processes costs
Use only when work takes a lot of time
external
Some packages ignored when packaging
webpack.config.js root
externals: { // Ignore the specified package name, jquery jquery: }
dll
Package a library, third-party libraries can be packaged into different chunk s
webpack.dll.js
const { resolve } = require('path'); const webpack = require('webpack'); module.exports = { entry: { jquery: ['jquery'] }, output: { filename: '[name].js', path: resolve(__dirname, 'dll'), library: '[name]_[hash]' }, plugin: [ new webpack.DllPlugin({ name: '[name]_[hash]', // Name of Mapping Library path: resolve(__name, 'dll/manifest.json') // Provide mapping relationships for jquery packages }) ] }
webpack.config.js
const webpack = require('webpack'); const addAssetsHtmlWebpackPlugin = require('add-html-webpack-plugin'); { plugin: [ // Which libraries do not participate in high-speed webpack packaging and the name used will be changed new webpack.DllReferencPlugin({ manifest: resolve(__dirname, 'dll/manifest.json') }), new addAssetsHtmlWebpackPlugin({ filepath: resolve(__dirname, 'dll/jquery.js') }); ] }
Other
{ output: { filename: '/js/[name].js', path: resolve(__dirname, 'dist'), publicPath: '/', chunkFilename: '[name]_chunk.js', // The name of the non-entry chunk, labraryTarget: 'window' // node commonjs } }
resolve
{ resolve: { alias: { $css: resolve(__dirname, 'src/css') }, extensions: ['.js', '.json'], modules: [ 'node_modules', ] } }
devServer
{ // Project Build Catalog contentBase: resolve(__dirname, 'dist'), // Start gizp compression compress: true, // Good port port: 3000, // Open browser automatically open: true, // Turn on the HMR function, hot: true, // Monitor contentbase directory changes overload watchContentBase: true, // Do not start server logs clientLogLevel: 'none', quiet: true, // Do not print other unnecessary information watchOptions: { ignored: /node_modules/ }, overlay: false, // Do not prompt in full screen for errors. proxy: { '/api': { target: 'http://localhost:5000', pathRewrite: { '^/api': '' // Path Rewrite } } } }
optimizions
const TerserWebpackPlugin = requrie('terser-webpack-plugin'); { optimizions: { splitChunk: 'all', // miniSize: 30 * 1024, // Minimum split size maxSize: 0, // All split up, minChunck: 1, // Be introduced at least once maxAsyncRequest: 5, // Maximum number of parallel loads maxInitialRequest: 3, // Entry Maximum Request Parallel Number automaticNameDelimiter: "~",// Named Link Rule name: true, // You can use it, cacheGroups: { // Split chunk group // Node_ Files in modules are packaged in vendor vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { // The chunk to extract is referenced at least twice minChunk: 2, priority: -20, // If the current module to be packaged is the same as the module already extracted, reuse does not have to be packaged reuseExistingChunk: true, } }, // Package the hash values of the current module record other modules into a single file and run ntime file runtimeChunk: { name: entrypoint=> 'runtime-${entryport.name}' }, minimizer: [ new TerserWebpackPlugin( cache: true, // Open Cache parallel: true, // Open multiprocess packaging sourceMap: true ) ] } }