177 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const ChainedMap = require('./ChainedMap');
 | 
						|
const ChainedSet = require('./ChainedSet');
 | 
						|
const Resolve = require('./Resolve');
 | 
						|
const ResolveLoader = require('./ResolveLoader');
 | 
						|
const Output = require('./Output');
 | 
						|
const DevServer = require('./DevServer');
 | 
						|
const Plugin = require('./Plugin');
 | 
						|
const Module = require('./Module');
 | 
						|
const Optimization = require('./Optimization');
 | 
						|
const Performance = require('./Performance');
 | 
						|
 | 
						|
module.exports = class extends ChainedMap {
 | 
						|
  constructor() {
 | 
						|
    super();
 | 
						|
    this.devServer = new DevServer(this);
 | 
						|
    this.entryPoints = new ChainedMap(this);
 | 
						|
    this.module = new Module(this);
 | 
						|
    this.node = new ChainedMap(this);
 | 
						|
    this.optimization = new Optimization(this);
 | 
						|
    this.output = new Output(this);
 | 
						|
    this.performance = new Performance(this);
 | 
						|
    this.plugins = new ChainedMap(this);
 | 
						|
    this.resolve = new Resolve(this);
 | 
						|
    this.resolveLoader = new ResolveLoader(this);
 | 
						|
    this.extend([
 | 
						|
      'amd',
 | 
						|
      'bail',
 | 
						|
      'cache',
 | 
						|
      'context',
 | 
						|
      'devtool',
 | 
						|
      'externals',
 | 
						|
      'loader',
 | 
						|
      'mode',
 | 
						|
      'name',
 | 
						|
      'parallelism',
 | 
						|
      'profile',
 | 
						|
      'recordsInputPath',
 | 
						|
      'recordsPath',
 | 
						|
      'recordsOutputPath',
 | 
						|
      'stats',
 | 
						|
      'target',
 | 
						|
      'watch',
 | 
						|
      'watchOptions',
 | 
						|
    ]);
 | 
						|
  }
 | 
						|
 | 
						|
  static toString(config, { verbose = false, configPrefix = 'config' } = {}) {
 | 
						|
    // eslint-disable-next-line global-require
 | 
						|
    const { stringify } = require('javascript-stringify');
 | 
						|
 | 
						|
    return stringify(
 | 
						|
      config,
 | 
						|
      (value, indent, stringify) => {
 | 
						|
        // improve plugin output
 | 
						|
        if (value && value.__pluginName) {
 | 
						|
          const prefix = `/* ${configPrefix}.${value.__pluginType}('${value.__pluginName}') */\n`;
 | 
						|
          const constructorExpression = value.__pluginPath
 | 
						|
            ? // The path is stringified to ensure special characters are escaped
 | 
						|
              // (such as the backslashes in Windows-style paths).
 | 
						|
              `(require(${stringify(value.__pluginPath)}))`
 | 
						|
            : value.__pluginConstructorName;
 | 
						|
 | 
						|
          if (constructorExpression) {
 | 
						|
            // get correct indentation for args by stringifying the args array and
 | 
						|
            // discarding the square brackets.
 | 
						|
            const args = stringify(value.__pluginArgs).slice(1, -1);
 | 
						|
            return `${prefix}new ${constructorExpression}(${args})`;
 | 
						|
          }
 | 
						|
          return (
 | 
						|
            prefix +
 | 
						|
            stringify(
 | 
						|
              value.__pluginArgs && value.__pluginArgs.length
 | 
						|
                ? { args: value.__pluginArgs }
 | 
						|
                : {},
 | 
						|
            )
 | 
						|
          );
 | 
						|
        }
 | 
						|
 | 
						|
        // improve rule/use output
 | 
						|
        if (value && value.__ruleNames) {
 | 
						|
          const ruleTypes = value.__ruleTypes;
 | 
						|
          const prefix = `/* ${configPrefix}.module${value.__ruleNames
 | 
						|
            .map(
 | 
						|
              (r, index) => `.${ruleTypes ? ruleTypes[index] : 'rule'}('${r}')`,
 | 
						|
            )
 | 
						|
            .join('')}${
 | 
						|
            value.__useName ? `.use('${value.__useName}')` : ``
 | 
						|
          } */\n`;
 | 
						|
          return prefix + stringify(value);
 | 
						|
        }
 | 
						|
 | 
						|
        if (value && value.__expression) {
 | 
						|
          return value.__expression;
 | 
						|
        }
 | 
						|
 | 
						|
        // shorten long functions
 | 
						|
        if (typeof value === 'function') {
 | 
						|
          if (!verbose && value.toString().length > 100) {
 | 
						|
            return `function () { /* omitted long function */ }`;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        return stringify(value);
 | 
						|
      },
 | 
						|
      2,
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  entry(name) {
 | 
						|
    return this.entryPoints.getOrCompute(name, () => new ChainedSet(this));
 | 
						|
  }
 | 
						|
 | 
						|
  plugin(name) {
 | 
						|
    return this.plugins.getOrCompute(name, () => new Plugin(this, name));
 | 
						|
  }
 | 
						|
 | 
						|
  toConfig() {
 | 
						|
    const entryPoints = this.entryPoints.entries() || {};
 | 
						|
 | 
						|
    return this.clean(
 | 
						|
      Object.assign(this.entries() || {}, {
 | 
						|
        node: this.node.entries(),
 | 
						|
        output: this.output.entries(),
 | 
						|
        resolve: this.resolve.toConfig(),
 | 
						|
        resolveLoader: this.resolveLoader.toConfig(),
 | 
						|
        devServer: this.devServer.toConfig(),
 | 
						|
        module: this.module.toConfig(),
 | 
						|
        optimization: this.optimization.toConfig(),
 | 
						|
        plugins: this.plugins.values().map((plugin) => plugin.toConfig()),
 | 
						|
        performance: this.performance.entries(),
 | 
						|
        entry: Object.keys(entryPoints).reduce(
 | 
						|
          (acc, key) =>
 | 
						|
            Object.assign(acc, { [key]: entryPoints[key].values() }),
 | 
						|
          {},
 | 
						|
        ),
 | 
						|
      }),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  toString(options) {
 | 
						|
    return module.exports.toString(this.toConfig(), options);
 | 
						|
  }
 | 
						|
 | 
						|
  merge(obj = {}, omit = []) {
 | 
						|
    const omissions = [
 | 
						|
      'node',
 | 
						|
      'output',
 | 
						|
      'resolve',
 | 
						|
      'resolveLoader',
 | 
						|
      'devServer',
 | 
						|
      'optimization',
 | 
						|
      'performance',
 | 
						|
      'module',
 | 
						|
    ];
 | 
						|
 | 
						|
    if (!omit.includes('entry') && 'entry' in obj) {
 | 
						|
      Object.keys(obj.entry).forEach((name) =>
 | 
						|
        this.entry(name).merge([].concat(obj.entry[name])),
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (!omit.includes('plugin') && 'plugin' in obj) {
 | 
						|
      Object.keys(obj.plugin).forEach((name) =>
 | 
						|
        this.plugin(name).merge(obj.plugin[name]),
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    omissions.forEach((key) => {
 | 
						|
      if (!omit.includes(key) && key in obj) {
 | 
						|
        this[key].merge(obj[key]);
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    return super.merge(obj, [...omit, ...omissions, 'entry', 'plugin']);
 | 
						|
  }
 | 
						|
};
 |