1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- const Module = require("../Module");
- const Template = require("../Template");
- const Parser = require("../Parser");
- const eslintScope = require("eslint-scope");
- const { ConcatSource, ReplaceSource } = require("webpack-sources");
- const DependencyReference = require("../dependencies/DependencyReference");
- const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
- const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
- const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
- const HarmonyExportSpecifierDependency = require("../dependencies/HarmonyExportSpecifierDependency");
- const HarmonyExportExpressionDependency = require("../dependencies/HarmonyExportExpressionDependency");
- const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
- const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
- const createHash = require("../util/createHash");
- /** @typedef {import("../Dependency")} Dependency */
- /** @typedef {import("../Compilation")} Compilation */
- /** @typedef {import("../util/createHash").Hash} Hash */
- /** @typedef {import("../RequestShortener")} RequestShortener */
- const joinIterableWithComma = iterable => {
- // This is more performant than Array.from().join(", ")
- // as it doesn't create an array
- let str = "";
- let first = true;
- for (const item of iterable) {
- if (first) {
- first = false;
- } else {
- str += ", ";
- }
- str += item;
- }
- return str;
- };
- /**
- * @typedef {Object} ConcatenationEntry
- * @property {"concatenated" | "external"} type
- * @property {Module} module
- */
- const ensureNsObjSource = (
- info,
- moduleToInfoMap,
- requestShortener,
- strictHarmonyModule
- ) => {
- if (!info.hasNamespaceObject) {
- info.hasNamespaceObject = true;
- const name = info.exportMap.get(true);
- const nsObj = [`var ${name} = {};`, `__webpack_require__.r(${name});`];
- for (const exportName of info.module.buildMeta.providedExports) {
- const finalName = getFinalName(
- info,
- exportName,
- moduleToInfoMap,
- requestShortener,
- false,
- strictHarmonyModule
- );
- nsObj.push(
- `__webpack_require__.d(${name}, ${JSON.stringify(
- exportName
- )}, function() { return ${finalName}; });`
- );
- }
- info.namespaceObjectSource = nsObj.join("\n") + "\n";
- }
- };
- const getExternalImport = (
- importedModule,
- info,
- exportName,
- asCall,
- strictHarmonyModule
- ) => {
- const used = importedModule.isUsed(exportName);
- if (!used) return "/* unused reexport */undefined";
- const comment =
- used !== exportName ? ` ${Template.toNormalComment(exportName)}` : "";
- switch (importedModule.buildMeta.exportsType) {
- case "named":
- if (exportName === "default") {
- return info.name;
- } else if (exportName === true) {
- info.interopNamespaceObjectUsed = true;
- return info.interopNamespaceObjectName;
- } else {
- break;
- }
- case "namespace":
- if (exportName === true) {
- return info.name;
- } else {
- break;
- }
- default:
- if (strictHarmonyModule) {
- if (exportName === "default") {
- return info.name;
- } else if (exportName === true) {
- info.interopNamespaceObjectUsed = true;
- return info.interopNamespaceObjectName;
- } else {
- return "/* non-default import from non-esm module */undefined";
- }
- } else {
- if (exportName === "default") {
- info.interopDefaultAccessUsed = true;
- return asCall
- ? `${info.interopDefaultAccessName}()`
- : `${info.interopDefaultAccessName}.a`;
- } else if (exportName === true) {
- return info.name;
- } else {
- break;
- }
- }
- }
- const reference = `${info.name}[${JSON.stringify(used)}${comment}]`;
- if (asCall) return `Object(${reference})`;
- return reference;
- };
- const getFinalName = (
- info,
- exportName,
- moduleToInfoMap,
- requestShortener,
- asCall,
- strictHarmonyModule,
- alreadyVisited = new Set()
- ) => {
- switch (info.type) {
- case "concatenated": {
- const directExport = info.exportMap.get(exportName);
- if (directExport) {
- if (exportName === true) {
- ensureNsObjSource(
- info,
- moduleToInfoMap,
- requestShortener,
- strictHarmonyModule
- );
- } else if (!info.module.isUsed(exportName)) {
- return "/* unused export */ undefined";
- }
- if (info.globalExports.has(directExport)) {
- return directExport;
- }
- const name = info.internalNames.get(directExport);
- if (!name) {
- throw new Error(
- `The export "${directExport}" in "${info.module.readableIdentifier(
- requestShortener
- )}" has no internal name`
- );
- }
- return name;
- }
- const reexport = info.reexportMap.get(exportName);
- if (reexport) {
- if (alreadyVisited.has(reexport)) {
- throw new Error(
- `Circular reexports ${Array.from(
- alreadyVisited,
- e =>
- `"${e.module.readableIdentifier(requestShortener)}".${
- e.exportName
- }`
- ).join(
- " --> "
- )} -(circular)-> "${reexport.module.readableIdentifier(
- requestShortener
- )}".${reexport.exportName}`
- );
- }
- alreadyVisited.add(reexport);
- const refInfo = moduleToInfoMap.get(reexport.module);
- if (refInfo) {
- // module is in the concatenation
- return getFinalName(
- refInfo,
- reexport.exportName,
- moduleToInfoMap,
- requestShortener,
- asCall,
- strictHarmonyModule,
- alreadyVisited
- );
- }
- }
- const problem =
- `Cannot get final name for export "${exportName}" in "${info.module.readableIdentifier(
- requestShortener
- )}"` +
- ` (known exports: ${Array.from(info.exportMap.keys())
- .filter(name => name !== true)
- .join(" ")}, ` +
- `known reexports: ${Array.from(info.reexportMap.keys()).join(" ")})`;
- return `${Template.toNormalComment(problem)} undefined`;
- }
- case "external": {
- const importedModule = info.module;
- return getExternalImport(
- importedModule,
- info,
- exportName,
- asCall,
- strictHarmonyModule
- );
- }
- }
- };
- const addScopeSymbols1 = (s, nameSet, scopeSet) => {
- let scope = s;
- while (scope) {
- if (scopeSet.has(scope)) break;
- scopeSet.add(scope);
- for (const variable of scope.variables) {
- nameSet.add(variable.name);
- }
- scope = scope.upper;
- }
- };
- const addScopeSymbols2 = (s, nameSet, scopeSet1, scopeSet2) => {
- let scope = s;
- while (scope) {
- if (scopeSet1.has(scope)) break;
- if (scopeSet2.has(scope)) break;
- scopeSet1.add(scope);
- for (const variable of scope.variables) {
- nameSet.add(variable.name);
- }
- scope = scope.upper;
- }
- };
- const getAllReferences = variable => {
- let set = variable.references;
- // Look for inner scope variables too (like in class Foo { t() { Foo } })
- const identifiers = new Set(variable.identifiers);
- for (const scope of variable.scope.childScopes) {
- for (const innerVar of scope.variables) {
- if (innerVar.identifiers.some(id => identifiers.has(id))) {
- set = set.concat(innerVar.references);
- break;
- }
- }
- }
- return set;
- };
- const getPathInAst = (ast, node) => {
- if (ast === node) {
- return [];
- }
- const nr = node.range;
- const enterNode = n => {
- if (!n) return undefined;
- const r = n.range;
- if (r) {
- if (r[0] <= nr[0] && r[1] >= nr[1]) {
- const path = getPathInAst(n, node);
- if (path) {
- path.push(n);
- return path;
- }
- }
- }
- return undefined;
- };
- var i;
- if (Array.isArray(ast)) {
- for (i = 0; i < ast.length; i++) {
- const enterResult = enterNode(ast[i]);
- if (enterResult !== undefined) return enterResult;
- }
- } else if (ast && typeof ast === "object") {
- const keys = Object.keys(ast);
- for (i = 0; i < keys.length; i++) {
- const value = ast[keys[i]];
- if (Array.isArray(value)) {
- const pathResult = getPathInAst(value, node);
- if (pathResult !== undefined) return pathResult;
- } else if (value && typeof value === "object") {
- const enterResult = enterNode(value);
- if (enterResult !== undefined) return enterResult;
- }
- }
- }
- };
- const getHarmonyExportImportedSpecifierDependencyExports = dep => {
- const importModule = dep._module;
- if (!importModule) return [];
- if (dep._id) {
- // export { named } from "module"
- return [
- {
- name: dep.name,
- id: dep._id,
- module: importModule
- }
- ];
- }
- if (dep.name) {
- // export * as abc from "module"
- return [
- {
- name: dep.name,
- id: true,
- module: importModule
- }
- ];
- }
- // export * from "module"
- return importModule.buildMeta.providedExports
- .filter(exp => exp !== "default" && !dep.activeExports.has(exp))
- .map(exp => {
- return {
- name: exp,
- id: exp,
- module: importModule
- };
- });
- };
- class ConcatenatedModule extends Module {
- constructor(rootModule, modules, concatenationList) {
- super("javascript/esm", null);
- super.setChunks(rootModule._chunks);
- // Info from Factory
- this.rootModule = rootModule;
- this.factoryMeta = rootModule.factoryMeta;
- // Info from Compilation
- this.index = rootModule.index;
- this.index2 = rootModule.index2;
- this.depth = rootModule.depth;
- // Info from Optimization
- this.used = rootModule.used;
- this.usedExports = rootModule.usedExports;
- // Info from Build
- this.buildInfo = {
- strict: true,
- cacheable: modules.every(m => m.buildInfo.cacheable),
- moduleArgument: rootModule.buildInfo.moduleArgument,
- exportsArgument: rootModule.buildInfo.exportsArgument,
- fileDependencies: new Set(),
- contextDependencies: new Set(),
- assets: undefined
- };
- this.built = modules.some(m => m.built);
- this.buildMeta = rootModule.buildMeta;
- // Caching
- this._numberOfConcatenatedModules = modules.length;
- // Graph
- const modulesSet = new Set(modules);
- this.reasons = rootModule.reasons.filter(
- reason =>
- !(reason.dependency instanceof HarmonyImportDependency) ||
- !modulesSet.has(reason.module)
- );
- this.dependencies = [];
- this.blocks = [];
- this.warnings = [];
- this.errors = [];
- this._orderedConcatenationList =
- concatenationList ||
- ConcatenatedModule.createConcatenationList(rootModule, modulesSet, null);
- for (const info of this._orderedConcatenationList) {
- if (info.type === "concatenated") {
- const m = info.module;
- // populate dependencies
- for (const d of m.dependencies.filter(
- dep =>
- !(dep instanceof HarmonyImportDependency) ||
- !modulesSet.has(dep._module)
- )) {
- this.dependencies.push(d);
- }
- // populate blocks
- for (const d of m.blocks) {
- this.blocks.push(d);
- }
- // populate file dependencies
- if (m.buildInfo.fileDependencies) {
- for (const file of m.buildInfo.fileDependencies) {
- this.buildInfo.fileDependencies.add(file);
- }
- }
- // populate context dependencies
- if (m.buildInfo.contextDependencies) {
- for (const context of m.buildInfo.contextDependencies) {
- this.buildInfo.contextDependencies.add(context);
- }
- }
- // populate warnings
- for (const warning of m.warnings) {
- this.warnings.push(warning);
- }
- // populate errors
- for (const error of m.errors) {
- this.errors.push(error);
- }
- if (m.buildInfo.assets) {
- if (this.buildInfo.assets === undefined) {
- this.buildInfo.assets = Object.create(null);
- }
- Object.assign(this.buildInfo.assets, m.buildInfo.assets);
- }
- if (m.buildInfo.assetsInfo) {
- if (this.buildInfo.assetsInfo === undefined) {
- this.buildInfo.assetsInfo = new Map();
- }
- for (const [key, value] of m.buildInfo.assetsInfo) {
- this.buildInfo.assetsInfo.set(key, value);
- }
- }
- }
- }
- this._identifier = this._createIdentifier();
- }
- get modules() {
- return this._orderedConcatenationList
- .filter(info => info.type === "concatenated")
- .map(info => info.module);
- }
- identifier() {
- return this._identifier;
- }
- readableIdentifier(requestShortener) {
- return (
- this.rootModule.readableIdentifier(requestShortener) +
- ` + ${this._numberOfConcatenatedModules - 1} modules`
- );
- }
- libIdent(options) {
- return this.rootModule.libIdent(options);
- }
- nameForCondition() {
- return this.rootModule.nameForCondition();
- }
- build(options, compilation, resolver, fs, callback) {
- throw new Error("Cannot build this module. It should be already built.");
- }
- size() {
- // Guess size from embedded modules
- return this._orderedConcatenationList.reduce((sum, info) => {
- switch (info.type) {
- case "concatenated":
- return sum + info.module.size();
- case "external":
- return sum + 5;
- }
- return sum;
- }, 0);
- }
- /**
- * @param {Module} rootModule the root of the concatenation
- * @param {Set<Module>} modulesSet a set of modules which should be concatenated
- * @param {Compilation} compilation the compilation context
- * @returns {ConcatenationEntry[]} concatenation list
- */
- static createConcatenationList(rootModule, modulesSet, compilation) {
- const list = [];
- const set = new Set();
- /**
- * @param {Module} module a module
- * @returns {(function(): Module)[]} imported modules in order
- */
- const getConcatenatedImports = module => {
- /** @type {WeakMap<DependencyReference, Dependency>} */
- const map = new WeakMap();
- const references = module.dependencies
- .filter(dep => dep instanceof HarmonyImportDependency)
- .map(dep => {
- const ref = compilation.getDependencyReference(module, dep);
- if (ref) map.set(ref, dep);
- return ref;
- })
- .filter(ref => ref);
- DependencyReference.sort(references);
- // TODO webpack 5: remove this hack, see also DependencyReference
- return references.map(ref => {
- const dep = map.get(ref);
- return () => compilation.getDependencyReference(module, dep).module;
- });
- };
- const enterModule = getModule => {
- const module = getModule();
- if (!module) return;
- if (set.has(module)) return;
- set.add(module);
- if (modulesSet.has(module)) {
- const imports = getConcatenatedImports(module);
- imports.forEach(enterModule);
- list.push({
- type: "concatenated",
- module
- });
- } else {
- list.push({
- type: "external",
- get module() {
- // We need to use a getter here, because the module in the dependency
- // could be replaced by some other process (i. e. also replaced with a
- // concatenated module)
- return getModule();
- }
- });
- }
- };
- enterModule(() => rootModule);
- return list;
- }
- _createIdentifier() {
- let orderedConcatenationListIdentifiers = "";
- for (let i = 0; i < this._orderedConcatenationList.length; i++) {
- if (this._orderedConcatenationList[i].type === "concatenated") {
- orderedConcatenationListIdentifiers += this._orderedConcatenationList[
- i
- ].module.identifier();
- orderedConcatenationListIdentifiers += " ";
- }
- }
- const hash = createHash("md4");
- hash.update(orderedConcatenationListIdentifiers);
- return this.rootModule.identifier() + " " + hash.digest("hex");
- }
- source(dependencyTemplates, runtimeTemplate) {
- const requestShortener = runtimeTemplate.requestShortener;
- // Metainfo for each module
- const modulesWithInfo = this._orderedConcatenationList.map((info, idx) => {
- switch (info.type) {
- case "concatenated": {
- const exportMap = new Map();
- const reexportMap = new Map();
- for (const dep of info.module.dependencies) {
- if (dep instanceof HarmonyExportSpecifierDependency) {
- if (!exportMap.has(dep.name)) {
- exportMap.set(dep.name, dep.id);
- }
- } else if (dep instanceof HarmonyExportExpressionDependency) {
- if (!exportMap.has("default")) {
- exportMap.set("default", "__WEBPACK_MODULE_DEFAULT_EXPORT__");
- }
- } else if (
- dep instanceof HarmonyExportImportedSpecifierDependency
- ) {
- const exportName = dep.name;
- const importName = dep._id;
- const importedModule = dep._module;
- if (exportName && importName) {
- if (!reexportMap.has(exportName)) {
- reexportMap.set(exportName, {
- module: importedModule,
- exportName: importName,
- dependency: dep
- });
- }
- } else if (exportName) {
- if (!reexportMap.has(exportName)) {
- reexportMap.set(exportName, {
- module: importedModule,
- exportName: true,
- dependency: dep
- });
- }
- } else if (importedModule) {
- for (const name of importedModule.buildMeta.providedExports) {
- if (dep.activeExports.has(name) || name === "default") {
- continue;
- }
- if (!reexportMap.has(name)) {
- reexportMap.set(name, {
- module: importedModule,
- exportName: name,
- dependency: dep
- });
- }
- }
- }
- }
- }
- return {
- type: "concatenated",
- module: info.module,
- index: idx,
- ast: undefined,
- internalSource: undefined,
- source: undefined,
- globalScope: undefined,
- moduleScope: undefined,
- internalNames: new Map(),
- globalExports: new Set(),
- exportMap: exportMap,
- reexportMap: reexportMap,
- hasNamespaceObject: false,
- namespaceObjectSource: null
- };
- }
- case "external":
- return {
- type: "external",
- module: info.module,
- index: idx,
- name: undefined,
- interopNamespaceObjectUsed: false,
- interopNamespaceObjectName: undefined,
- interopDefaultAccessUsed: false,
- interopDefaultAccessName: undefined
- };
- default:
- throw new Error(`Unsupported concatenation entry type ${info.type}`);
- }
- });
- // Create mapping from module to info
- const moduleToInfoMap = new Map();
- for (const m of modulesWithInfo) {
- moduleToInfoMap.set(m.module, m);
- }
- // Configure template decorators for dependencies
- const innerDependencyTemplates = new Map(dependencyTemplates);
- innerDependencyTemplates.set(
- HarmonyImportSpecifierDependency,
- new HarmonyImportSpecifierDependencyConcatenatedTemplate(
- dependencyTemplates.get(HarmonyImportSpecifierDependency),
- moduleToInfoMap
- )
- );
- innerDependencyTemplates.set(
- HarmonyImportSideEffectDependency,
- new HarmonyImportSideEffectDependencyConcatenatedTemplate(
- dependencyTemplates.get(HarmonyImportSideEffectDependency),
- moduleToInfoMap
- )
- );
- innerDependencyTemplates.set(
- HarmonyExportSpecifierDependency,
- new NullTemplate()
- );
- innerDependencyTemplates.set(
- HarmonyExportExpressionDependency,
- new HarmonyExportExpressionDependencyConcatenatedTemplate(
- dependencyTemplates.get(HarmonyExportExpressionDependency),
- this.rootModule
- )
- );
- innerDependencyTemplates.set(
- HarmonyExportImportedSpecifierDependency,
- new NullTemplate()
- );
- innerDependencyTemplates.set(
- HarmonyCompatibilityDependency,
- new NullTemplate()
- );
- // Must use full identifier in our cache here to ensure that the source
- // is updated should our dependencies list change.
- // TODO webpack 5 refactor
- innerDependencyTemplates.set(
- "hash",
- innerDependencyTemplates.get("hash") + this.identifier()
- );
- // Generate source code and analyse scopes
- // Prepare a ReplaceSource for the final source
- for (const info of modulesWithInfo) {
- if (info.type === "concatenated") {
- const m = info.module;
- const source = m.source(innerDependencyTemplates, runtimeTemplate);
- const code = source.source();
- let ast;
- try {
- ast = Parser.parse(code, {
- sourceType: "module"
- });
- } catch (err) {
- if (
- err.loc &&
- typeof err.loc === "object" &&
- typeof err.loc.line === "number"
- ) {
- const lineNumber = err.loc.line;
- const lines = code.split("\n");
- err.message +=
- "\n| " +
- lines
- .slice(Math.max(0, lineNumber - 3), lineNumber + 2)
- .join("\n| ");
- }
- throw err;
- }
- const scopeManager = eslintScope.analyze(ast, {
- ecmaVersion: 6,
- sourceType: "module",
- optimistic: true,
- ignoreEval: true,
- impliedStrict: true
- });
- const globalScope = scopeManager.acquire(ast);
- const moduleScope = globalScope.childScopes[0];
- const resultSource = new ReplaceSource(source);
- info.ast = ast;
- info.internalSource = source;
- info.source = resultSource;
- info.globalScope = globalScope;
- info.moduleScope = moduleScope;
- }
- }
- // List of all used names to avoid conflicts
- const allUsedNames = new Set([
- "__WEBPACK_MODULE_DEFAULT_EXPORT__", // avoid using this internal name
- "abstract",
- "arguments",
- "async",
- "await",
- "boolean",
- "break",
- "byte",
- "case",
- "catch",
- "char",
- "class",
- "const",
- "continue",
- "debugger",
- "default",
- "delete",
- "do",
- "double",
- "else",
- "enum",
- "eval",
- "export",
- "extends",
- "false",
- "final",
- "finally",
- "float",
- "for",
- "function",
- "goto",
- "if",
- "implements",
- "import",
- "in",
- "instanceof",
- "int",
- "interface",
- "let",
- "long",
- "native",
- "new",
- "null",
- "package",
- "private",
- "protected",
- "public",
- "return",
- "short",
- "static",
- "super",
- "switch",
- "synchronized",
- "this",
- "throw",
- "throws",
- "transient",
- "true",
- "try",
- "typeof",
- "var",
- "void",
- "volatile",
- "while",
- "with",
- "yield",
- "module",
- "__dirname",
- "__filename",
- "exports",
- "Array",
- "Date",
- "eval",
- "function",
- "hasOwnProperty",
- "Infinity",
- "isFinite",
- "isNaN",
- "isPrototypeOf",
- "length",
- "Math",
- "NaN",
- "name",
- "Number",
- "Object",
- "prototype",
- "String",
- "toString",
- "undefined",
- "valueOf",
- "alert",
- "all",
- "anchor",
- "anchors",
- "area",
- "assign",
- "blur",
- "button",
- "checkbox",
- "clearInterval",
- "clearTimeout",
- "clientInformation",
- "close",
- "closed",
- "confirm",
- "constructor",
- "crypto",
- "decodeURI",
- "decodeURIComponent",
- "defaultStatus",
- "document",
- "element",
- "elements",
- "embed",
- "embeds",
- "encodeURI",
- "encodeURIComponent",
- "escape",
- "event",
- "fileUpload",
- "focus",
- "form",
- "forms",
- "frame",
- "innerHeight",
- "innerWidth",
- "layer",
- "layers",
- "link",
- "location",
- "mimeTypes",
- "navigate",
- "navigator",
- "frames",
- "frameRate",
- "hidden",
- "history",
- "image",
- "images",
- "offscreenBuffering",
- "open",
- "opener",
- "option",
- "outerHeight",
- "outerWidth",
- "packages",
- "pageXOffset",
- "pageYOffset",
- "parent",
- "parseFloat",
- "parseInt",
- "password",
- "pkcs11",
- "plugin",
- "prompt",
- "propertyIsEnum",
- "radio",
- "reset",
- "screenX",
- "screenY",
- "scroll",
- "secure",
- "select",
- "self",
- "setInterval",
- "setTimeout",
- "status",
- "submit",
- "taint",
- "text",
- "textarea",
- "top",
- "unescape",
- "untaint",
- "window",
- "onblur",
- "onclick",
- "onerror",
- "onfocus",
- "onkeydown",
- "onkeypress",
- "onkeyup",
- "onmouseover",
- "onload",
- "onmouseup",
- "onmousedown",
- "onsubmit"
- ]);
- // Set of already checked scopes
- const alreadyCheckedScopes = new Set();
- // get all global names
- for (const info of modulesWithInfo) {
- const superClassExpressions = [];
- // ignore symbols from moduleScope
- if (info.moduleScope) {
- alreadyCheckedScopes.add(info.moduleScope);
- // The super class expression in class scopes behaves weird
- // We store ranges of all super class expressions to make
- // renaming to work correctly
- for (const childScope of info.moduleScope.childScopes) {
- if (childScope.type !== "class") continue;
- if (!childScope.block.superClass) continue;
- superClassExpressions.push({
- range: childScope.block.superClass.range,
- variables: childScope.variables
- });
- }
- }
- // add global symbols
- if (info.globalScope) {
- for (const reference of info.globalScope.through) {
- const name = reference.identifier.name;
- if (
- /^__WEBPACK_MODULE_REFERENCE__\d+_([\da-f]+|ns)(_call)?(_strict)?__$/.test(
- name
- )
- ) {
- for (const expr of superClassExpressions) {
- if (
- expr.range[0] <= reference.identifier.range[0] &&
- expr.range[1] >= reference.identifier.range[1]
- ) {
- for (const variable of expr.variables) {
- allUsedNames.add(variable.name);
- }
- }
- }
- addScopeSymbols1(
- reference.from,
- allUsedNames,
- alreadyCheckedScopes
- );
- } else {
- allUsedNames.add(name);
- }
- }
- }
- // add exported globals
- if (info.type === "concatenated") {
- const variables = new Set();
- for (const variable of info.moduleScope.variables) {
- variables.add(variable.name);
- }
- for (const [, variable] of info.exportMap) {
- if (!variables.has(variable)) {
- info.globalExports.add(variable);
- }
- }
- }
- }
- // generate names for symbols
- for (const info of modulesWithInfo) {
- switch (info.type) {
- case "concatenated": {
- const namespaceObjectName = this.findNewName(
- "namespaceObject",
- allUsedNames,
- null,
- info.module.readableIdentifier(requestShortener)
- );
- allUsedNames.add(namespaceObjectName);
- info.internalNames.set(namespaceObjectName, namespaceObjectName);
- info.exportMap.set(true, namespaceObjectName);
- for (const variable of info.moduleScope.variables) {
- const name = variable.name;
- if (allUsedNames.has(name)) {
- const references = getAllReferences(variable);
- const symbolsInReferences = new Set();
- const alreadyCheckedInnerScopes = new Set();
- for (const ref of references) {
- addScopeSymbols2(
- ref.from,
- symbolsInReferences,
- alreadyCheckedInnerScopes,
- alreadyCheckedScopes
- );
- }
- const newName = this.findNewName(
- name,
- allUsedNames,
- symbolsInReferences,
- info.module.readableIdentifier(requestShortener)
- );
- allUsedNames.add(newName);
- info.internalNames.set(name, newName);
- const source = info.source;
- const allIdentifiers = new Set(
- references.map(r => r.identifier).concat(variable.identifiers)
- );
- for (const identifier of allIdentifiers) {
- const r = identifier.range;
- const path = getPathInAst(info.ast, identifier);
- if (
- path &&
- path.length > 1 &&
- path[1].type === "Property" &&
- path[1].shorthand
- ) {
- source.insert(r[1], `: ${newName}`);
- } else {
- source.replace(r[0], r[1] - 1, newName);
- }
- }
- } else {
- allUsedNames.add(name);
- info.internalNames.set(name, name);
- }
- }
- break;
- }
- case "external": {
- const externalName = this.findNewName(
- "",
- allUsedNames,
- null,
- info.module.readableIdentifier(requestShortener)
- );
- allUsedNames.add(externalName);
- info.name = externalName;
- if (
- info.module.buildMeta.exportsType === "named" ||
- !info.module.buildMeta.exportsType
- ) {
- const externalNameInterop = this.findNewName(
- "namespaceObject",
- allUsedNames,
- null,
- info.module.readableIdentifier(requestShortener)
- );
- allUsedNames.add(externalNameInterop);
- info.interopNamespaceObjectName = externalNameInterop;
- }
- if (!info.module.buildMeta.exportsType) {
- const externalNameInterop = this.findNewName(
- "default",
- allUsedNames,
- null,
- info.module.readableIdentifier(requestShortener)
- );
- allUsedNames.add(externalNameInterop);
- info.interopDefaultAccessName = externalNameInterop;
- }
- break;
- }
- }
- }
- // Find and replace referenced to modules
- for (const info of modulesWithInfo) {
- if (info.type === "concatenated") {
- for (const reference of info.globalScope.through) {
- const name = reference.identifier.name;
- const match = /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_strict)?__$/.exec(
- name
- );
- if (match) {
- const referencedModule = modulesWithInfo[+match[1]];
- let exportName;
- if (match[2] === "ns") {
- exportName = true;
- } else {
- const exportData = match[2];
- exportName = Buffer.from(exportData, "hex").toString("utf-8");
- }
- const asCall = !!match[3];
- const strictHarmonyModule = !!match[4];
- const finalName = getFinalName(
- referencedModule,
- exportName,
- moduleToInfoMap,
- requestShortener,
- asCall,
- strictHarmonyModule
- );
- const r = reference.identifier.range;
- const source = info.source;
- source.replace(r[0], r[1] - 1, finalName);
- }
- }
- }
- }
- // Map with all root exposed used exports
- /** @type {Map<string, function(RequestShortener): string>} */
- const exportsMap = new Map();
- // Set with all root exposed unused exports
- /** @type {Set<string>} */
- const unusedExports = new Set();
- for (const dep of this.rootModule.dependencies) {
- if (dep instanceof HarmonyExportSpecifierDependency) {
- const used = this.rootModule.isUsed(dep.name);
- if (used) {
- const info = moduleToInfoMap.get(this.rootModule);
- if (!exportsMap.has(used)) {
- exportsMap.set(
- used,
- () => `/* binding */ ${info.internalNames.get(dep.id)}`
- );
- }
- } else {
- unusedExports.add(dep.name || "namespace");
- }
- } else if (dep instanceof HarmonyExportImportedSpecifierDependency) {
- const exportDefs = getHarmonyExportImportedSpecifierDependencyExports(
- dep
- );
- for (const def of exportDefs) {
- const info = moduleToInfoMap.get(def.module);
- const used = dep.originModule.isUsed(def.name);
- if (used) {
- if (!exportsMap.has(used)) {
- exportsMap.set(used, requestShortener => {
- const finalName = getFinalName(
- info,
- def.id,
- moduleToInfoMap,
- requestShortener,
- false,
- this.rootModule.buildMeta.strictHarmonyModule
- );
- return `/* reexport */ ${finalName}`;
- });
- }
- } else {
- unusedExports.add(def.name);
- }
- }
- }
- }
- const result = new ConcatSource();
- // add harmony compatibility flag (must be first because of possible circular dependencies)
- const usedExports = this.rootModule.usedExports;
- if (usedExports === true || usedExports === null) {
- result.add(`// ESM COMPAT FLAG\n`);
- result.add(
- runtimeTemplate.defineEsModuleFlagStatement({
- exportsArgument: this.exportsArgument
- })
- );
- }
- // define exports
- if (exportsMap.size > 0) {
- result.add(`\n// EXPORTS\n`);
- for (const [key, value] of exportsMap) {
- result.add(
- `__webpack_require__.d(${this.exportsArgument}, ${JSON.stringify(
- key
- )}, function() { return ${value(requestShortener)}; });\n`
- );
- }
- }
- // list unused exports
- if (unusedExports.size > 0) {
- result.add(
- `\n// UNUSED EXPORTS: ${joinIterableWithComma(unusedExports)}\n`
- );
- }
- // define required namespace objects (must be before evaluation modules)
- for (const info of modulesWithInfo) {
- if (info.namespaceObjectSource) {
- result.add(
- `\n// NAMESPACE OBJECT: ${info.module.readableIdentifier(
- requestShortener
- )}\n`
- );
- result.add(info.namespaceObjectSource);
- }
- }
- // evaluate modules in order
- for (const info of modulesWithInfo) {
- switch (info.type) {
- case "concatenated":
- result.add(
- `\n// CONCATENATED MODULE: ${info.module.readableIdentifier(
- requestShortener
- )}\n`
- );
- result.add(info.source);
- break;
- case "external":
- result.add(
- `\n// EXTERNAL MODULE: ${info.module.readableIdentifier(
- requestShortener
- )}\n`
- );
- result.add(
- `var ${info.name} = __webpack_require__(${JSON.stringify(
- info.module.id
- )});\n`
- );
- if (info.interopNamespaceObjectUsed) {
- if (info.module.buildMeta.exportsType === "named") {
- result.add(
- `var ${info.interopNamespaceObjectName} = /*#__PURE__*/__webpack_require__.t(${info.name}, 2);\n`
- );
- } else if (!info.module.buildMeta.exportsType) {
- result.add(
- `var ${info.interopNamespaceObjectName} = /*#__PURE__*/__webpack_require__.t(${info.name});\n`
- );
- }
- }
- if (info.interopDefaultAccessUsed) {
- result.add(
- `var ${info.interopDefaultAccessName} = /*#__PURE__*/__webpack_require__.n(${info.name});\n`
- );
- }
- break;
- default:
- throw new Error(`Unsupported concatenation entry type ${info.type}`);
- }
- }
- return result;
- }
- findNewName(oldName, usedNamed1, usedNamed2, extraInfo) {
- let name = oldName;
- if (name === "__WEBPACK_MODULE_DEFAULT_EXPORT__") name = "";
- // Remove uncool stuff
- extraInfo = extraInfo.replace(
- /\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules/g,
- ""
- );
- const splittedInfo = extraInfo.split("/");
- while (splittedInfo.length) {
- name = splittedInfo.pop() + (name ? "_" + name : "");
- const nameIdent = Template.toIdentifier(name);
- if (
- !usedNamed1.has(nameIdent) &&
- (!usedNamed2 || !usedNamed2.has(nameIdent))
- )
- return nameIdent;
- }
- let i = 0;
- let nameWithNumber = Template.toIdentifier(`${name}_${i}`);
- while (
- usedNamed1.has(nameWithNumber) ||
- (usedNamed2 && usedNamed2.has(nameWithNumber))
- ) {
- i++;
- nameWithNumber = Template.toIdentifier(`${name}_${i}`);
- }
- return nameWithNumber;
- }
- /**
- * @param {Hash} hash the hash used to track dependencies
- * @returns {void}
- */
- updateHash(hash) {
- for (const info of this._orderedConcatenationList) {
- switch (info.type) {
- case "concatenated":
- info.module.updateHash(hash);
- break;
- case "external":
- hash.update(`${info.module.id}`);
- break;
- }
- }
- super.updateHash(hash);
- }
- }
- class HarmonyImportSpecifierDependencyConcatenatedTemplate {
- constructor(originalTemplate, modulesMap) {
- this.originalTemplate = originalTemplate;
- this.modulesMap = modulesMap;
- }
- getHarmonyInitOrder(dep) {
- const module = dep._module;
- const info = this.modulesMap.get(module);
- if (!info) {
- return this.originalTemplate.getHarmonyInitOrder(dep);
- }
- return NaN;
- }
- harmonyInit(dep, source, runtimeTemplate, dependencyTemplates) {
- const module = dep._module;
- const info = this.modulesMap.get(module);
- if (!info) {
- this.originalTemplate.harmonyInit(
- dep,
- source,
- runtimeTemplate,
- dependencyTemplates
- );
- return;
- }
- }
- apply(dep, source, runtime, dependencyTemplates) {
- const module = dep._module;
- const info = this.modulesMap.get(module);
- if (!info) {
- this.originalTemplate.apply(dep, source, runtime, dependencyTemplates);
- return;
- }
- let content;
- const callFlag = dep.call ? "_call" : "";
- const strictFlag = dep.originModule.buildMeta.strictHarmonyModule
- ? "_strict"
- : "";
- if (dep._id === null) {
- content = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns${strictFlag}__`;
- } else if (dep.namespaceObjectAsContext) {
- content = `__WEBPACK_MODULE_REFERENCE__${
- info.index
- }_ns${strictFlag}__[${JSON.stringify(dep._id)}]`;
- } else {
- const exportData = Buffer.from(dep._id, "utf-8").toString("hex");
- content = `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportData}${callFlag}${strictFlag}__`;
- }
- if (dep.shorthand) {
- content = dep.name + ": " + content;
- }
- source.replace(dep.range[0], dep.range[1] - 1, content);
- }
- }
- class HarmonyImportSideEffectDependencyConcatenatedTemplate {
- constructor(originalTemplate, modulesMap) {
- this.originalTemplate = originalTemplate;
- this.modulesMap = modulesMap;
- }
- getHarmonyInitOrder(dep) {
- const module = dep._module;
- const info = this.modulesMap.get(module);
- if (!info) {
- return this.originalTemplate.getHarmonyInitOrder(dep);
- }
- return NaN;
- }
- harmonyInit(dep, source, runtime, dependencyTemplates) {
- const module = dep._module;
- const info = this.modulesMap.get(module);
- if (!info) {
- this.originalTemplate.harmonyInit(
- dep,
- source,
- runtime,
- dependencyTemplates
- );
- return;
- }
- }
- apply(dep, source, runtime, dependencyTemplates) {
- const module = dep._module;
- const info = this.modulesMap.get(module);
- if (!info) {
- this.originalTemplate.apply(dep, source, runtime, dependencyTemplates);
- return;
- }
- }
- }
- class HarmonyExportExpressionDependencyConcatenatedTemplate {
- constructor(originalTemplate, rootModule) {
- this.originalTemplate = originalTemplate;
- this.rootModule = rootModule;
- }
- apply(dep, source, runtime, dependencyTemplates) {
- let content =
- "/* harmony default export */ var __WEBPACK_MODULE_DEFAULT_EXPORT__ = ";
- if (dep.originModule === this.rootModule) {
- const used = dep.originModule.isUsed("default");
- const exportsName = dep.originModule.exportsArgument;
- if (used) content += `${exportsName}[${JSON.stringify(used)}] = `;
- }
- if (dep.range) {
- source.replace(
- dep.rangeStatement[0],
- dep.range[0] - 1,
- content + "(" + dep.prefix
- );
- source.replace(dep.range[1], dep.rangeStatement[1] - 1, ");");
- return;
- }
- source.replace(
- dep.rangeStatement[0],
- dep.rangeStatement[1] - 1,
- content + dep.prefix
- );
- }
- }
- class NullTemplate {
- apply() {}
- }
- module.exports = ConcatenatedModule;
|