webpack-chain項目中文翻譯

webpack-chain

注意:這是對原項目readme文件的翻譯,爲啥翻譯這個呢,由於Vue CLI3腳手架生成的項目使用這種方式配置webpack,可是腳手架中對這塊的介紹很少,因此把這部分翻譯出來,以供團隊和你們參考。css

應用一個鏈式 API 來生成和簡化 2-4 版本的webpack的配置的修改。html

此文檔對應於webpack-chain的v5版本,對於之前的版本,請參閱:node

注意: 雖然 webpack-chain 被普遍應用在Neutrino中,然而本軟件包徹底獨立,可供任何項目使用。jquery

介紹

webpack 的核心配置的建立和修改基於一個有潛在難於處理的 JavaScript 對象。雖然這對於配置單個項目來講仍是 OK 的,但當你嘗試跨項目共享這些對象並使其進行後續的修改就會變的混亂不堪,由於您須要深刻了解底層對象的結構以進行這些更改。webpack

webpack-chain 嘗試經過提供可鏈式或順流式的 API 建立和修改webpack 配置。API的 Key 部分能夠由用戶指定的名稱引用,這有助於 跨項目修改配置方式 的標準化。git

經過如下示例能夠更容易地解釋這一點。github

安裝

webpack-chain 須要 Node.js v6.9及更高版本.
webpack-chain 也只建立並被設計於使用webpack的2,3,4版本的配置對象。web

你可使用Yarn或者npm來安裝此軟件包(倆個包管理工具選一個就行):express

Yarn方式

yarn add --dev webpack-chain

npm方式

npm install --save-dev webpack-chain

入門

當你安裝了 webpack-chain, 你就能夠開始建立一個webpack的配置。 對於本指南,咱們的示例基本配置 webpack.config.js 將位於咱們項目的根目錄。npm

// 導入 webpack-chain 模塊,該模塊導出了一個用於建立一個webpack配置API的單一構造函數。
const Config = require('webpack-chain');

// 對該單一構造函數建立一個新的配置實例
const config = new Config();

// 用鏈式API改變配置
// 每一個API的調用都會跟蹤對存儲配置的更改。

config
  // 修改 entry 配置
  .entry('index')
    .add('src/index.js')
    .end()
  // 修改 output 配置
  .output
    .path('dist')
    .filename('[name].bundle.js');

// 建立一個具名規則,之後用來修改規則
config.module
  .rule('lint')
    .test(/\.js$/)
    .pre()
    .include
      .add('src')
      .end()
    // 還能夠建立具名use (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 }]
        ]
      });

// 也能夠建立一個具名的插件!
config
  .plugin('clean')
    .use(CleanPlugin, [['dist'], { root: '/dir' }]);

// 導出這個修改完成的要被webpack使用的配置對象
module.exports = config.toConfig();

共享配置也很簡單。僅僅導出配置 和 在傳遞給webpack以前調用 .toConfig() 方法將配置導出給webpack使用。

// 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

webpack-chain 中的核心API接口之一是 ChainedMap. 一個 ChainedMap的操做相似於JavaScript Map, 爲鏈式和生成配置提供了一些便利。 若是一個屬性被標記一個 ChainedMap, 則它將具備以下的API和方法:

除非另有說明,不然這些方法將返回 ChainedMap , 容許鏈式調用這些方法。

// 從 Map 移除全部 配置.
clear()
// 經過鍵值從 Map 移除單個配置.
// key: *
delete(key)
// 獲取 Map 中相應鍵的值
// key: *
// returns: value
get(key)
// 獲取 Map 中相應鍵的值
// 若是鍵在Map中不存在,則ChainedMap中該鍵的值會被配置爲fn的返回值.
// key: *
// fn: Function () -> value
// returns: value
getOrCompute(key, fn)
// 配置Map中 已存在的鍵的值
// key: *
// value: *
set(key, value)
// Map中是否存在一個配置值的特定鍵,返回 真或假
// key: *
// returns: Boolean
has(key)
// 返回 Map中已存儲的全部值的數組
// returns: Array
values()
// 返回Map中所有配置的一個對象, 其中 鍵是這個對象屬性,值是相應鍵的值,
// 若是Map是空,返回 `undefined`
// 使用 `.before() 或 .after()` 的ChainedMap, 則將按照屬性名進行排序。
// returns: Object, undefined if empty
entries()
//  提供一個對象,這個對象的屬性和值將 映射進 Map。
// 你也能夠提供一個數組做爲第二個參數以便忽略合併的屬性名稱。
// obj: Object
// omit: Optional Array
merge(obj, omit)
// 對當前配置上下文執行函數。
// handler: Function -> ChainedMap
  // 一個把ChainedMap實例做爲單個參數的函數
batch(handler)
// 條件執行一個函數去繼續配置
// condition: Boolean
// whenTruthy: Function -> ChainedMap
  // 當條件爲真,調用把ChainedMap實例做爲單一參數傳入的函數
// whenFalsy: Optional Function -> ChainedMap
  // 當條件爲假,調用把ChainedMap實例做爲單一參數傳入的函數
when(condition, whenTruthy, whenFalsy)

ChainedSet

webpack-chain 中的核心API接口另外一個是 ChainedSet. 一個 ChainedSet的操做相似於JavaScript Map, 爲鏈式和生成配置提供了一些便利。 若是一個屬性被標記一個 ChainedSet, 則它將具備以下的API和方法:

除非另有說明,不然這些方法將返回 ChainedSet , 容許鏈式調用這些方法。

// 添加/追加 給Set末尾位置一個值.
// value: *
add(value)
// 添加 給Set開始位置一個值.
// value: *
prepend(value)
// 移除Set中所有值.
clear()
// 移除Set中一個指定的值.
// value: *
delete(value)
// 檢測Set中是否存在一個值.
// value: *
// returns: Boolean
has(value)
// 返回Set中值的數組.
// returns: Array
values()
// 鏈接給定的數組到 Set 尾部。
// arr: Array
merge(arr)
// 對當前配置上下文執行函數。
// handler: Function -> ChainedSet
  // 一個把 ChainedSet 實例做爲單個參數的函數
batch(handler)
// 條件執行一個函數去繼續配置
// condition: Boolean
// whenTruthy: Function -> ChainedSet
  // 當條件爲真,調用把 ChainedSet 實例做爲單一參數傳入的函數
// whenFalsy: Optional Function -> ChainedSet
  // 當條件爲假,調用把 ChainedSet 實例做爲單一參數傳入的函數
when(condition, whenTruthy, whenFalsy)

速記方法

存在許多簡寫方法,用於 使用與簡寫方法名稱相同的鍵在 ChainedMap 設置一個值
例如, devServer.hot 是一個速記方法, 所以它能夠用做:

// 在 ChainedMap 上設置一個值的 速記方法
devServer.hot(true);

// 上述方法等效於:
devServer.set('hot', true);

一個速記方法是可鏈式的,所以調用它將返回 原實例,容許你繼續鏈式使用

配置

建立一個新的配置對象

const Config = require('webpack-chain');

const config = new Config();

移動到API的更深層將改變你正在修改的內容的上下文。 你能夠經過 config在此引用頂級配置或者經過調用 .end() 方法向上移動一級 使你移回更高的 上下文環境。
若是你熟悉jQuery, 這裏與其 .end() 工做原理相似。除非另有說明,不然所有的API調用都將在當前上下文中返回API實例。 這樣,你能夠根據須要連續 鏈式API調用.
有關對全部速記和低級房費有效的特定值的詳細信息,請參閱 webpack文檔層次結構 中的相應名詞。

Config : ChainedMap

配置速記方法

config
  .amd(amd)
  .bail(bail)
  .cache(cache)
  .devtool(devtool)
  .context(context)
  .externals(externals)
  .loader(loader)
  .mode(mode)
  .parallelism(parallelism)
  .profile(profile)
  .recordsPath(recordsPath)
  .recordsInputPath(recordsInputPath)
  .recordsOutputPath(recordsOutputPath)
  .stats(stats)
  .target(target)
  .watch(watch)
  .watchOptions(watchOptions)

配置 entryPoints

// 回到 config.entryPoints : ChainedMap
config.entry(name) : ChainedSet

config
  .entry(name)
    .add(value)
    .add(value)

config
  .entry(name)
    .clear()

// 用低級別 config.entryPoints:

config.entryPoints
  .get(name)
    .add(value)
    .add(value)

config.entryPoints
  .get(name)
    .clear()

配置 output: 速記 方法

config.output : ChainedMap

config.output
  .auxiliaryComment(auxiliaryComment)
  .chunkFilename(chunkFilename)
  .chunkLoadTimeout(chunkLoadTimeout)
  .crossOriginLoading(crossOriginLoading)
  .devtoolFallbackModuleFilenameTemplate(devtoolFallbackModuleFilenameTemplate)
  .devtoolLineToLine(devtoolLineToLine)
  .devtoolModuleFilenameTemplate(devtoolModuleFilenameTemplate)
  .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)

配置 resolve(解析): 速記方法

config.resolve : ChainedMap

config.resolve
  .cachePredicate(cachePredicate)
  .cacheWithContext(cacheWithContext)
  .enforceExtension(enforceExtension)
  .enforceModuleExtension(enforceModuleExtension)
  .unsafeCache(unsafeCache)
  .symlinks(symlinks)

配置 resolve 別名

config.resolve.alias : ChainedMap

config.resolve.alias
  .set(key, value)
  .set(key, value)
  .delete(key)
  .clear()

配置 resolve modules

config.resolve.modules : ChainedSet

config.resolve.modules
  .add(value)
  .prepend(value)
  .clear()

配置 resolve aliasFields

config.resolve.aliasFields : ChainedSet

config.resolve.aliasFields
  .add(value)
  .prepend(value)
  .clear()

配置 resolve descriptionFields

config.resolve.descriptionFields : ChainedSet

config.resolve.descriptionFields
  .add(value)
  .prepend(value)
  .clear()

配置 resolve extensions

config.resolve.extensions : ChainedSet

config.resolve.extensions
  .add(value)
  .prepend(value)
  .clear()

配置 resolve mainFields

config.resolve.mainFields : ChainedSet

config.resolve.mainFields
  .add(value)
  .prepend(value)
  .clear()

配置 resolve mainFiles

config.resolve.mainFiles : ChainedSet

config.resolve.mainFiles
  .add(value)
  .prepend(value)
  .clear()

配置 resolveLoader

當前API config.resolveLoader 相同於 配置 config.resolve 用下面的配置:

配置 resolveLoader moduleExtensions
config.resolveLoader.moduleExtensions : ChainedSet

config.resolveLoader.moduleExtensions
  .add(value)
  .prepend(value)
  .clear()
配置 resolveLoader packageMains
config.resolveLoader.packageMains : ChainedSet

config.resolveLoader.packageMains
  .add(value)
  .prepend(value)
  .clear()

配置 performance(性能): 速記方法

config.performance : ChainedMap

config.performance
  .hints(hints)
  .maxEntrypointSize(maxEntrypointSize)
  .maxAssetSize(maxAssetSize)
  .assetFilter(assetFilter)

配置 optimizations(優化): 速記方法

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)

配置 optimization minimizers(最小優化器)

// 回到 config.optimization.minimizers
config.optimization
  .minimizer(name) : ChainedMap

配置 optimization minimizers: 添加

注意: 不要用 new 去建立最小優化器插件,由於已經爲你作好了。

config.optimization
  .minimizer(name)
  .use(WebpackPlugin, args)

// 例如

config.optimization
  .minimizer('css')
  .use(OptimizeCSSAssetsPlugin, [{ cssProcessorOptions: { safe: true } }])

// Minimizer 插件也能夠由它們的路徑指定,從而容許在不使用插件或webpack配置的狀況下跳過昂貴的 require s。
config.optimization
  .minimizer('css')
  .use(require.resolve('optimize-css-assets-webpack-plugin'), [{ cssProcessorOptions: { safe: true } }])

配置 optimization minimizers: 修改參數

config.optimization
  .minimizer(name)
  .tap(args => newArgs)

// 例如
config
  .minimizer('css')
  .tap(args => [...args, { cssProcessorOptions: { safe: false } }])

配置 optimization minimizers: 修改實例

config.optimization
  .minimizer(name)
  .init((Plugin, args) => new Plugin(...args));

配置 optimization minimizers: 移除

config.optimization.minimizers.delete(name)

配置插件

// 回到 config.plugins
config.plugin(name) : ChainedMap

配置插件: 添加

注意: 不要用 new 去建立插件,由於已經爲你作好了。

config
  .plugin(name)
  .use(WebpackPlugin, args)

// 例如
config
  .plugin('hot')
  .use(webpack.HotModuleReplacementPlugin);

// 插件也能夠由它們的路徑指定,從而容許在不使用插件或webpack配置的狀況下跳過昂貴的 require s。
config
  .plugin('env')
  .use(require.resolve('webpack/lib/EnvironmentPlugin'), [{ 'VAR': false }]);

配置插件: 修改參數

config
  .plugin(name)
  .tap(args => newArgs)

// 例如
config
  .plugin('env')
  .tap(args => [...args, 'SECRET_KEY']);

配置插件: 修改實例

config
  .plugin(name)
  .init((Plugin, args) => new Plugin(...args));

配置插件: 移除

config.plugins.delete(name)

配置插件: 在以前調用

指定當前插件上下文應該在另外一個指定插件以前執行,你不能在同一個插件上同時使用 .before().after()

config
  .plugin(name)
    .before(otherName)

// 例如
config
  .plugin('html-template')
    .use(HtmlWebpackTemplate)
    .end()
  .plugin('script-ext')
    .use(ScriptExtWebpackPlugin)
    .before('html-template');

Config plugins: 在以後調用

指定當前插件上下文應該在另外一個指定插件以後執行,你不能在同一個插件上同時使用 .before().after()

config
  .plugin(name)
    .after(otherName)

// 例如
config
  .plugin('html-template')
    .after('script-ext')
    .use(HtmlWebpackTemplate)
    .end()
  .plugin('script-ext')
    .use(ScriptExtWebpackPlugin);

配置 resolve 插件

// 回到 config.resolve.plugins
config.resolve.plugin(name) : ChainedMap

配置 resolve 插件: 添加

注意: 不要用 new 去建立插件,由於已經爲你作好了。

config.resolve
  .plugin(name)
  .use(WebpackPlugin, args)

配置 resolve 插件: 修改參數

config.resolve
  .plugin(name)
  .tap(args => newArgs)

配置 resolve 插件: 修改實例

config.resolve
  .plugin(name)
  .init((Plugin, args) => new Plugin(...args))

配置 resolve 插件: 移除

config.resolve.plugins.delete(name)

配置 resolve 插件: 在以前調用

指定當前插件上下文應該在另外一個指定插件以前執行,你不能在同一個插件上同時使用 .before().after()

config.resolve
  .plugin(name)
    .before(otherName)

// 例如

config.resolve
  .plugin('beta')
    .use(BetaWebpackPlugin)
    .end()
  .plugin('alpha')
    .use(AlphaWebpackPlugin)
    .before('beta');

配置 resolve 插件: 在以後調用

指定當前插件上下文應該在另外一個指定插件以後執行,你不能在同一個插件上同時使用 .before().after()

config.resolve
  .plugin(name)
    .after(otherName)

// 例如
config.resolve
  .plugin('beta')
    .after('alpha')
    .use(BetaWebpackTemplate)
    .end()
  .plugin('alpha')
    .use(AlphaWebpackPlugin);

配置 node

config.node : ChainedMap

config.node
  .set('__dirname', 'mock')
  .set('__filename', 'mock');

配置 devServer

config.devServer : ChainedMap

配置 devServer allowedHosts

config.devServer.allowedHosts : ChainedSet

config.devServer.allowedHosts
  .add(value)
  .prepend(value)
  .clear()

配置 devServer: 速記方法

config.devServer
  .bonjour(bonjour)
  .clientLogLevel(clientLogLevel)
  .color(color)
  .compress(compress)
  .contentBase(contentBase)
  .disableHostCheck(disableHostCheck)
  .filename(filename)
  .headers(headers)
  .historyApiFallback(historyApiFallback)
  .host(host)
  .hot(hot)
  .hotOnly(hotOnly)
  .https(https)
  .inline(inline)
  .info(info)
  .lazy(lazy)
  .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)
  .staticOptions(staticOptions)
  .stats(stats)
  .stdin(stdin)
  .useLocalIp(useLocalIp)
  .watchContentBase(watchContentBase)
  .watchOptions(watchOptions)

配置 module

config.module : ChainedMap

配置 module: 速記方法

config.module : ChainedMap

config.module
  .noParse(noParse)

配置 module rules: 速記方法

config.module.rules : ChainedMap

config.module
  .rule(name)
    .test(test)
    .pre()
    .post()
    .enforce(preOrPost)

配置 module rules uses (loaders): 建立

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'] });

配置 module rules uses (loaders): 修改選項

config.module
  .rule(name)
    .use(name)
      .tap(options => newOptions)

// 例如

config.module
  .rule('compile')
    .use('babel')
      .tap(options => merge(options, {
        plugins: ['@babel/plugin-proposal-class-properties']
      }));

配置 module rules oneOfs (條件 rules)

config.module.rules{}.oneOfs : ChainedMap<Rule>

config.module
  .rule(name)
    .oneOf(name)

// 例如

config.module
  .rule('css')
    .oneOf('inline')
      .resourceQuery(/inline/)
      .use('url')
        .loader('url-loader')
        .end()
      .end()
    .oneOf('external')
      .resourceQuery(/external/)
      .use('file')
        .loader('file-loader')

合併配置

webpack-chain 支持將對象合併到配置實例,改實例相似於 webpack-chain 模式 佈局的佈局。 請注意,這不是 webpack 配置對象,但您能夠再將webpack配置對象提供給webpack-chain 以匹配器佈局以前對其進行轉換。

config.merge({ devtool: 'source-map' });

config.get('devtool') // "source-map"
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
  },

  optimizations: {
    concatenateModules,
    flagIncludedChunks,
    mergeDuplicateChunks,
    minimize,
    minimizer,
    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],

        oneOf: {
          [name]: Rule
        },

        use: {
          [name]: {
            loader: LoaderString,
            options: LoaderOptions,
            before,
            after
          }
        }
      }
    }
  }
})

條件配置

當使用的狀況下工做ChainedMap和ChainedSet,則可使用執行條件的配置when。您必須指定一個表達式 when(),以評估其真實性或虛假性。若是表達式是真實的,則將使用當前連接實例的實例調用第一個函數參數。您能夠選擇提供在條件爲假時調用的第二個函數,該函數也是當前連接的實例。

// 示例:僅在生產期間添加minify插件
config
  .when(process.env.NODE_ENV === 'production', config => {
    config
      .plugin('minify')
      .use(BabiliWebpackPlugin);
  });
// 例:只有在生產過程當中添加縮小插件,不然設置devtool到源映射
config
  .when(process.env.NODE_ENV === 'production',
    config => config.plugin('minify').use(BabiliWebpackPlugin),
    config => config.devtool('source-map')
  );

檢查生成的配置

您可使用檢查生成的webpack配置config.toString()。這將生成配置的字符串化版本,其中包含命名規則,用法和插件的註釋提示:

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'
          }
        ]
      }
    ]
  }
}

默認狀況下,若是生成的字符串包含須要的函數和插件,則不能直接用做真正的webpack配置。爲了生成可用的配置,您能夠經過__expression在其上設置特殊屬性來自定義函數和插件的字符串化方式:

class MyPlugin {}
MyPlugin.__expression = `require('my-plugin')`;

function myFunction () {}
myFunction.__expression = `require('my-function')`;

config
  .plugin('example')
    .use(MyPlugin, [{ fn: myFunction }]);

config.toString();

/*
{
  plugins: [
    new (require('my-plugin'))({
      fn: require('my-function')
    })
  ]
}
*/

經過其路徑指定的插件將require()自動生成其語句:

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'
      }
    )
  ]
}

您還能夠調用toString靜態方法Config,以便在字符串化以前修改配置對象。

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'
            }
          }
        ]
      }
    ]
  }
}
相關文章
相關標籤/搜索