Configuration(配置)1

你可能已经注意到很少有webpack配置看上去完全一样。这是因为webpack的配置文件是一个导出一个对象的JavaScript文件。然后webpack基于它本身定义好的属性来处理这个对象。

由于它是一个标准的Node.js CommonJS模块,你可以做如下事情:

  • 通过require(...)import其他文件
  • 通过require(...)使用npm上的工具
  • 使用JavaScript控制流表达式,即?:操作符
  • 为常用的值使用常量或变量
  • 编写或执行函数来生成一部分配置

合适的时候使用上面的特性。

你不应当使用下面的东西。技术上来说你可以使用,但是不推荐

  • 当使用Webpack命令行时去访问命令行参数(应当编写你自己的命令行,或使用--env
  • 导出不确定的值(调用两次webpack应当输出相同的结果)
  • 编写超长的配置(应当分割配置为多个文件)

下面的样例展示了webpack的配置对象可以既有表现力,又有配置性,因为它是代码

最简单的配置

webpack.config.js

var path = require('path');

module.exports = {
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js'
  }
};

多个目标

webpack.config.js

var path = require('path');
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');

var baseConfig = {
  target: 'async-node',
  entry: {
    entry: './entry.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'inline',
      filename: 'inline.js',
      minChunks: Infinity
    }),
    new webpack.optimize.AggressiveSplittingPlugin({
        minSize: 5000,
        maxSize: 10000
    }),
  ]
};

let targets = ['web', 'webworker', 'node', 'async-node', 'node-webkit', 'electron-main'].map((target) => {
  let base = webpackMerge(baseConfig, {
    target: target,
    output: {
      path: path.resolve(__dirname, 'dist/' + target),
      filename: '[name].' + target + '.js'
    }
  });
  return base;
});

module.exports = targets;

ℹ️这篇文档最重要的思想是:有很多不同的方式来格式化和风格化你的webpack配置。关键是坚持你和你的团队能理解、维护的,持久化的东西。

使用TypeScript

下面的样例我们使用TypeScript创建一个angular-cli能用来生成配置的类。

webpack.config.ts

import * as webpackMerge from 'webpack-merge';
import { CliConfig } from './config';
import {
  getWebpackCommonConfig,
  getWebpackDevConfigPartial,
  getWebpackProdConfigPartial,
  getWebpackMobileConfigPartial,
  getWebpackMobileProdConfigPartial
} from './';

export class NgCliWebpackConfig {
  // TODO: When webpack2 types are finished let's replace all these any types
  // so this is more maintainable in the future for devs
  public config: any;
  private webpackDevConfigPartial: any;
  private webpackProdConfigPartial: any;
  private webpackBaseConfig: any;
  private webpackMobileConfigPartial: any;
  private webpackMobileProdConfigPartial: any;

  constructor(public ngCliProject: any, public target: string, public environment: string, outputDir?: string) {
    const config: CliConfig = CliConfig.fromProject();
    const appConfig = config.config.apps[0];

    appConfig.outDir = outputDir || appConfig.outDir;

    this.webpackBaseConfig = getWebpackCommonConfig(this.ngCliProject.root, environment, appConfig);
    this.webpackDevConfigPartial = getWebpackDevConfigPartial(this.ngCliProject.root, appConfig);
    this.webpackProdConfigPartial = getWebpackProdConfigPartial(this.ngCliProject.root, appConfig);

    if (appConfig.mobile){
      this.webpackMobileConfigPartial = getWebpackMobileConfigPartial(this.ngCliProject.root, appConfig);
      this.webpackMobileProdConfigPartial = getWebpackMobileProdConfigPartial(this.ngCliProject.root, appConfig);
      this.webpackBaseConfig = webpackMerge(this.webpackBaseConfig, this.webpackMobileConfigPartial);
      this.webpackProdConfigPartial = webpackMerge(this.webpackProdConfigPartial, this.webpackMobileProdConfigPartial);
    }

    this.generateConfig();
  }

  generateConfig(): void {
    switch (this.target) {
      case "development":
        this.config = webpackMerge(this.webpackBaseConfig, this.webpackDevConfigPartial);
        break;
      case "production":
        this.config = webpackMerge(this.webpackBaseConfig, this.webpackProdConfigPartial);
        break;
      default:
        throw new Error("Invalid build target. Only 'development' and 'production' are available.");
        break;
    }
  }
}

使用JSX

下面的例子,用到了JSX(React JavaScript标记)和Babel来创建一个webpack能理解的JSON配置。(经由Jason Miller提供2

import h from 'jsxobj';

// example of an imported plugin
const CustomPlugin = config => ({
  ...config,
  name: 'custom-plugin'
});

const uglifyJsConfig = {
  compression: true,
  mangle: false
}

export default (
  <webpack target="web" watch>
    <entry path="src/index.js" />
    <resolve>
      <alias {...{
        react: 'preact-compat',
        'react-dom': 'preact-compat'
      }} />
    </resolve>
    <plugins>
      <uglify-js opts={uglifyJsConfig} />
      <CustomPlugin foo="bar" />
    </plugins>
  </webpack>
);
1. https://webpack.js.org/concepts/configuration/
2. 原源代码无法在GitBook编译,将uglify-js配置移出JSX改写了一下。

results matching ""

    No results matching ""