1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558 |
- # webpack-chain
- [![NPM version][npm-image]][npm-url]
- [![NPM downloads][npm-downloads]][npm-url]
- [![Build Status][travis-image]][travis-url]
- Use a chaining API to generate and simplify the modification of
- webpack version 2-4 configurations.
- This documentation corresponds to v6 of webpack-chain. For previous versions, see:
- * [v5 docs](https://github.com/neutrinojs/webpack-chain/tree/v5)
- * [v4 docs](https://github.com/neutrinojs/webpack-chain/tree/v4)
- * [v3 docs](https://github.com/neutrinojs/webpack-chain/tree/v3)
- * [v2 docs](https://github.com/neutrinojs/webpack-chain/tree/v2)
- * [v1 docs](https://github.com/neutrinojs/webpack-chain/tree/v1)
- _Note: while webpack-chain is utilized extensively in Neutrino, this package is
- completely standalone and can be used by any project._
- **[Chinese docs(中文文档)](https://github.com/Yatoo2018/webpack-chain/tree/zh-cmn-Hans)**
- ## Introduction
- webpack's core configuration is based on creating and modifying a
- potentially unwieldy JavaScript object. While this is OK for configurations
- on individual projects, trying to share these objects across projects and
- make subsequent modifications gets messy, as you need to have a deep
- understanding of the underlying object structure to make those changes.
- `webpack-chain` attempts to improve this process by providing a chainable or
- fluent API for creating and modifying webpack configurations. Key portions
- of the API can be referenced by user-specified names, which helps to
- standardize how to modify a configuration across projects.
- This is easier explained through the examples following.
- ## Installation
- `webpack-chain` requires Node.js v6.9 and higher. `webpack-chain` also
- only creates configuration objects designed for use in webpack versions 2, 3,
- and 4.
- You may install this package using either Yarn or npm (choose one):
- **Yarn**
- ```bash
- yarn add --dev webpack-chain
- ```
- **npm**
- ```bash
- npm install --save-dev webpack-chain
- ```
- ## Getting Started
- Once you have `webpack-chain` installed, you can start creating a
- webpack configuration. For this guide, our example base configuration will
- be `webpack.config.js` in the root of our project directory.
- ```js
- // Require the webpack-chain module. This module exports a single
- // constructor function for creating a configuration API.
- const Config = require('webpack-chain');
- // Instantiate the configuration with a new API
- const config = new Config();
- // Make configuration changes using the chain API.
- // Every API call tracks a change to the stored configuration.
- config
- // Interact with entry points
- .entry('index')
- .add('src/index.js')
- .end()
- // Modify output settings
- .output
- .path('dist')
- .filename('[name].bundle.js');
- // Create named rules which can be modified later
- config.module
- .rule('lint')
- .test(/\.js$/)
- .pre()
- .include
- .add('src')
- .end()
- // Even create named uses (loaders)
- .use('eslint')
- .loader('eslint-loader')
- .options({
- rules: {
- semi: 'off'
- }
- });
- config.module
- .rule('compile')
- .test(/\.js$/)
- .include
- .add('src')
- .add('test')
- .end()
- .use('babel')
- .loader('babel-loader')
- .options({
- presets: [
- ['@babel/preset-env', { modules: false }]
- ]
- });
- // Create named plugins too!
- config
- .plugin('clean')
- .use(CleanPlugin, [['dist'], { root: '/dir' }]);
- // Export the completed configuration object to be consumed by webpack
- module.exports = config.toConfig();
- ```
- Having shared configurations is also simple. Just export the configuration
- and call `.toConfig()` prior to passing to webpack.
- ```js
- // webpack.core.js
- const Config = require('webpack-chain');
- const config = new Config();
- // Make configuration shared across targets
- // ...
- module.exports = config;
- // webpack.dev.js
- const config = require('./webpack.core');
- // Dev-specific configuration
- // ...
- module.exports = config.toConfig();
- // webpack.prod.js
- const config = require('./webpack.core');
- // Production-specific configuration
- // ...
- module.exports = config.toConfig();
- ```
- ## ChainedMap
- One of the core API interfaces in webpack-chain is a `ChainedMap`. A
- `ChainedMap` operates similar to a JavaScript Map, with some conveniences for
- chaining and generating configuration. If a property is marked as being a
- `ChainedMap`, it will have an API and methods as described below:
- **Unless stated otherwise, these methods will return the `ChainedMap`, allowing
- you to chain these methods.**
- ```js
- // Remove all entries from a Map.
- clear()
- ```
- ```js
- // Remove a single entry from a Map given its key.
- // key: *
- delete(key)
- ```
- ```js
- // Fetch the value from a Map located at the corresponding key.
- // key: *
- // returns: value
- get(key)
- ```
- ```js
- // Fetch the value from a Map located at the corresponding key.
- // If the key is missing, the key is set to the result of function fn.
- // key: *
- // fn: Function () -> value
- // returns: value
- getOrCompute(key, fn)
- ```
- ```js
- // Set a value on the Map stored at the `key` location.
- // key: *
- // value: *
- set(key, value)
- ```
- ```js
- // Returns `true` or `false` based on whether a Map as has a value set at a
- // particular key.
- // key: *
- // returns: Boolean
- has(key)
- ```
- ```js
- // Returns an array of all the values stored in the Map.
- // returns: Array
- values()
- ```
- ```js
- // Returns an object of all the entries in the backing Map
- // where the key is the object property, and the value
- // corresponding to the key. Will return `undefined` if the backing
- // Map is empty.
- // This will order properties by their name if the value is
- // a ChainedMap that used .before() or .after().
- // returns: Object, undefined if empty
- entries()
- ```
- ```js
- // Provide an object which maps its properties and values
- // into the backing Map as keys and values.
- // You can also provide an array as the second argument
- // for property names to omit from being merged.
- // obj: Object
- // omit: Optional Array
- merge(obj, omit)
- ```
- ```js
- // Execute a function against the current configuration context
- // handler: Function -> ChainedMap
- // A function which is given a single argument of the ChainedMap instance
- batch(handler)
- ```
- ```js
- // Conditionally execute a function to continue configuration
- // condition: Boolean
- // whenTruthy: Function -> ChainedMap
- // invoked when condition is truthy, given a single argument of the ChainedMap instance
- // whenFalsy: Optional Function -> ChainedMap
- // invoked when condition is falsy, given a single argument of the ChainedMap instance
- when(condition, whenTruthy, whenFalsy)
- ```
- ## ChainedSet
- Another of the core API interfaces in webpack-chain is a `ChainedSet`. A
- `ChainedSet` operates similar to a JavaScript Set, with some conveniences for
- chaining and generating configuration. If a property is marked as being a
- `ChainedSet`, it will have an API and methods as described below:
- **Unless stated otherwise, these methods will return the `ChainedSet`, allowing
- you to chain these methods.**
- ```js
- // Add/append a value to the end of a Set.
- // value: *
- add(value)
- ```
- ```js
- // Add a value to the beginning of a Set.
- // value: *
- prepend(value)
- ```
- ```js
- // Remove all values from a Set.
- clear()
- ```
- ```js
- // Remove a specific value from a Set.
- // value: *
- delete(value)
- ```
- ```js
- // Returns `true` or `false` based on whether or not the
- // backing Set contains the specified value.
- // value: *
- // returns: Boolean
- has(value)
- ```
- ```js
- // Returns an array of values contained in the backing Set.
- // returns: Array
- values()
- ```
- ```js
- // Concatenates the given array to the end of the backing Set.
- // arr: Array
- merge(arr)
- ```
- ```js
- // Execute a function against the current configuration context
- // handler: Function -> ChainedSet
- // A function which is given a single argument of the ChainedSet instance
- batch(handler)
- ```
- ```js
- // Conditionally execute a function to continue configuration
- // condition: Boolean
- // whenTruthy: Function -> ChainedSet
- // invoked when condition is truthy, given a single argument of the ChainedSet instance
- // whenFalsy: Optional Function -> ChainedSet
- // invoked when condition is falsy, given a single argument of the ChainedSet instance
- when(condition, whenTruthy, whenFalsy)
- ```
- ## Shorthand methods
- A number of shorthand methods exist for setting a value on a `ChainedMap`
- with the same key as the shorthand method name.
- For example, `devServer.hot` is a shorthand method, so it can be used as:
- ```js
- // A shorthand method for setting a value on a ChainedMap
- devServer.hot(true);
- // This would be equivalent to:
- devServer.set('hot', true);
- ```
- A shorthand method is chainable, so calling it will return the original
- instance, allowing you to continue to chain.
- ### Config
- Create a new configuration object.
- ```js
- const Config = require('webpack-chain');
- const config = new Config();
- ```
- Moving to deeper points in the API will change the context of what you
- are modifying. You can move back to the higher context by either referencing
- the top-level `config` again, or by calling `.end()` to move up one level.
- If you are familiar with jQuery, `.end()` works similarly. All API calls
- will return the API instance at the current context unless otherwise
- specified. This is so you may chain API calls continuously if desired.
- For details on the specific values that are valid for all shorthand and
- low-level methods, please refer to their corresponding name in the
- [webpack docs hierarchy](https://webpack.js.org/configuration/).
- ```js
- Config : ChainedMap
- ```
- #### Config shorthand methods
- ```js
- config
- .amd(amd)
- .bail(bail)
- .cache(cache)
- .devtool(devtool)
- .context(context)
- .externals(externals)
- .loader(loader)
- .name(name)
- .mode(mode)
- .parallelism(parallelism)
- .profile(profile)
- .recordsPath(recordsPath)
- .recordsInputPath(recordsInputPath)
- .recordsOutputPath(recordsOutputPath)
- .stats(stats)
- .target(target)
- .watch(watch)
- .watchOptions(watchOptions)
- ```
- #### Config entryPoints
- ```js
- // Backed at config.entryPoints : ChainedMap
- config.entry(name) : ChainedSet
- config
- .entry(name)
- .add(value)
- .add(value)
- config
- .entry(name)
- .clear()
- // Using low-level config.entryPoints:
- config.entryPoints
- .get(name)
- .add(value)
- .add(value)
- config.entryPoints
- .get(name)
- .clear()
- ```
- #### Config output: shorthand methods
- ```js
- config.output : ChainedMap
- config.output
- .auxiliaryComment(auxiliaryComment)
- .chunkFilename(chunkFilename)
- .chunkLoadTimeout(chunkLoadTimeout)
- .crossOriginLoading(crossOriginLoading)
- .devtoolFallbackModuleFilenameTemplate(devtoolFallbackModuleFilenameTemplate)
- .devtoolLineToLine(devtoolLineToLine)
- .devtoolModuleFilenameTemplate(devtoolModuleFilenameTemplate)
- .devtoolNamespace(devtoolNamespace)
- .filename(filename)
- .hashFunction(hashFunction)
- .hashDigest(hashDigest)
- .hashDigestLength(hashDigestLength)
- .hashSalt(hashSalt)
- .hotUpdateChunkFilename(hotUpdateChunkFilename)
- .hotUpdateFunction(hotUpdateFunction)
- .hotUpdateMainFilename(hotUpdateMainFilename)
- .jsonpFunction(jsonpFunction)
- .library(library)
- .libraryExport(libraryExport)
- .libraryTarget(libraryTarget)
- .path(path)
- .pathinfo(pathinfo)
- .publicPath(publicPath)
- .sourceMapFilename(sourceMapFilename)
- .sourcePrefix(sourcePrefix)
- .strictModuleExceptionHandling(strictModuleExceptionHandling)
- .umdNamedDefine(umdNamedDefine)
- ```
- #### Config resolve: shorthand methods
- ```js
- config.resolve : ChainedMap
- config.resolve
- .cachePredicate(cachePredicate)
- .cacheWithContext(cacheWithContext)
- .enforceExtension(enforceExtension)
- .enforceModuleExtension(enforceModuleExtension)
- .unsafeCache(unsafeCache)
- .symlinks(symlinks)
- ```
- #### Config resolve alias
- ```js
- config.resolve.alias : ChainedMap
- config.resolve.alias
- .set(key, value)
- .set(key, value)
- .delete(key)
- .clear()
- ```
- #### Config resolve modules
- ```js
- config.resolve.modules : ChainedSet
- config.resolve.modules
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolve aliasFields
- ```js
- config.resolve.aliasFields : ChainedSet
- config.resolve.aliasFields
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolve descriptionFields
- ```js
- config.resolve.descriptionFields : ChainedSet
- config.resolve.descriptionFields
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolve extensions
- ```js
- config.resolve.extensions : ChainedSet
- config.resolve.extensions
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolve mainFields
- ```js
- config.resolve.mainFields : ChainedSet
- config.resolve.mainFields
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolve mainFiles
- ```js
- config.resolve.mainFiles : ChainedSet
- config.resolve.mainFiles
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolveLoader
- The API for `config.resolveLoader` is identical to `config.resolve` with
- the following additions:
- #### Config resolveLoader moduleExtensions
- ```js
- config.resolveLoader.moduleExtensions : ChainedSet
- config.resolveLoader.moduleExtensions
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config resolveLoader packageMains
- ```js
- config.resolveLoader.packageMains : ChainedSet
- config.resolveLoader.packageMains
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config performance: shorthand methods
- ```js
- config.performance : ChainedMap
- config.performance
- .hints(hints)
- .maxEntrypointSize(maxEntrypointSize)
- .maxAssetSize(maxAssetSize)
- .assetFilter(assetFilter)
- ```
- #### Configuring optimizations: shorthand methods
- ```js
- config.optimization : ChainedMap
- config.optimization
- .concatenateModules(concatenateModules)
- .flagIncludedChunks(flagIncludedChunks)
- .mergeDuplicateChunks(mergeDuplicateChunks)
- .minimize(minimize)
- .namedChunks(namedChunks)
- .namedModules(namedModules)
- .nodeEnv(nodeEnv)
- .noEmitOnErrors(noEmitOnErrors)
- .occurrenceOrder(occurrenceOrder)
- .portableRecords(portableRecords)
- .providedExports(providedExports)
- .removeAvailableModules(removeAvailableModules)
- .removeEmptyChunks(removeEmptyChunks)
- .runtimeChunk(runtimeChunk)
- .sideEffects(sideEffects)
- .splitChunks(splitChunks)
- .usedExports(usedExports)
- ```
- #### Config optimization minimizers
- ```js
- // Backed at config.optimization.minimizers
- config.optimization
- .minimizer(name) : ChainedMap
- ```
- #### Config optimization minimizers: adding
- _NOTE: Do not use `new` to create the minimizer plugin, as this will be done for you._
- ```js
- config.optimization
- .minimizer(name)
- .use(WebpackPlugin, args)
- // Examples
- config.optimization
- .minimizer('css')
- .use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: { safe: true } }])
- // Minimizer plugins can also be specified by their path, allowing the expensive require()s to be
- // skipped in cases where the plugin or webpack configuration won't end up being used.
- config.optimization
- .minimizer('css')
- .use(require.resolve('optimize-css-assets-webpack-plugin'), [{ cssProcessorOptions: { safe: true } }])
- ```
- #### Config optimization minimizers: modify arguments
- ```js
- config.optimization
- .minimizer(name)
- .tap(args => newArgs)
- // Example
- config.optimization
- .minimizer('css')
- .tap(args => [...args, { cssProcessorOptions: { safe: false } }])
- ```
- #### Config optimization minimizers: modify instantiation
- ```js
- config.optimization
- .minimizer(name)
- .init((Plugin, args) => new Plugin(...args));
- ```
- #### Config optimization minimizers: removing
- ```js
- config.optimization.minimizers.delete(name)
- ```
- #### Config plugins
- ```js
- // Backed at config.plugins
- config.plugin(name) : ChainedMap
- ```
- #### Config plugins: adding
- _NOTE: Do not use `new` to create the plugin, as this will be done for you._
- ```js
- config
- .plugin(name)
- .use(WebpackPlugin, args)
- // Examples
- config
- .plugin('hot')
- .use(webpack.HotModuleReplacementPlugin);
- // Plugins can also be specified by their path, allowing the expensive require()s to be
- // skipped in cases where the plugin or webpack configuration won't end up being used.
- config
- .plugin('env')
- .use(require.resolve('webpack/lib/EnvironmentPlugin'), [{ 'VAR': false }]);
- ```
- #### Config plugins: modify arguments
- ```js
- config
- .plugin(name)
- .tap(args => newArgs)
- // Example
- config
- .plugin('env')
- .tap(args => [...args, 'SECRET_KEY']);
- ```
- #### Config plugins: modify instantiation
- ```js
- config
- .plugin(name)
- .init((Plugin, args) => new Plugin(...args));
- ```
- #### Config plugins: removing
- ```js
- config.plugins.delete(name)
- ```
- #### Config plugins: ordering before
- Specify that the current `plugin` context should operate before another named
- `plugin`. You cannot use both `.before()` and `.after()` on the same plugin.
- ```js
- config
- .plugin(name)
- .before(otherName)
- // Example
- config
- .plugin('html-template')
- .use(HtmlWebpackTemplate)
- .end()
- .plugin('script-ext')
- .use(ScriptExtWebpackPlugin)
- .before('html-template');
- ```
- #### Config plugins: ordering after
- Specify that the current `plugin` context should operate after another named
- `plugin`. You cannot use both `.before()` and `.after()` on the same plugin.
- ```js
- config
- .plugin(name)
- .after(otherName)
- // Example
- config
- .plugin('html-template')
- .after('script-ext')
- .use(HtmlWebpackTemplate)
- .end()
- .plugin('script-ext')
- .use(ScriptExtWebpackPlugin);
- ```
- #### Config resolve plugins
- ```js
- // Backed at config.resolve.plugins
- config.resolve.plugin(name) : ChainedMap
- ```
- #### Config resolve plugins: adding
- _NOTE: Do not use `new` to create the plugin, as this will be done for you._
- ```js
- config.resolve
- .plugin(name)
- .use(WebpackPlugin, args)
- ```
- #### Config resolve plugins: modify arguments
- ```js
- config.resolve
- .plugin(name)
- .tap(args => newArgs)
- ```
- #### Config resolve plugins: modify instantiation
- ```js
- config.resolve
- .plugin(name)
- .init((Plugin, args) => new Plugin(...args))
- ```
- #### Config resolve plugins: removing
- ```js
- config.resolve.plugins.delete(name)
- ```
- #### Config resolve plugins: ordering before
- Specify that the current `plugin` context should operate before another named
- `plugin`. You cannot use both `.before()` and `.after()` on the same resolve
- plugin.
- ```js
- config.resolve
- .plugin(name)
- .before(otherName)
- // Example
- config.resolve
- .plugin('beta')
- .use(BetaWebpackPlugin)
- .end()
- .plugin('alpha')
- .use(AlphaWebpackPlugin)
- .before('beta');
- ```
- #### Config resolve plugins: ordering after
- Specify that the current `plugin` context should operate after another named
- `plugin`. You cannot use both `.before()` and `.after()` on the same resolve
- plugin.
- ```js
- config.resolve
- .plugin(name)
- .after(otherName)
- // Example
- config.resolve
- .plugin('beta')
- .after('alpha')
- .use(BetaWebpackTemplate)
- .end()
- .plugin('alpha')
- .use(AlphaWebpackPlugin);
- ```
- #### Config node
- ```js
- config.node : ChainedMap
- config.node
- .set('__dirname', 'mock')
- .set('__filename', 'mock');
- ```
- #### Config devServer
- ```js
- config.devServer : ChainedMap
- ```
- #### Config devServer allowedHosts
- ```js
- config.devServer.allowedHosts : ChainedSet
- config.devServer.allowedHosts
- .add(value)
- .prepend(value)
- .clear()
- ```
- #### Config devServer: shorthand methods
- ```js
- config.devServer
- .after(after)
- .before(before)
- .bonjour(bonjour)
- .clientLogLevel(clientLogLevel)
- .color(color)
- .compress(compress)
- .contentBase(contentBase)
- .disableHostCheck(disableHostCheck)
- .filename(filename)
- .headers(headers)
- .historyApiFallback(historyApiFallback)
- .host(host)
- .hot(hot)
- .hotOnly(hotOnly)
- .http2(http2)
- .https(https)
- .index(index)
- .info(info)
- .inline(inline)
- .lazy(lazy)
- .mimeTypes(mimeTypes)
- .noInfo(noInfo)
- .open(open)
- .openPage(openPage)
- .overlay(overlay)
- .pfx(pfx)
- .pfxPassphrase(pfxPassphrase)
- .port(port)
- .progress(progress)
- .proxy(proxy)
- .public(public)
- .publicPath(publicPath)
- .quiet(quiet)
- .setup(setup)
- .socket(socket)
- .sockHost(sockHost)
- .sockPath(sockPath)
- .sockPort(sockPort)
- .staticOptions(staticOptions)
- .stats(stats)
- .stdin(stdin)
- .useLocalIp(useLocalIp)
- .watchContentBase(watchContentBase)
- .watchOptions(watchOptions)
- .writeToDisk(writeToDisk)
- ```
- #### Config module
- ```js
- config.module : ChainedMap
- ```
- #### Config module: shorthand methods
- ```js
- config.module : ChainedMap
- config.module
- .noParse(noParse)
- ```
- #### Config module rules: shorthand methods
- ```js
- config.module.rules : ChainedMap
- config.module
- .rule(name)
- .test(test)
- .pre()
- .post()
- .enforce(preOrPost)
- ```
- #### Config module rules uses (loaders): creating
- ```js
- config.module.rules{}.uses : ChainedMap
- config.module
- .rule(name)
- .use(name)
- .loader(loader)
- .options(options)
- // Example
- config.module
- .rule('compile')
- .use('babel')
- .loader('babel-loader')
- .options({ presets: ['@babel/preset-env'] });
- ```
- #### Config module rules uses (loaders): modifying options
- ```js
- config.module
- .rule(name)
- .use(name)
- .tap(options => newOptions)
- // Example
- config.module
- .rule('compile')
- .use('babel')
- .tap(options => merge(options, {
- plugins: ['@babel/plugin-proposal-class-properties']
- }));
- ```
- #### Config module rules nested rules:
- ```js
- config.module.rules{}.rules : ChainedMap<Rule>
- config.module
- .rule(name)
- .rule(name)
- // Example
- config.module
- .rule('css')
- .test(/\.css$/)
- .use('style')
- .loader('style-loader')
- .end()
- .rule('postcss')
- .resourceQuery(/postcss/)
- .use('postcss')
- .loader('postcss-loader')
- ```
- #### Config module rules nested rules: ordering before
- Specify that the current `rule` context should operate before another named
- `rule`. You cannot use both `.before()` and `.after()` on the same `rule`.
- ```js
- config.module.rules{}.rules : ChainedMap<Rule>
- config.module
- .rule(name)
- .rule(name)
- .before(otherName)
- // Example
- config.module
- .rule('css')
- .use('style')
- .loader('style-loader')
- .end()
- .rule('postcss')
- .resourceQuery(/postcss/)
- .use('postcss')
- .loader('postcss-loader')
- .end()
- .end()
- .rule('css-loader')
- .resourceQuery(/css-loader/)
- .before('postcss')
- .use('css-loader')
- .loader('css-loader')
- ```
- #### Config module rules nested rules: ordering after
- Specify that the current `rule` context should operate after another named
- `rule`. You cannot use both `.before()` and `.after()` on the same `rule`.
- ```js
- config.module.rules{}.rules : ChainedMap<Rule>
- config.module
- .rule(name)
- .rule(name)
- .after(otherName)
- // Example
- config.module
- .rule('css')
- .use('style')
- .loader('style-loader')
- .end()
- .rule('postcss')
- .resourceQuery(/postcss/)
- .after('css-loader')
- .use('postcss')
- .loader('postcss-loader')
- .end()
- .end()
- .rule('css-loader')
- .resourceQuery(/css-loader/)
- .use('css-loader')
- .loader('css-loader')
- ```
- #### Config module rules oneOfs (conditional rules):
- ```js
- config.module.rules{}.oneOfs : ChainedMap<Rule>
- config.module
- .rule(name)
- .oneOf(name)
- // Example
- config.module
- .rule('css')
- .oneOf('inline')
- .resourceQuery(/inline/)
- .use('url')
- .loader('url-loader')
- .end()
- .end()
- .oneOf('external')
- .resourceQuery(/external/)
- .use('file')
- .loader('file-loader')
- ```
- #### Config module rules oneOfs (conditional rules): ordering before
- Specify that the current `oneOf` context should operate before another named
- `oneOf`. You cannot use both `.before()` and `.after()` on the same `oneOf`.
- ```js
- config.module
- .rule(name)
- .oneOf(name)
- .before()
- // Example
- config.module
- .rule('scss')
- .test(/\.scss$/)
- .oneOf('normal')
- .use('sass')
- .loader('sass-loader')
- .end()
- .end()
- .oneOf('sass-vars')
- .before('normal')
- .resourceQuery(/\?sassvars/)
- .use('sass-vars')
- .loader('sass-vars-to-js-loader')
- ```
- #### Config module rules oneOfs (conditional rules): ordering after
- Specify that the current `oneOf` context should operate after another named
- `oneOf`. You cannot use both `.before()` and `.after()` on the same `oneOf`.
- ```js
- config.module
- .rule(name)
- .oneOf(name)
- .after()
- // Example
- config.module
- .rule('scss')
- .test(/\.scss$/)
- .oneOf('vue')
- .resourceQuery(/\?vue/)
- .use('vue-style')
- .loader('vue-style-loader')
- .end()
- .end()
- .oneOf('normal')
- .use('sass')
- .loader('sass-loader')
- .end()
- .end()
- .oneOf('sass-vars')
- .after('vue')
- .resourceQuery(/\?sassvars/)
- .use('sass-vars')
- .loader('sass-vars-to-js-loader')
- ```
- #### Config module rules resolve
- Specify a resolve configuration to be merged over the default `config.resolve`
- for modules that match the rule.
- See "Config resolve" sections above for full syntax.
- **Note:** This option is supported by webpack since 4.36.1.
- ```js
- config.module
- .rule(name)
- .resolve
- // Example
- config.module
- .rule('scss')
- .test(/\.scss$/)
- .resolve
- .symlinks(true)
- ```
- ---
- ### Merging Config
- webpack-chain supports merging in an object to the configuration instance which
- matches a layout similar to how the webpack-chain schema is laid out.
- **Note:** This object does not match the webpack configuration schema exactly
- (for example the `[name]` keys for entry/rules/plugins), so you may need to transform
- webpack configuration objects (such as those output by webpack-chain's `.toConfig()`)
- to match the layout below prior to passing to `.merge()`.
- ```js
- config.merge({ devtool: 'source-map' });
- config.get('devtool') // "source-map"
- ```
- ```js
- config.merge({
- [key]: value,
- amd,
- bail,
- cache,
- context,
- devtool,
- externals,
- loader,
- mode,
- parallelism,
- profile,
- recordsPath,
- recordsInputPath,
- recordsOutputPath,
- stats,
- target,
- watch,
- watchOptions,
- entry: {
- [name]: [...values]
- },
- plugin: {
- [name]: {
- plugin: WebpackPlugin,
- args: [...args],
- before,
- after
- }
- },
- devServer: {
- [key]: value,
- clientLogLevel,
- compress,
- contentBase,
- filename,
- headers,
- historyApiFallback,
- host,
- hot,
- hotOnly,
- https,
- inline,
- lazy,
- noInfo,
- overlay,
- port,
- proxy,
- quiet,
- setup,
- stats,
- watchContentBase
- },
- node: {
- [key]: value
- },
- optimization: {
- concatenateModules,
- flagIncludedChunks,
- mergeDuplicateChunks,
- minimize,
- minimizer: {
- [name]: {
- plugin: WebpackPlugin,
- args: [...args],
- before,
- after
- }
- },
- namedChunks,
- namedModules,
- nodeEnv,
- noEmitOnErrors,
- occurrenceOrder,
- portableRecords,
- providedExports,
- removeAvailableModules,
- removeEmptyChunks,
- runtimeChunk,
- sideEffects,
- splitChunks,
- usedExports,
- },
- performance: {
- [key]: value,
- hints,
- maxEntrypointSize,
- maxAssetSize,
- assetFilter
- },
- resolve: {
- [key]: value,
- alias: {
- [key]: value
- },
- aliasFields: [...values],
- descriptionFields: [...values],
- extensions: [...values],
- mainFields: [...values],
- mainFiles: [...values],
- modules: [...values],
- plugin: {
- [name]: {
- plugin: WebpackPlugin,
- args: [...args],
- before,
- after
- }
- }
- },
- resolveLoader: {
- [key]: value,
- alias: {
- [key]: value
- },
- aliasFields: [...values],
- descriptionFields: [...values],
- extensions: [...values],
- mainFields: [...values],
- mainFiles: [...values],
- modules: [...values],
- moduleExtensions: [...values],
- packageMains: [...values],
- plugin: {
- [name]: {
- plugin: WebpackPlugin,
- args: [...args],
- before,
- after
- }
- }
- },
- module: {
- [key]: value,
- rule: {
- [name]: {
- [key]: value,
- enforce,
- issuer,
- parser,
- resource,
- resourceQuery,
- test,
- include: [...paths],
- exclude: [...paths],
- rules: {
- [name]: Rule
- },
- oneOf: {
- [name]: Rule
- },
- use: {
- [name]: {
- loader: LoaderString,
- options: LoaderOptions,
- before,
- after
- }
- }
- }
- }
- }
- })
- ```
- ### Conditional configuration
- When working with instances of `ChainedMap` and `ChainedSet`, you can perform
- conditional configuration using `when`. You must specify an expression to
- `when()` which will be evaluated for truthiness or falsiness. If the expression
- is truthy, the first function argument will be invoked with an instance of the
- current chained instance. You can optionally provide a second function to be
- invoked when the condition is falsy, which is also given the current chained
- instance.
- ```js
- // Example: Only add minify plugin during production
- config
- .when(process.env.NODE_ENV === 'production', config => {
- config
- .plugin('minify')
- .use(BabiliWebpackPlugin);
- });
- ```
- ```js
- // Example: Only add minify plugin during production,
- // otherwise set devtool to source-map
- config
- .when(process.env.NODE_ENV === 'production',
- config => config.plugin('minify').use(BabiliWebpackPlugin),
- config => config.devtool('source-map')
- );
- ```
- ### Inspecting generated configuration
- You can inspect the generated webpack config using `config.toString()`. This
- will generate a stringified version of the config with comment hints for named
- rules, uses and plugins:
- ```js
- config
- .module
- .rule('compile')
- .test(/\.js$/)
- .use('babel')
- .loader('babel-loader');
- config.toString();
- /*
- {
- module: {
- rules: [
- /* config.module.rule('compile') */
- {
- test: /\.js$/,
- use: [
- /* config.module.rule('compile').use('babel') */
- {
- loader: 'babel-loader'
- }
- ]
- }
- ]
- }
- }
- */
- ```
- By default the generated string cannot be used directly as real webpack config
- if it contains objects and plugins that need to be required. In order to
- generate usable config, you can customize how objects and plugins are
- stringified by setting a special `__expression` property on them:
- ```js
- const sass = require('sass');
- sass.__expression = `require('sass')`;
- class MyPlugin {}
- MyPlugin.__expression = `require('my-plugin')`;
- function myFunction () {}
- myFunction.__expression = `require('my-function')`;
- config
- .plugin('example')
- .use(MyPlugin, [{ fn: myFunction, implementation: sass, }]);
- config.toString();
- /*
- {
- plugins: [
- new (require('my-plugin'))({
- fn: require('my-function'),
- implementation: require('sass')
- })
- ]
- }
- */
- ```
- Plugins specified via their path will have their `require()` statement generated
- automatically:
- ```js
- config
- .plugin('env')
- .use(require.resolve('webpack/lib/ProvidePlugin'), [{ jQuery: 'jquery' }])
- config.toString();
- /*
- {
- plugins: [
- new (require('/foo/bar/src/node_modules/webpack/lib/EnvironmentPlugin.js'))(
- {
- jQuery: 'jquery'
- }
- )
- ]
- }
- */
- ```
- You can also call `toString` as a static method on `Config` in order to
- modify the configuration object prior to stringifying.
- ```js
- Config.toString({
- ...config.toConfig(),
- module: {
- defaultRules: [
- {
- use: [
- {
- loader: 'banner-loader',
- options: { prefix: 'banner-prefix.txt' },
- },
- ],
- },
- ],
- },
- })
- ```
- ```
- {
- plugins: [
- /* config.plugin('foo') */
- new TestPlugin()
- ],
- module: {
- defaultRules: [
- {
- use: [
- {
- loader: 'banner-loader',
- options: {
- prefix: 'banner-prefix.txt'
- }
- }
- ]
- }
- ]
- }
- }
- ```
- [npm-image]: https://img.shields.io/npm/v/webpack-chain.svg
- [npm-downloads]: https://img.shields.io/npm/dt/webpack-chain.svg
- [npm-url]: https://www.npmjs.com/package/webpack-chain
- [travis-image]: https://api.travis-ci.com/neutrinojs/webpack-chain.svg?branch=master
- [travis-url]: https://travis-ci.com/neutrinojs/webpack-chain
|