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'
            }
          }
        ]
      }
    ]
  }
}
相关文章
相关标签/搜索