webpack-remove-empty-scripts
Version:
Webpack plugin removes empty JavaScript files generated when using styles.
146 lines (132 loc) • 5.24 kB
JavaScript
var require$$0 = require("path");
var require$$1 = require("ansis");
function getDefaultExportFromCjs(x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
var utils;
var hasRequiredUtils;
function requireUtils() {
if (hasRequiredUtils) return utils;
hasRequiredUtils = 1;
const outToConsole = (...args) => process.stdout.write(args.join(" ") + "\n");
utils = {
outToConsole
};
return utils;
}
var src;
var hasRequiredSrc;
function requireSrc() {
if (hasRequiredSrc) return src;
hasRequiredSrc = 1;
const path = require$$0;
const {cyan, black, gray} = require$$1;
const {outToConsole} = requireUtils();
const pluginName = "remove-empty-scripts";
const infoPluginName = `\n${black.bgYellow` ${pluginName} `}`;
const errorPluginName = `\n${black.bgRed` ${pluginName} `}`;
let dependencyId = 1;
class WebpackPlugin {
outputPath="";
trash=[];
static STAGE_BEFORE_PROCESS_PLUGINS=100;
static STAGE_AFTER_PROCESS_PLUGINS=200;
constructor(options) {
this.apply = this.apply.bind(this);
this.options = Object.assign({}, defaultOptions, options);
this.enabled = this.options.enabled !== false;
this.verbose = this.options.verbose;
if (!Array.isArray(this.options.ignore)) {
this.options.ignore = [ this.options.ignore ];
}
if (Array.isArray(this.options.extensions)) {
const pattern = this.options.extensions.map((etx => etx[0] === "." ? etx.substring(1) : etx)).join("|");
this.options.extensions = new RegExp(`.(${pattern})([?].*)?$`);
}
}
apply(compiler) {
if (!this.enabled) return;
this.trash = [];
this.outputPath = compiler.options.output.path;
compiler.hooks.thisCompilation.tap(pluginName, (compilation => {
const resourcesCache = [];
compilation.hooks.chunkAsset.tap(pluginName, ((chunk, filename) => {
const {remove: removeAssets, ignore: ignoreEntryResource, extensions: styleExtensionRegexp} = this.options;
if (!removeAssets.test(filename)) return;
const chunkGraph = compilation.chunkGraph;
let entryResources = [];
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
if (!compilation.modules.has(module)) {
throw new Error(`${errorPluginName} Entry module in chunk but not in compilation ${chunk.debugId} ${module.debugId}`);
}
const moduleResources = getEntryResources(compilation, module, resourcesCache);
entryResources = entryResources.concat(moduleResources);
}
const resources = ignoreEntryResource.length > 0 ? entryResources.filter((res => ignoreEntryResource.every((item => !res.match(item))))) : entryResources;
const isEmptyScript = resources.length > 0 && resources.every((resource => styleExtensionRegexp.test(resource)));
if (isEmptyScript) {
const stage = this.options.stage;
if (this.verbose) {
const outputFile = path.join(this.outputPath, filename);
outToConsole(`${infoPluginName} remove ${cyan(outputFile)}`);
}
switch (stage) {
case WebpackPlugin.STAGE_BEFORE_PROCESS_PLUGINS:
compilation.deleteAsset(filename);
break;
case WebpackPlugin.STAGE_AFTER_PROCESS_PLUGINS:
this.trash.push(filename);
break;
default:
throw new Error(`${errorPluginName} Invalid value of config option 'stage': ${gray(stage ? stage.toString() : "")}. ` + `See the option description in README.`);
}
}
}));
compilation.hooks.afterProcessAssets.tap(pluginName, (() => {
this.trash.forEach((file => compilation.deleteAsset(file)));
}));
}));
}
}
const defaultOptions = {
enabled: true,
verbose: false,
extensions: [ "css", "scss", "sass", "less", "styl" ],
ignore: [],
remove: /\.(js|mjs)$/,
stage: WebpackPlugin.STAGE_BEFORE_PROCESS_PLUGINS
};
function getEntryResources(compilation, module, cache) {
const moduleGraph = compilation.moduleGraph, index = moduleGraph.getPreOrderIndex(module), propNameDependencyId = "__webpackRemoveEmptyScriptsUniqueId", resources = [];
if (index == null) return resources;
if (cache[index] !== undefined) return cache[index];
if (typeof module.resource === "string") {
const resources = [ module.resource ];
cache[index] = resources;
return resources;
}
if (module.dependencies) {
module.dependencies.forEach((dependency => {
let module = moduleGraph.getModule(dependency), originModule = moduleGraph.getParentModule(dependency), nextModule = module || originModule, useNextModule = false;
if (!dependency.hasOwnProperty(propNameDependencyId)) {
dependency[propNameDependencyId] = dependencyId++;
useNextModule = true;
}
if (nextModule && useNextModule) {
const dependencyResources = getEntryResources(compilation, nextModule, cache);
for (let i = 0, length = dependencyResources.length; i !== length; i++) {
const file = dependencyResources[i];
if (resources.indexOf(file) < 0) resources.push(file);
}
}
}));
}
if (resources.length > 0) cache[index] = resources;
return resources;
}
src = WebpackPlugin;
return src;
}
var srcExports = requireSrc();
var index = getDefaultExportFromCjs(srcExports);
module.exports = index;