CssExportsGenerator.js
4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Sergey Melyukov @smelukov
*/
"use strict";
const { ReplaceSource, RawSource, ConcatSource } = require("webpack-sources");
const { UsageState } = require("../ExportsInfo");
const Generator = require("../Generator");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
/** @typedef {import("../NormalModule")} NormalModule */
/** @typedef {import("../util/Hash")} Hash */
const TYPES = new Set(["javascript"]);
class CssExportsGenerator extends Generator {
constructor() {
super();
}
// TODO add getConcatenationBailoutReason to allow concatenation
// but how to make it have a module id
/**
* @param {NormalModule} module module for which the code should be generated
* @param {GenerateContext} generateContext context for generate
* @returns {Source} generated code
*/
generate(module, generateContext) {
const source = new ReplaceSource(new RawSource(""));
const initFragments = [];
const cssExports = new Map();
generateContext.runtimeRequirements.add(RuntimeGlobals.module);
const runtimeRequirements = new Set();
const templateContext = {
runtimeTemplate: generateContext.runtimeTemplate,
dependencyTemplates: generateContext.dependencyTemplates,
moduleGraph: generateContext.moduleGraph,
chunkGraph: generateContext.chunkGraph,
module,
runtime: generateContext.runtime,
runtimeRequirements: runtimeRequirements,
concatenationScope: generateContext.concatenationScope,
codeGenerationResults: generateContext.codeGenerationResults,
initFragments,
cssExports
};
const handleDependency = dependency => {
const constructor = /** @type {new (...args: any[]) => Dependency} */ (
dependency.constructor
);
const template = generateContext.dependencyTemplates.get(constructor);
if (!template) {
throw new Error(
"No template for dependency: " + dependency.constructor.name
);
}
template.apply(dependency, source, templateContext);
};
module.dependencies.forEach(handleDependency);
if (generateContext.concatenationScope) {
const source = new ConcatSource();
const usedIdentifiers = new Set();
for (const [k, v] of cssExports) {
let identifier = Template.toIdentifier(k);
let i = 0;
while (usedIdentifiers.has(identifier)) {
identifier = Template.toIdentifier(k + i);
}
usedIdentifiers.add(identifier);
generateContext.concatenationScope.registerExport(k, identifier);
source.add(
`${
generateContext.runtimeTemplate.supportsConst ? "const" : "var"
} ${identifier} = ${JSON.stringify(v)};\n`
);
}
return source;
} else {
const otherUsed =
generateContext.moduleGraph
.getExportsInfo(module)
.otherExportsInfo.getUsed(generateContext.runtime) !==
UsageState.Unused;
if (otherUsed) {
generateContext.runtimeRequirements.add(
RuntimeGlobals.makeNamespaceObject
);
}
return new RawSource(
`${otherUsed ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${
module.moduleArgument
}.exports = {\n${Array.from(
cssExports,
([k, v]) => `\t${JSON.stringify(k)}: ${JSON.stringify(v)}`
).join(",\n")}\n}${otherUsed ? ")" : ""};`
);
}
}
/**
* @param {NormalModule} module fresh module
* @returns {Set<string>} available types (do not mutate)
*/
getTypes(module) {
return TYPES;
}
/**
* @param {NormalModule} module the module
* @param {string=} type source type
* @returns {number} estimate size of the module
*/
getSize(module, type) {
return 42;
}
/**
* @param {Hash} hash hash that will be modified
* @param {UpdateHashContext} updateHashContext context for updating hash
*/
updateHash(hash, { module }) {}
}
module.exports = CssExportsGenerator;