<commit_before>'use strict';

// use Polyfill for util.promisify in node versions < v8
const promisify = require('util.promisify');

const vm = require('vm');
const fs = require('fs');
const _ = require('lodash');
const path = require('path');
const childCompiler = require('./lib/compiler.js');
const prettyError = require('./lib/errors.js');
const chunkSorter = require('./lib/chunksorter.js');

const fsStatAsync = promisify(fs.stat);
const fsReadFileAsync = promisify(fs.readFile);

class HtmlWebpackPlugin {
  constructor (options) {
    // Default options
    this.options = _.extend({
      template: path.join(__dirname, 'default_index.ejs'),
      filename: 'index.html',
      hash: false,
      inject: true,
      compile: true,
      favicon: false,
      minify: false,
      cache: true,
      showErrors: true,
      chunks: 'all',
      excludeChunks: [],
      title: 'Webpack App',
      xhtml: false
    }, options);
  }

  apply (compiler) {
    const self = this;
    let isCompilationCached = false;
    let compilationPromise;

    this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);

    // convert absolute filename into relative so that webpack can
    // generate it at correct location
    const filename = this.options.filename;
    if (path.resolve(filename) === path.normalize(filename)) {
      this.options.filename = path.relative(compiler.options.output.path, filename);
    }

    // setup hooks for webpack 4
    if (compiler.hooks) {
      compiler.hooks.compilation.tap('HtmlWebpackPluginHooks', compilation => {
        const SyncWaterfallHook = require('tapable').SyncWaterfallHook;
        const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
        compilation.hooks.htmlWebpackPluginAlterChunks = new SyncWaterfallHook(['chunks', 'objectWithPluginRef']);
        compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginAlterAssetTags = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginAfterHtmlProcessing = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginAfterEmit = new AsyncSeriesWaterfallHook(['pluginArgs']);
      });
    }

    compiler.plugin('make', (compilation, callback) => {
      // Compile the template (queued)
      compilationPromise = childCompiler.compileTemplate(self.options.template, compiler.context, self.options.filename, compilation)
        .catch(err => {
          compilation.errors.push(prettyError(err, compiler.context).toString());
          return {
            content: self.options.showErrors ? prettyError(err, compiler.context).toJsonHtml() : 'ERROR',
            outputName: self.options.filename
          };
        })
        .then(compilationResult => {
          // If the compilation change didnt change the cache is valid
          isCompilationCached = compilationResult.hash && self.childCompilerHash === compilationResult.hash;
          self.childCompilerHash = compilationResult.hash;
          self.childCompilationOutputName = compilationResult.outputName;
          callback();
          return compilationResult.content;
        });
    });

    compiler.plugin('emit', (compilation, callback) => {
      const applyPluginsAsyncWaterfall = self.applyPluginsAsyncWaterfall(compilation);
      // Get all chunks
      const allChunks = compilation.getStats().toJson().chunks;
      // Filter chunks (options.chunks and options.excludeCHunks)
      let chunks = self.filterChunks(allChunks, self.options.chunks, self.options.excludeChunks);
      // Sort chunks
      chunks = self.sortChunks(chunks, self.options.chunksSortMode, compilation.chunkGroups);
      // Let plugins alter the chunks and the chunk sorting
      if (compilation.hooks) {
        chunks = compilation.hooks.htmlWebpackPluginAlterChunks.call(chunks, { plugin: self });
      } else {
        // Before Webpack 4
        chunks = compilation.applyPluginsWaterfall('html-webpack-plugin-alter-chunks', chunks, { plugin: self });
      }
      // Get assets
      const assets = self.htmlWebpackPluginAssets(compilation, chunks);
      // If this is a hot update compilation, move on!
      // This solves a problem where an `index.html` file is generated for hot-update js files
      // It only happens in Webpack 2, where hot updates are emitted separately before the full bundle
      if (self.isHotUpdateCompilation(assets)) {
        return callback();<commit_msg>refactor(performance): Reduce the generated chunk information to speed up build time<commit_after>'use strict';

// use Polyfill for util.promisify in node versions < v8
const promisify = require('util.promisify');

const vm = require('vm');
const fs = require('fs');
const _ = require('lodash');
const path = require('path');
const childCompiler = require('./lib/compiler.js');
const prettyError = require('./lib/errors.js');
const chunkSorter = require('./lib/chunksorter.js');

const fsStatAsync = promisify(fs.stat);
const fsReadFileAsync = promisify(fs.readFile);

class HtmlWebpackPlugin {
  constructor (options) {
    // Default options
    this.options = _.extend({
      template: path.join(__dirname, 'default_index.ejs'),
      filename: 'index.html',
      hash: false,
      inject: true,
      compile: true,
      favicon: false,
      minify: false,
      cache: true,
      showErrors: true,
      chunks: 'all',
      excludeChunks: [],
      title: 'Webpack App',
      xhtml: false
    }, options);
  }

  apply (compiler) {
    const self = this;
    let isCompilationCached = false;
    let compilationPromise;

    this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);

    // convert absolute filename into relative so that webpack can
    // generate it at correct location
    const filename = this.options.filename;
    if (path.resolve(filename) === path.normalize(filename)) {
      this.options.filename = path.relative(compiler.options.output.path, filename);
    }

    // setup hooks for webpack 4
    if (compiler.hooks) {
      compiler.hooks.compilation.tap('HtmlWebpackPluginHooks', compilation => {
        const SyncWaterfallHook = require('tapable').SyncWaterfallHook;
        const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
        compilation.hooks.htmlWebpackPluginAlterChunks = new SyncWaterfallHook(['chunks', 'objectWithPluginRef']);
        compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginAlterAssetTags = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginAfterHtmlProcessing = new AsyncSeriesWaterfallHook(['pluginArgs']);
        compilation.hooks.htmlWebpackPluginAfterEmit = new AsyncSeriesWaterfallHook(['pluginArgs']);
      });
    }

    compiler.plugin('make', (compilation, callback) => {
      // Compile the template (queued)
      compilationPromise = childCompiler.compileTemplate(self.options.template, compiler.context, self.options.filename, compilation)
        .catch(err => {
          compilation.errors.push(prettyError(err, compiler.context).toString());
          return {
            content: self.options.showErrors ? prettyError(err, compiler.context).toJsonHtml() : 'ERROR',
            outputName: self.options.filename
          };
        })
        .then(compilationResult => {
          // If the compilation change didnt change the cache is valid
          isCompilationCached = compilationResult.hash && self.childCompilerHash === compilationResult.hash;
          self.childCompilerHash = compilationResult.hash;
          self.childCompilationOutputName = compilationResult.outputName;
          callback();
          return compilationResult.content;
        });
    });

    compiler.plugin('emit', (compilation, callback) => {
      const applyPluginsAsyncWaterfall = self.applyPluginsAsyncWaterfall(compilation);
      // Get chunks info as json
      // Note: we're excluding stuff that we don't need to improve toJson serialization speed.
      const chunkOnlyConfig = {
        assets: false,
        cached: false,
        children: false,
        chunks: true,
        chunkModules: false,
        chunkOrigins: false,
        errorDetails: false,
        hash: false,
        modules: false,
        reasons: false,
        source: false,
        timings: false,
        version: false
      };
      const allChunks = compilation.getStats().toJson(chunkOnlyConfig).chunks;
      // Filter chunks (options.chunks and options.excludeCHunks)
      let chunks = self.filterChunks(allChunks, self.options.chunks, self.options.excludeChunks);
      // Sort chunks
      chunks = self.sortChunks(chunks, self.options.chunksSortMode, compilation.chunkGroups);
      // Let plugins alter the chunks and the chunk sorting
      if (compilation.hooks) {
        chunks = compilation.hooks.htmlWebpackPluginAlterChunks.call(chunks, { plugin: self });
      } else {
        // Before Webpack 4
        chunks = compilation.applyPluginsWaterfall('html-webpack-plugin-alter-chunks', chunks, { plugin: self });
      }
      // Get assets
      const assets = self.htmlWebpackPluginAssets(compilation, chunks);
      // If this is a hot update compilation, move on!
      // This solves a problem where an `index.html` file is generated for hot-update js files
      // It only happens in Webpack 2, where hot updates are emitted separately before the full bundle
      if (self.isHotUpdateCompilation(assets)) {
        return callback();
{'fraction_non_alphanumeric': 0.10721483272873841, 'fraction_numerical': 0.0008061265618702137, 'mean_word_length': 3.287257019438445, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '689446', 'n_tokens_mistral': 2620, 'n_tokens_neox': 2620, 'n_words': 634}