UNPKG

webpack-remove-empty-scripts

Version:

Webpack plugin removes empty JavaScript files generated when using styles.

146 lines (132 loc) 5.24 kB
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;