index.js 3.55 KB
Newer Older
Kriengkrai Yothee's avatar
Kriengkrai Yothee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _schemaUtils = _interopRequireDefault(require("schema-utils"));

var _pLimit = _interopRequireDefault(require("p-limit"));

var _options = _interopRequireDefault(require("./options.json"));

var _preProcessPattern = _interopRequireDefault(require("./preProcessPattern"));

var _processPattern = _interopRequireDefault(require("./processPattern"));

var _postProcessPattern = _interopRequireDefault(require("./postProcessPattern"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

class CopyPlugin {
  constructor(options = {}) {
    (0, _schemaUtils.default)(_options.default, options, {
      name: 'Copy Plugin',
      baseDataPath: 'options'
    });
    this.patterns = options.patterns;
    this.options = options.options || {};
  }

  apply(compiler) {
    const plugin = {
      name: 'CopyPlugin'
    };
    const limit = (0, _pLimit.default)(this.options.concurrency || 100);
    compiler.hooks.thisCompilation.tap(plugin, compilation => {
      const logger = compilation.getLogger('copy-webpack-plugin');
      compilation.hooks.additionalAssets.tapAsync('copy-webpack-plugin', async callback => {
        logger.debug('start to adding additional assets');
        const globalRef = {
          context: compiler.options.context,
          logger,
          compilation,
          inputFileSystem: compiler.inputFileSystem,
          output: compiler.options.output.path
        };
        let assets;

        try {
          assets = await Promise.all(this.patterns.map(pattern => limit(async () => {
            const patternAfterPreProcess = await (0, _preProcessPattern.default)(globalRef, pattern);
            const files = await (0, _processPattern.default)(globalRef, patternAfterPreProcess);

            if (!files) {
              return Promise.resolve();
            }

            return Promise.all(files.filter(Boolean).map(file => (0, _postProcessPattern.default)(globalRef, patternAfterPreProcess, file)));
          })));
        } catch (error) {
          compilation.errors.push(error);
          callback();
          return;
        } // Avoid writing assets inside `p-limit`, because it creates concurrency.
        // It could potentially lead to an error - "Multiple assets emit different content to the same filename"


        assets.reduce((acc, val) => acc.concat(val), []).filter(Boolean).forEach(asset => {
          const {
            absoluteFrom,
            targetPath,
            webpackTo,
            source,
            force
          } = asset; // For old version webpack 4

          /* istanbul ignore if */

          if (typeof compilation.emitAsset !== 'function') {
            // eslint-disable-next-line no-param-reassign
            compilation.assets[targetPath] = source;
            return;
          }

          if (compilation.getAsset(targetPath)) {
            if (force) {
              logger.log(`force updating '${webpackTo}' to compilation assets from '${absoluteFrom}'`);
              compilation.updateAsset(targetPath, source);
              return;
            }

            logger.log(`skipping '${webpackTo}', because it already exists`);
            return;
          }

          logger.log(`writing '${webpackTo}' to compilation assets from '${absoluteFrom}'`);
          compilation.emitAsset(targetPath, source);
        });
        logger.debug('end to adding additional assets');
        callback();
      });
    });
  }

}

var _default = CopyPlugin;
exports.default = _default;