UNPKG

5.47 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const ConcatenationScope = require("../ConcatenationScope");
9const RuntimeGlobals = require("../RuntimeGlobals");
10const makeSerializable = require("../util/makeSerializable");
11const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
12const NullDependency = require("./NullDependency");
13
14/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
15/** @typedef {import("../Dependency")} Dependency */
16/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
17/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
18/** @typedef {import("../ModuleGraph")} ModuleGraph */
19/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
20
21class HarmonyExportExpressionDependency extends NullDependency {
22 constructor(range, rangeStatement, prefix, declarationId) {
23 super();
24 this.range = range;
25 this.rangeStatement = rangeStatement;
26 this.prefix = prefix;
27 this.declarationId = declarationId;
28 }
29
30 get type() {
31 return "harmony export expression";
32 }
33
34 /**
35 * Returns the exported names
36 * @param {ModuleGraph} moduleGraph module graph
37 * @returns {ExportsSpec | undefined} export names
38 */
39 getExports(moduleGraph) {
40 return {
41 exports: ["default"],
42 priority: 1,
43 terminalBinding: true,
44 dependencies: undefined
45 };
46 }
47
48 /**
49 * @param {ModuleGraph} moduleGraph the module graph
50 * @returns {ConnectionState} how this dependency connects the module to referencing modules
51 */
52 getModuleEvaluationSideEffectsState(moduleGraph) {
53 // The expression/declaration is already covered by SideEffectsFlagPlugin
54 return false;
55 }
56
57 serialize(context) {
58 const { write } = context;
59 write(this.range);
60 write(this.rangeStatement);
61 write(this.prefix);
62 write(this.declarationId);
63 super.serialize(context);
64 }
65
66 deserialize(context) {
67 const { read } = context;
68 this.range = read();
69 this.rangeStatement = read();
70 this.prefix = read();
71 this.declarationId = read();
72 super.deserialize(context);
73 }
74}
75
76makeSerializable(
77 HarmonyExportExpressionDependency,
78 "webpack/lib/dependencies/HarmonyExportExpressionDependency"
79);
80
81HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTemplate extends (
82 NullDependency.Template
83) {
84 /**
85 * @param {Dependency} dependency the dependency for which the template should be applied
86 * @param {ReplaceSource} source the current replace source which can be modified
87 * @param {DependencyTemplateContext} templateContext the context object
88 * @returns {void}
89 */
90 apply(
91 dependency,
92 source,
93 {
94 module,
95 moduleGraph,
96 runtimeTemplate,
97 runtimeRequirements,
98 initFragments,
99 runtime,
100 concatenationScope
101 }
102 ) {
103 const dep = /** @type {HarmonyExportExpressionDependency} */ (dependency);
104 const { declarationId } = dep;
105 const exportsName = module.exportsArgument;
106 if (declarationId) {
107 let name;
108 if (typeof declarationId === "string") {
109 name = declarationId;
110 } else {
111 name = ConcatenationScope.DEFAULT_EXPORT;
112 source.replace(
113 declarationId.range[0],
114 declarationId.range[1] - 1,
115 `${declarationId.prefix}${name}${declarationId.suffix}`
116 );
117 }
118
119 if (concatenationScope) {
120 concatenationScope.registerExport("default", name);
121 } else {
122 const used = moduleGraph
123 .getExportsInfo(module)
124 .getUsedName("default", runtime);
125 if (used) {
126 const map = new Map();
127 map.set(used, `/* export default binding */ ${name}`);
128 initFragments.push(new HarmonyExportInitFragment(exportsName, map));
129 }
130 }
131
132 source.replace(
133 dep.rangeStatement[0],
134 dep.range[0] - 1,
135 `/* harmony default export */ ${dep.prefix}`
136 );
137 } else {
138 let content;
139 const name = ConcatenationScope.DEFAULT_EXPORT;
140 if (runtimeTemplate.supportsConst()) {
141 content = `/* harmony default export */ const ${name} = `;
142 if (concatenationScope) {
143 concatenationScope.registerExport("default", name);
144 } else {
145 const used = moduleGraph
146 .getExportsInfo(module)
147 .getUsedName("default", runtime);
148 if (used) {
149 runtimeRequirements.add(RuntimeGlobals.exports);
150 const map = new Map();
151 map.set(used, name);
152 initFragments.push(new HarmonyExportInitFragment(exportsName, map));
153 } else {
154 content = `/* unused harmony default export */ var ${name} = `;
155 }
156 }
157 } else if (concatenationScope) {
158 content = `/* harmony default export */ var ${name} = `;
159 concatenationScope.registerExport("default", name);
160 } else {
161 const used = moduleGraph
162 .getExportsInfo(module)
163 .getUsedName("default", runtime);
164 if (used) {
165 runtimeRequirements.add(RuntimeGlobals.exports);
166 // This is a little bit incorrect as TDZ is not correct, but we can't use const.
167 content = `/* harmony default export */ ${exportsName}[${JSON.stringify(
168 used
169 )}] = `;
170 } else {
171 content = `/* unused harmony default export */ var ${name} = `;
172 }
173 }
174
175 if (dep.range) {
176 source.replace(
177 dep.rangeStatement[0],
178 dep.range[0] - 1,
179 content + "(" + dep.prefix
180 );
181 source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");");
182 return;
183 }
184
185 source.replace(dep.rangeStatement[0], dep.rangeStatement[1] - 1, content);
186 }
187 }
188};
189
190module.exports = HarmonyExportExpressionDependency;