preface
Basic configurations can be divided into the following aspects: Entry, Output, Mode, Resolve, Module, Optimization, Plugin, Source Map, and Performance
Webpack has five core concepts
- Entry: Indicates which Entry point to start packaging, analyze and build internal dependency diagrams.
- Output: Where do the Output of packaged resource bundles go
- Loader: Handles non-JS files (Webpack itself only understands JS)
- Plugins: Plugins for a wider range of tasks. Package optimization, compression, redefinition of variables in the environment, etc.
- Mode: development Mode, production Mode
Webpack is a front-end resource builder, a static module bundle.
For Webpack, all resource files in the front end (js/ CSS /img/json/less/…) Will be treated as modules.
Webpack can handle JS and JSON resources, not CSS/IMG and other resources
The production and development environments compile the ES6 modularity into a modularity that the browser recognizes
The production environment has one more compressed JS code than the development environment
1. Configure entry
The entry point indicates which module webPack should use as a starting point for building its internal dependency Graph. Once at the entry point, WebPack finds out which modules and libraries are (directly and indirectly) dependent on the entry point.
The default is./ SRC /index.js, but you can specify one (or more) different entry starting points by configuring the Entry property in webpack Configuration. Such as:
1. Single entrance
- webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
// 或者
module.exports = {
entry: {
main: './path/to/my/entry/file.js'
}
};
Copy the code
2. Multi-entry (multi-page application)
- webpack.config.js
module.exports = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
};
Copy the code
2. Configure export output
The Output attribute tells WebPack where to export the bundles it creates and how to name those files. The default value for the main output file is./dist/main.js, and the other generated files are placed in the./dist folder by default.
- webpack.config.js
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
Copy the code
1. Basic configuration
- Path: The output directory corresponds to an absolute path. Destination path for all output files; Storage location of packaged files on hard disk)
- Filename: This option determines the name of each output bundle. These bundles will be written to the directory specified by the output.path option.
- ChunkFilename: This option determines the name of a non-entry chunk file and configures the file to be loaded on demand.
- PublicPath: WebPack provides a very useful configuration that helps you specify a base path for all resources in your project, called a publicPath. Resources: publicPath is a basic path for CSS, JS, img, and other resources….
Static resource access path = output.publicPath + Resource loader or plug-in configuration path
- .
2. Browser cache and hash value
For every application we develop, the browser caches the static resource, and if we update the static resource without updating the static resource name (or path), the browser may not get the updated resource due to caching issues. When we use WebPack for packaging, WebPack provides the concept of hash, so we can use hash for packaging.
When defining package names (e.g. chunkFilename, filename), we usually use hashes. Different hashes can be used in different scenarios:
- Hash [maximum range] is related to the construction of the entire project. Whenever a file changes in the project, the hash value of the entire project will change, and all files share the same hash value. It can be used in the development environment, but not in the production environment.
- Chunkhash performs dependency file parsing according to different Entry files, constructs corresponding chunks, and generates corresponding hash values. In the production environment, some public libraries and program Entry files are separated, and the code of the public library is packaged and built without changing, which can ensure that hash values are not affected. It is suitable for the production environment.
- Contenthash is associated with the contents of a single file. Using the contenthash value, as long as the contents of the current file remain unchanged, the build will not be repeated, as will the resulting file hash. Setting non-output filenames to hash or chunkhash (CSS, image, etc.) will not work, and contenthash is used by default, suitable for production environments.
Note:
- Use hashes in production whenever possible
- Chunks loaded on demand are not affected by filename and are affected by chunkFilename
- Use hash/chunkhash/contenthash usually cooperate with HTML – webpack – plugin (create the HTML, and bound to the corresponding package files), the clean – webpack – plugin (removal of old packing files) are used together.
Configure moudle.loader to parse and convert files
Webpack only understands JavaScript and JSON files. Loader enables WebPack to process other types of files and convert them into valid modules for use by applications and to be added to dependency diagrams.
At a higher level, loader has two properties in the webpack configuration:
- The test property identifies the files or files that should be converted by the corresponding loader.
- The use attribute indicates which loader should be used for conversion.
- webpack.config.js
Module. exports = {module: {rules: [// detailed loader configuration {// match which files test: /\.css$/, // which loaders to use: [// style-loader creates a style tag, inserts js style string resources into the HTML head to take effect 'style-loader', // css-loader converts CSS files into commonJS modules and loads them into JS modules. Style string 'CSS-loader ',],},],},}Copy the code
module.noParse
Indicating that WebPack does not parse something helps improve webPack build performance.
Module. exports = {module: {// indicates that webPack does not parse some content. NoParse: /jquery/, rules: []}}Copy the code
Sas-loader, less-loader, or stylus-loader
Process.scss/.sass,.less,.stylus/.styl files separately and compile them into CSS files
postcss-loader
Prefixes CSS styles for compatibility with different browsers.
css-loader
Css-loader handles @import and URL () just as JS interprets import/require().
style-loader
Style-loader is a javascript script that creates a style tag, contains some styles, and inserts CSS into the DOM.
Module. exports = {module: {rules: [{// handle less resources test: /\. ['style-loader', 'css-loader', 'less-loader'],}, {// / \. (JPG | PNG | | GIF jpeg) $/, / / the use of a loader: file - loader url - loader loader: 'url - loader, the options: {// Image size less than 8KB, will be base64 processing // advantages: reduce the number of requests, reduce the server stress // disadvantages: larger image size, slow request speed: 8 * 1024 / / [10] hash: take pictures of the hash top ten rename / / / ext file extension originally name: '[10] hash: [ext]',,}},],}},Copy the code
vue-style-loader
Based on style-loader fork, similar to style-loader.
The mini – CSS – extract – the plugin MiniCssExtractPlugin. Loader
Package the style file imported from JS import into a CSS file separately, and insert it into the HTML file in the form of link combined with htML-webpack-plugin. Note: this plug-in does not support HMR, if you modify the style file, it will not be displayed in the browser immediately, you need to manually refresh the page.
vue-loader
Plugins need to be configured synchronously to handle.vue files.
Const VueLoaderPlugin = require('vue-loader/lib/plugin') {rules: [// add parse.vue file {test: /\.vue$/, loader: 'vue-loader'},]}, plugins: [// vue-loader! New VueLoaderPlugin(),],}Copy the code
File-loader (deprecated with V5)
File-loader parses import/require () on a file into a URL and emits the file to the output directory.
Deprecated after V5: Consider using Asset Modules instead.
Url-loader (v5 deprecated)
Loader used to convert files to base64 URIs. If there are many images, many HTTP requests will be sent, which degrades page performance. Url-loader will encode the imported image and generate the dataURl.
Deprecated after V5: Consider using Asset Modules instead.
html-loader
Export HTML as a string. HTML is minimized when required by the compiler.
babel-loader
This package allows you to translate JavaScript files using Babel and Webpack.
cache-loader
Cache-loader allows caching of the following loaders to (default) disks or databases. Add cache-loaders before some performance expensive loaders to cache the results to disk.
thread-loader
Multi-process packaging. To use this loader, place it before other loaders. Loaders placed after this loader will run in a separate worker pool.
val-loader
Executes the given module to generate source code at build time.
gzip-loader
Gzip loader module for Webpack
i18n-loader
internationalization
4. Configure plugins
Loaders are used to transform certain types of modules, while plugins can be used to perform a wider range of tasks. Including: package optimization, resource management, injection of environment variables.
Module.exports = {plugins: [// detailed plugins],}Copy the code
html-webpack-plugin
Used to compile htML-type files in a Webpack project
plugins: [// html-webpack-plugin // function: create an empty HTML file by default, automatically import output packaged all resources (JS/CSS) // requirements: New HtmlWebpackPlugin({// copy./ SRC /index.html file and automatically import package output all resources (js/ CSS) template: './src/index.html', }), ]Copy the code
copy-webpack-plugin
Copy/copy the plug-in to copy a single file or the entire directory (which already exists) to the build directory.
mini-css-extract-plugin
This plugin extracts CSS into a separate file, creates a CSS file for each JS file containing CSS, and supports on-demand loading of CSS and SourceMaps.
optimize-css-assets-webpack-plugin
Compress a single CSS file to optimize or compress CSS resources
css-minimizer-webpack-plugin
This plugin uses CSSNano to optimize and compress CSS. It’s like the optimize-CSS-assets-webpack-plugin, but using query strings in Source maps and Assets is more accurate, enabling caching and concurrent mode.
webpack. DefinePlugin
DefinePlugin lets you create configured global constants at compile time, which is useful when you need to differentiate between development mode and production mode.
VueLoaderPlugin
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’)
add-asset-html-webpack-plugin
Add vendor.dll.js to HTML dynamically using add-asset-html-webpack-plugin
webpack. HotModuleReplacementPlugin()
Enable Hot Module Replacement – HMR
uglifyjs-webpack-plugin
The UglifyJS Webpack Plugin is used to shrink (compress and optimize) JS files. Webpack 4 previous version by webpack. Optimize the CommonsChunkPlugin to compress js, webpack was removed after 4 version, use the config. Optimization. SplitChunks instead.
terser-webpack-plugin
The plug-in uses Terser to compress JavaScript.
webpack-bundle-analyzer
Package volume analysis
speed-measure-webpack-plugin
Baling speed analysis
webpack-parallel-uglify-plugin
ParallelUglifyPlugin enables multiple sub-processes to compress files, but each of them still compresses the code using UglifyJS. Is nothing more than the parallel processing of the compression, parallel processing of multiple sub-tasks, the efficiency will be more improved. However, this plugin is not officially maintained by Webpack, has not been updated for a year now, and does not support old projects.
terser-webpack-plugin
ParallelUglifyPlugin uses Terser to compress JavaScript. ParallelUglifyPlugin is the same as ParallelUglifyPlugin, and is recommended by WebPack4. It can be maintained by specific personnel, and can be configured directly in Optimization
5. Configuration mode
- Mode can be None, development, or production
1. Mode: Production default
// webpack.prod.config.js module.exports = {performance: {// Set performance: {hints: 'warning'}, output: }, optimization: {// Debug namedModules without readable module identifiers: False, // debug namedChunks without readable block identifiers: false, // set process.env.node_env to production nodeEnv: 'production', // flags whether a block is a subset of another block // controls the size of the chunks loaded (no subsets are loaded when larger chunks are loaded) flagIncludedChunks: true, // flags the loading order of modules to make the initial package smaller occurrenceOrder: True, // Enable sideEffects: // Optimization. UsedExports The information collected will be used by other optimizations or code generation using usedExports: ConcatenateModules: true, // SplitChunksPlugin configuration items splitChunks: {// default webPack4 will only do chunks of code loaded on demand: 'async', // represents the minimum module size before compression, default is 30KB minSize: 30000, minRemainingSize: 0, // Intended for use with HTTP/2 and long-term caches // it increases the number of requests for better caches // It can also be used to reduce file sizes to speed up rebuilds. MaxSize: 0, // Minimum chunks that must be shared before splitting a module minChunks: 1, // Maximum concurrent requests that can be loaded on demand maxAsyncRequests: 6, // Maximum concurrent requests that can be imported maxInitialRequests: 4, // the qualifier automaticNameDelimiter: '~', // the maximum number of characters in block names automaticNameMaxLength: 30, cacheGroups: {// cacheGroups: {test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: NoEmitOnErrors: true, checkWasmTypes: True, / / using optimization minimizer | | TerserPlugin to minimize packet minimize: true,}, plugins: [// Use terser to optimize JavaScript new TerserPlugin(/*... */), // Define the environment variable new webpack.defineplugin ({" process.env.node_env ": Json.stringify ("production")}), // precompile all modules into a closure, Promotion code in the browser execution speed new webpack. Optimize the ModuleConcatenationPlugin (), / / during the compilation of errors, Use NoEmitOnErrorsPlugin to skip the output stage. / / this will ensure that the output error resource will not include new webpack. NoEmitOnErrorsPlugin ()]}Copy the code
2. Mode :development Default configuration
// webpack.dev.config.js module.exports = { devtool: 'eval', cache: true, performance: }, output: {// Include pathinfo: true}, optimization: {// Debug namedModules: true with readable module identifiers, // debug namedChunks with readable block identifiers: True, // set process.env.node_env to development nodeEnv: 'development', // do not flag whether the block is a subset of other blocks flagIncludedChunks: False, // do not mark the loading order of modules occurrenceOrder: false, // do not enable sideEffects sideEffects: false, usedExports: false, concatenateModules: false, splitChunks: { hidePathInfo: false, minSize: 10000, maxAsyncRequests: Infinity, maxInitialRequests: NoEmitOnErrors: false, checkWasmTypes: {noEmitOnErrors: false, checkWasmTypes: False, / / no use optimization. Minimizer | | TerserPlugin to minimize packet minimize: false, removeAvailableModules: false}, plugins: [/ / when enabled HMR, using the plugin will display module relative path / / Suggestions for the development environment of new webpack. NamedModulesPlugin (), / / internal maintains a webpack on the id, Each chunk has an ID. // So when you add entries or other types of chunks, the ID changes. // NamedChunksPlugin maps the internal chunk ID to a string identifier (the relative path of the module) // So the chunk ID is stabilized new Webpack. NamedChunksPlugin (), / / define environment variables. New webpack DefinePlugin ({" process. The env. NODE_ENV ": JSON.stringify("development") }), ] }Copy the code
3, mode:none Default configuration
// webpack.com.config.js module.exports = {performance: {// Config.js module.exports = {performance: { {// Do not flag whether a block is a subset of other blocks flagIncludedChunks: false, // do not flag the loading order of modules occurrenceOrder: false, // Do not enable sideEffects: false, usedExports: false, concatenateModules: false, splitChunks: { hidePathInfo: false, minSize: (maxAsyncRequests: Infinity, maxInitialRequests: Infinity,}) False, checkWasmTypes: false, / / no use optimization. The minimizer | | TerserPlugin to minimize packet minimize: false,}, plugins: []}Copy the code
4, production, development, none
Configure DevTool
Configure how WebPack generates the Source Map to enhance the debugging process. Different values can significantly affect build and rebuild speed:
- Production environment: The default value is NULL. The production environment is source-map hidden-source-map nosource-source-map
- Development environment: The default is eval, Eval, eval-source-map, cheap-eval-source-map, cheap-module-eval-source-map, etc. Being the module – the source map, being the module – the eval – source – the map
If the default Webpack Minimizer has been redefined (e.g. Terser-webpack-plugin), you must provide the sourceMap: true option to enable Source Map support.
7. Configure the resolve policy
Configure the resolve policy. Resolve: Define the policy for finding dependent modules
When webPack starts, it triggers to find all dependent modules from the configured entry module. Resolve configs how WebPack finds the corresponding files for the modules. Webpack has built-in JavaScript modular syntax parsing capabilities, which are found by default using rules agreed in the modular standard, but you can modify the default rules to suit your needs.
- The resolve.alias configuration item maps the original import path to a new one using an alias.
- If the import statement does not have a file suffix, WebPack will automatically apply the suffix to try to access the file.
- Resolve. Symlinks Whether symlinks are resolved to their symlink location. When enabled, symlink resources are resolved to their real path, not their symlink location. Note that this approach may cause module parsing to fail when using tools that create symbolic link packages, such as NPM Link.
- .
Eight, configuration optimization
1. Minimize packages
- Using optimization. RemoveAvailableModules deleted already available modules
- Using optimization. RemoveEmptyChunks delete empty module
- Using optimization. OccurrenceOrder tag module load order, make the initial smaller packages
- Using optimization. ProvidedExports, optimization. UsedExports, concatenateModules, optimization. The sideEffects remove dead code
- Extract common packages using optimization.splitchunks
- Using optimization. Minimizer | | TerserPlugin to minimize the package
2. Unpacking
When the package is too large, if we update a small part of the package, then the whole package needs to be reloaded. If we split the package, then we only need to reload the changed package, not all of the packages, effectively utilizing the cache.
Split node_modules
In many cases, we don’t need to do this manually. Instead, we can use Optimization.splitchunks:
const path = require('path'); module.exports = { entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[contenthash].js', }, optimization: { splitChunks: {// split chunks on all packages: 'all',},},};Copy the code
Instead of having a unpacking strategy, chunks: All automatically puts everything in node_modules into a file called vendors ~ main.js.
Split business code
Adopt multi-entry approach, when there is business code update, the corresponding package can be updated
module.exports = {
entry: {
main: path.resolve(__dirname, 'src/index.js'),
ProductList: path.resolve(__dirname, 'src/ProductList/ProductList.js'),
ProductPage: path.resolve(__dirname, 'src/ProductPage/ProductPage.js'),
Icon: path.resolve(__dirname, 'src/Icon/Icon.js'),
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
},
};
Copy the code
Split third-party libraries
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[contenthash].js', }, optimization: { runtimeChunk: 'single', splitChunks: { chunks: 'all', maxInitialRequests: Infinity, minSize: 0, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, Name (module) {const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)) (/ / \ \ | $) /) [1]; Return 'NPM.${packageName. Replace ('@', ')}'; // NPM package names are URL-safe, but some servers don't like the @ sign. },},},},},},};Copy the code
When a third-party package is updated, only the corresponding package is updated.
Note that browsers make more requests when there are too many packages, and there is an impact on code compression when files are too small.
Dynamic loading
Now we’ve split the package thoroughly, but the above split is just a browser cache optimization to reduce the first screen load time. In fact, we can further split the package by loading it on demand to reduce the first screen load time:
import React, { useState, useEffect } from 'react'; import './index.scss' function Main() { const [NeighborPage, setNeighborPage] = useState(null) useEffect(() => { import('.. /neighbor').then(({ default: component }) => { setNeighborPage(React.createElement(component)) }); }, []) return NeighborPage ? NeighborPage : <div>Loading... </div>; } export default MainCopy the code
Configure performance
Performance controls how Webpack notifies when packaging is an asset and entry point that exceeds certain file limits:
Module.exports = {// how to display performance: {// Optional warning, error, false // false: performance Settings. If the file package is too large, no error or warning is reported, but only a warning is displayed. Error displayed, recommended for production environment, preventing too large production package deployment, affecting web page performance Hints: false}}Copy the code
X. Other configurations
context
Base directory, absolute path, used to parse entry points and loaders from configuration
module.exports = {
//...
context: path.resolve(__dirname, 'app')
};
Copy the code
The current directory is used by default, but it is recommended to pass a value in the configuration. This makes your configuration independent of CWD(current working Directory).
cache
Cache generated Webpack modules and blocks to speed up builds. In development mode, the cache is set to type: ‘memory’ and disabled in production mode. Cache: true is an alias for cache: {type: ‘memory’}. To disable cache passing false:
module.exports = {
cache: false
}
Copy the code
In memory, caching is only useful in monitor mode, and we assume you use monitor mode in development. In the absence of caching, the footprint is small.
watch
Monitor file updates and recompile when files are updated:
Module. export = {// Enable listening mode watch: true,}Copy the code
In webpack-dev-server and Webpack-dev-Middleware, monitor mode is enabled by default. Or we can start listening on the command line (–watch) :
webpack --watch --config webpack.config.dev.js
Copy the code
watchOptions
Module. export = {watch: true, watchOptions: {// Ignore: // node_modules/, // Listen for changes and delay the execution of actions for 300ms (default), // Prevent files from updating too quickly and recompiling too often. Poll: 1000ms poll: 1000}}Copy the code
target
Build target to specify an environment for WebPack:
Module. exports = {// compiles to class browser environment available (default) target: 'web'};Copy the code
externals
For example, if you use jquery in your project and you include it in your HTML, then you don’t need to include it in your package:
< script SRC = "https://code.jquery.com/jquery-3.1.0.js" integrity = "sha256 - slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk =" crossorigin="anonymous"> </script>Copy the code
Configuration:
Module.exports = {// externals: {jquery: 'jquery'}};Copy the code