webpack-chain項目中文翻譯

webpack-chain

注意:這是對原項目readme文件的翻譯,爲啥翻譯這個呢,因爲Vue CLI3腳手架生成的項目使用這種方式配置webpack,但是腳手架中對這塊的介紹不多,所以把這部分翻譯出來,以供團隊和大家參考。

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

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

注意: 雖然 webpack-chain 被廣泛應用在Neutrino中,然而本軟件包完全獨立,可供任何項目使用。

介紹

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

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

通過以下示例可以更容易地解釋這一點。

安裝

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

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

Yarn方式

yarn add --dev webpack-chain

npm方式

npm install --save-dev webpack-chain

入門

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

// 導入 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'
            }
          }
        ]
      }
    ]
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章