One, foreword
The core configuration of WebPack is created and modified based on a potentially difficult JavaScript object. Although it is no problem for the configuration of a single project, but when you have more project team, and to attempt to all projects share webpack configuration file, you will feel difficult to start, because you need to consider the scalability build configuration, such as a component has its own unique features, need to do some personalized configuration, It gets tricky.
Webpack-chain attempts to create and modify WebPack configurations by providing a chained or downstream API, the Key portion of which can be referenced by a user-specified name, which helps standardize the way configurations are modified across projects. Webpack-chain has been used in VUE-CLI3 and some open source builders, so this article will help you get familiar with the preparation and use of Webpack-chain from the beginning to the proficient.
Second, grammar introduction
1. Webpack instance creation
You can install the Webpack-chain package in NPM or YARN mode, as shown below
npm i --save-dev webpack-chain
or
yarn add --dev webpack-chain
Copy the code
Once you have webpack-chain installed, you can start creating an instance of Webpack, as shown below
// Imports the Webpack-chain module, which exports a single constructor for creating a WebPack configuration API.
const Config = require('webpack-chain');
// Create a new configuration instance for the single constructor
const config = new Config();
/ /... There are a number of WebPack configurations that we will cover in subsequent chapters and omit here
// Export the modified configuration object to be used by WebPack
module.exports = config.toConfig();
Copy the code
2, ChainedMap
One of the core APIS in Webpack-chain is ChainedMap. A ChainedMap operates like a JavaScript Map, providing some convenience for chained and generated configurations. If a property is marked as a ChainedMap, it will have the following APIS and methods: Unless otherwise noted, these methods return a ChainedMap, allowing the methods to be invoked chained.
// 1. Remove all configurations from Map
clear()
// 2. Remove a single configuration from the Map by key
delete(key)
// 3. Obtain the corresponding key value in Map
// Note: the return value is the corresponding value of the key
get(key)
// get the Map key value
// If the key does not exist in the Map, the value of the key in the ChainedMap will be configured as the return value of the FN.
// Note: the return value is the corresponding value of the key, or the value returned by fn
getOrCompute(key, fn)
// 5. Set the values of the existing keys in the Map
set(key, value)
// If there is a specific key configured in Map,
// Note: Return Boolean
has(key)
// return an array of all values stored in the Map
// Note: An Array is returned
values()
// return an object configured in the Map, where the key is the object attribute and the value is the corresponding key value.
entries()
// 9. Provide an object whose properties and values will be mapped into the Map
merge(obj, omit)
// execute the handler function for the current configuration context
batch(handler)
Condition executes a function to continue the configuration
// condition: Boolean
// whenTruthy: When the condition is true, call the function that passes in the ChainedMap instance as a single argument
// whenFalsy: When the condition is false, call the function passing in the ChainedMap instance as a single argument
when(condition, whenTruthy, whenFalsy)
Copy the code
3, ChainedSet
The other core API in Webpack-chain is a ChainedSet, which operates like a JavaScript Set and provides some convenience for chained and generated configurations. If a property is marked with a ChainedSet, it will have the following API and methods: unless otherwise specified, the methods will return a ChainedSet, allowing the methods to be called chained.
// 1, add/append a value to the end of Set
add(value)
// 2, add a value to the start of Set
prepend(value)
// 3, remove all values from Set
clear()
// remove a specified value from Set
delete(value)
// check if there is a value in Set
// Note: Return Boolean
has(value)
// 6, return an array of values in Set.
// Note: An Array is returned
values()
// connect the given array to the end of the Set.
merge(arr)
// Execute the handler function for the current configuration context
batch(handler)
Condition executes a function to continue the configuration
// whenTruthy: When the condition is true, call the function that passes in the ChainedSet instance as a single argument
// whenFalsy: When the condition is false, call the function that passes in the ChainedSet instance as a single argument
when(condition, whenTruthy, whenFalsy)
Copy the code
4. Method shorthand
In addition to the ChainedMap and ChainedSet syntax mentioned above, webpack-chain provides a number of shorthand methods, which are not listed here. You can refer to the webpack-chain Github documentation. For example, devServer.hot is a shorthand method written as follows
// devServer is abbreviated as follows
devServer.hot(true);
// The above method is equivalent to
devServer.set('hot'.true);
Copy the code
Like ChainedMap and ChainedSet syntaxes, abbreviations support chained syntax because they return the original instance unless otherwise specified.
5. Merge configurations
Webpack-chain supports merging objects into configuration instances, but note that this is not a WebPack configuration object, and if we need to merge webpack-chain objects, we need to transform them before merging them.
/ / merge
config.merge({ devtool: 'source-map' });
/ / to get "the source - the map"
config.get('devtool')
Copy the code
6. Check the generated configuration
We can use the syntax config.toString() method to convert the Webpack object into a string that contains naming rules, usage, and plug-in comment tips, as shown below
config
.module
.rule('compile')
.test(/\.js$/)
.use('babel')
.loader('babel-loader');
config.toString();
// The converted output
{
module: {
rules: [
/* config.module.rule('compile') */
{
test: /\.js$/,
use: [
/* config.module.rule('compile').use('babel') */
{
loader: 'babel-loader'}]}}Copy the code
Three, common examples
1. Configure entry entry
// Configure the compile entry file
config.entry('main').add('./src/main.js')
// Equivalent to the following WebPack configuration
entry: {
main: [
'./src/main.js']}Copy the code
2. Output export configuration
// Configure the export file
config.output
.path(path.resolve(__dirname, './dist'))
.filename('[name].[chunkhash].js')
.chunkFilename('chunks/[name].[chunkhash].js')
.libraryTarget('umd');
// Equivalent to the following WebPack configuration
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[chunkhash].js'.chunkFilename: 'chunks/[name].[chunkhash].js'.libraryTarget: 'umd'
},
Copy the code
3. Alias Alias configuration
// Configure the directory alias
config.resolve.alias
.set(The '@', path.resolve(__dirname, 'src'))
.set('assets', path.resolve(__dirname, 'src/assets'))
// Equivalent to the following WebPack configuration
resolve: {
alias: {
The '@': path.resolve(__dirname, 'src'),
assets: path.resolve(__dirname, 'src/assets'}})),Copy the code
4. Loader configuration is added
// Configure a new loader
config.module
.rule('babel')
.test(/\.(js|jsx|mjs|ts|tsx)$/)
.include
.add(path.resolve(__dirname, 'src'))
.end()
.use('babel-loader')
.loader('babel-loader')
.options({
'presets': ['@babel/preset-env']})// Equivalent to the following WebPack configuration
module: {
rules: [{test: /\.(js|jsx|mjs|ts|tsx)$/,
include: [
path.resolve(__dirname, 'src')].use: [{loader: 'babel-loader'.options: {
presets: [
'@babel/preset-env']}}]}Copy the code
5. Modify loader configuration
Different from the new loader, tap method is used. The callback parameter of this method is Options, which is the configuration option object of the loader. Therefore, we can change the options object to change the loader configuration.
config.module
.rule('babel')
.use('babel-loader')
.tap(options= > {
// Modify its options...
options.include = path.resolve(__dirname, 'test')
return options
})
Copy the code
6. Remove the Loader configuration
config.module.rules.clear(); // Delete all loaders added.
config.module.rule('babel').uses.clear(); Delete rule added with useCopy the code
7. Plugin configuration is added
// Configure a new plugin
config.plugin('HtmlWebpackPlugin').use(HtmlWebpackPlugin, [
{
template: path.resolve(__dirname, './src/index.html'),
minify: {
collapseWhitespace: true.minifyJS: true.minifyCSS: true.removeComments: true.removeEmptyAttributes: true.removeRedundantAttributes: true.useShortDoctype: true}}]);// Equivalent to the following WebPack configuration
plugins: [
new HtmlWebpackPlugin(
{
template: path.resolve(__dirname, './src/index.html'),
minify: {
collapseWhitespace: true.minifyJS: true.minifyCSS: true.removeComments: true.removeEmptyAttributes: true.removeRedundantAttributes: true.useShortDoctype: true}})].Copy the code
8. Plugin configuration modification
Different from the new loader/plugin, the tap method is used, and the previously configured options are retained, and the changed options are overwritten.
// Modify the plugin HtmlWebpackPlugin
config.plugin('HtmlWebpackPlugin').tap((args) = > [
{
...(args[0) | | {}),template: path.resolve(__dirname, './main.html'),}]);Copy the code
9. Use the when condition
// 1. Example: Add minify plugin only during production
config
.when(process.env.NODE_ENV === 'production'.config= > {
config
.plugin('minify')
.use(BabiliWebpackPlugin);
});
// 2. Example: DevTool to source mapping is set only when miniaturing is added during production
config
.when(process.env.NODE_ENV === 'production'.config= > config.plugin('minify').use(BabiliWebpackPlugin),
config= > config.devtool('source-map'));Copy the code
10. Remove the plugin configuration
config.plugins.delete('HtmlWebpackPlugin');
Copy the code
Four,
In this article, we will introduce webpack-chain syntax to manual writing webpack common configuration and operation, help you familiar with the use of Webpack-chain, I hope it will be helpful to you.
Hard to sort out for a long time, but also hope to manually praise encouragement ~ blog github address: github.com/fengshi123/… , a summary of all the author’s blog, welcome to follow and star ~