| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Alexander Akait @alexander-akait
- */
- "use strict";
- const WebpackError = require("../errors/WebpackError");
- /** @import Module from "../Module" */
- /** @import ModuleGraph from "../ModuleGraph" */
- /** @import NormalModule from "../NormalModule" */
- /** @import RequestShortener from "../RequestShortener" */
- /** @import { PackageCopy } from "./DuplicatePackagesPlugin" */
- /**
- * @param {Module} module the module
- * @returns {string | undefined} directory of the package the module belongs to
- */
- const getPackagePath = (module) => {
- const resolveData =
- /** @type {NormalModule} */
- (module).resourceResolveData;
- return resolveData && resolveData.descriptionFileRoot;
- };
- /**
- * Finds a module outside of the copy that pulled it into the build, so the
- * warning can name the dependency responsible for this copy.
- * @param {PackageCopy} copy the copy
- * @param {ModuleGraph} moduleGraph the module graph
- * @returns {Module | undefined} a module importing this copy, when there is one
- */
- const findImporter = (copy, moduleGraph) => {
- for (const module of copy.modules) {
- for (const origin of moduleGraph
- .getIncomingConnectionsByOriginModule(module)
- .keys()) {
- if (origin && getPackagePath(origin) !== copy.path) return origin;
- }
- }
- };
- /**
- * Warning emitted when one package is included more than once in a build,
- * either in different versions or as several copies of the same version.
- */
- class DuplicatePackagesWarning extends WebpackError {
- /**
- * @param {string} name name of the package
- * @param {PackageCopy[]} copies copies of the package, sorted by path
- * @param {ModuleGraph} moduleGraph the module graph
- * @param {RequestShortener} requestShortener the request shortener
- */
- constructor(name, copies, moduleGraph, requestShortener) {
- const versions = new Set(copies.map((copy) => copy.version));
- const headline =
- versions.size > 1
- ? `Multiple versions of the package "${name}" (${[...versions].join(", ")}) are included in this build:`
- : `The package "${name}" (${copies[0].version}) is included ${copies.length} times in this build:`;
- const copiesList = copies
- .map((copy) => {
- const importer = findImporter(copy, moduleGraph);
- let message = `* ${copy.version} from ${requestShortener.shorten(copy.path)}, ${copy.modules.length} module(s)`;
- if (importer !== undefined) {
- message += `\n Included by ${importer.readableIdentifier(requestShortener)}`;
- }
- return message;
- })
- .join("\n");
- super(`webpack performance recommendations:
- ${headline}
- ${copiesList}
- Every copy is bundled separately and has its own module state, which increases the output size and can break \`instanceof\` checks and configuration shared through the package.
- Align the version ranges requiring this package, or force a single version with "resolutions"/"overrides" in your package.json.`);
- /** @type {string} */
- this.name = "DuplicatePackagesWarning";
- /** @type {Module} */
- this.module = copies[0].modules[0];
- }
- }
- module.exports = DuplicatePackagesWarning;
|