webpack 5.101.0 → 5.101.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/ChunkGraph.js CHANGED
@@ -1238,6 +1238,60 @@ class ChunkGraph {
1238
1238
  return set;
1239
1239
  }
1240
1240
 
1241
+ /**
1242
+ * @param {Chunk} chunk the chunk
1243
+ * @returns {Iterable<Chunk>} iterable of chunks and include chunks from children entrypoints
1244
+ */
1245
+ getRuntimeChunkDependentChunksIterable(chunk) {
1246
+ /** @type {Set<Chunk>} */
1247
+ const set = new Set();
1248
+
1249
+ /** @type {Set<Entrypoint>} */
1250
+ const entrypoints = new Set();
1251
+
1252
+ for (const chunkGroup of chunk.groupsIterable) {
1253
+ if (chunkGroup instanceof Entrypoint) {
1254
+ const queue = [chunkGroup];
1255
+ while (queue.length > 0) {
1256
+ const current = queue.shift();
1257
+ if (current) {
1258
+ entrypoints.add(current);
1259
+
1260
+ let hasChildrenEntrypoint = false;
1261
+ for (const child of current.childrenIterable) {
1262
+ if (child instanceof Entrypoint && child.dependOn(current)) {
1263
+ hasChildrenEntrypoint = true;
1264
+ queue.push(/** @type {Entrypoint} */ (child));
1265
+ }
1266
+ }
1267
+ // entryChunkB: hasChildrenEntrypoint = true
1268
+ // entryChunkA: dependOn = entryChunkB
1269
+ if (hasChildrenEntrypoint) {
1270
+ const entrypointChunk = current.getEntrypointChunk();
1271
+ if (entrypointChunk !== chunk && !entrypointChunk.hasRuntime()) {
1272
+ // add entryChunkB to set
1273
+ set.add(entrypointChunk);
1274
+ }
1275
+ }
1276
+ }
1277
+ }
1278
+ }
1279
+ }
1280
+
1281
+ for (const entrypoint of entrypoints) {
1282
+ const entrypointChunk = entrypoint.getEntrypointChunk();
1283
+ const cgc = this._getChunkGraphChunk(entrypointChunk);
1284
+ for (const chunkGroup of cgc.entryModules.values()) {
1285
+ for (const c of chunkGroup.chunks) {
1286
+ if (c !== chunk && c !== entrypointChunk && !c.hasRuntime()) {
1287
+ set.add(c);
1288
+ }
1289
+ }
1290
+ }
1291
+ }
1292
+ return set;
1293
+ }
1294
+
1241
1295
  /**
1242
1296
  * @param {Chunk} chunk the chunk
1243
1297
  * @returns {boolean} true, when it has dependent chunks
@@ -32,7 +32,8 @@ const ErrorHelpers = require("./ErrorHelpers");
32
32
  const FileSystemInfo = require("./FileSystemInfo");
33
33
  const {
34
34
  connectChunkGroupAndChunk,
35
- connectChunkGroupParentAndChild
35
+ connectChunkGroupParentAndChild,
36
+ connectEntrypointAndDependOn
36
37
  } = require("./GraphHelpers");
37
38
  const {
38
39
  makeWebpackError,
@@ -526,6 +527,21 @@ class Compilation {
526
527
 
527
528
  /** @type {ProcessedAssets | undefined} */
528
529
  const processedAssets = additionalAssetsFn ? new WeakSet() : undefined;
530
+ /**
531
+ * @param {CompilationAssets} assets to be processed by additionalAssetsFn
532
+ * @returns {CompilationAssets} available assets
533
+ */
534
+ const getAvailableAssets = (assets) => {
535
+ /** @type {CompilationAssets} */
536
+ const availableAssets = {};
537
+ for (const file of Object.keys(assets)) {
538
+ // https://github.com/webpack-contrib/compression-webpack-plugin/issues/390
539
+ if (this.assets[file]) {
540
+ availableAssets[file] = assets[file];
541
+ }
542
+ }
543
+ return availableAssets;
544
+ };
529
545
  switch (type) {
530
546
  case "sync":
531
547
  if (additionalAssetsFn) {
@@ -534,7 +550,7 @@ class Compilation {
534
550
  /** @type {ProcessedAssets} */
535
551
  (processedAssets).has(this.assets)
536
552
  ) {
537
- additionalAssetsFn(assets);
553
+ additionalAssetsFn(getAvailableAssets(assets));
538
554
  }
539
555
  });
540
556
  }
@@ -575,7 +591,10 @@ class Compilation {
575
591
  /** @type {ProcessedAssets} */
576
592
  (processedAssets).has(this.assets)
577
593
  ) {
578
- return additionalAssetsFn(assets, callback);
594
+ return additionalAssetsFn(
595
+ getAvailableAssets(assets),
596
+ callback
597
+ );
579
598
  }
580
599
  callback();
581
600
  }
@@ -620,7 +639,7 @@ class Compilation {
620
639
  /** @type {ProcessedAssets} */
621
640
  (processedAssets).has(this.assets)
622
641
  ) {
623
- return additionalAssetsFn(assets);
642
+ return additionalAssetsFn(getAvailableAssets(assets));
624
643
  }
625
644
  return Promise.resolve();
626
645
  });
@@ -3189,7 +3208,6 @@ Remove the 'runtime' option from the entrypoint.`);
3189
3208
  const referencedChunks = entry
3190
3209
  .getEntrypointChunk()
3191
3210
  .getAllReferencedChunks();
3192
- const dependOnEntries = [];
3193
3211
  for (const dep of dependOn) {
3194
3212
  const dependency = this.entrypoints.get(dep);
3195
3213
  if (!dependency) {
@@ -3207,9 +3225,7 @@ Remove the 'runtime' option from the entrypoint.`);
3207
3225
  entry.setRuntimeChunk(entryChunk);
3208
3226
  continue outer;
3209
3227
  }
3210
- dependOnEntries.push(dependency);
3211
- }
3212
- for (const dependency of dependOnEntries) {
3228
+ connectEntrypointAndDependOn(entry, dependency);
3213
3229
  connectChunkGroupParentAndChild(dependency, entry);
3214
3230
  }
3215
3231
  } else if (runtime) {
@@ -3242,6 +3258,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3242
3258
  entry.setRuntimeChunk(chunk);
3243
3259
  }
3244
3260
  }
3261
+
3245
3262
  buildChunkGraph(this, chunkGraphInit);
3246
3263
  this.hooks.afterChunks.call(this.chunks);
3247
3264
  this.logger.timeEnd("create chunks");
package/lib/Dependency.js CHANGED
@@ -5,7 +5,6 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const RawModule = require("./RawModule");
9
8
  const memoize = require("./util/memoize");
10
9
 
11
10
  /** @typedef {import("webpack-sources").Source} Source */
@@ -86,6 +85,8 @@ const memoize = require("./util/memoize");
86
85
  const TRANSITIVE = Symbol("transitive");
87
86
 
88
87
  const getIgnoredModule = memoize(() => {
88
+ const RawModule = require("./RawModule");
89
+
89
90
  const module = new RawModule("/* (ignored) */", "ignored", "(ignored)");
90
91
  module.factoryMeta = { sideEffectFree: true };
91
92
  return module;
package/lib/Entrypoint.js CHANGED
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const ChunkGroup = require("./ChunkGroup");
9
+ const SortableSet = require("./util/SortableSet");
9
10
 
10
11
  /** @typedef {import("../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescription */
11
12
  /** @typedef {import("./Chunk")} Chunk */
@@ -38,6 +39,8 @@ class Entrypoint extends ChunkGroup {
38
39
  this._entrypointChunk = undefined;
39
40
  /** @type {boolean} */
40
41
  this._initial = initial;
42
+ /** @type {SortableSet<Entrypoint>} */
43
+ this._dependOn = new SortableSet();
41
44
  }
42
45
 
43
46
  /**
@@ -96,6 +99,22 @@ class Entrypoint extends ChunkGroup {
96
99
  if (this._entrypointChunk === oldChunk) this._entrypointChunk = newChunk;
97
100
  return super.replaceChunk(oldChunk, newChunk);
98
101
  }
102
+
103
+ /**
104
+ * @param {Entrypoint} entrypoint the entrypoint
105
+ * @returns {void}
106
+ */
107
+ addDependOn(entrypoint) {
108
+ this._dependOn.add(entrypoint);
109
+ }
110
+
111
+ /**
112
+ * @param {Entrypoint} entrypoint the entrypoint
113
+ * @returns {boolean} true if the entrypoint is in the dependOn set
114
+ */
115
+ dependOn(entrypoint) {
116
+ return this._dependOn.has(entrypoint);
117
+ }
99
118
  }
100
119
 
101
120
  module.exports = Entrypoint;
@@ -10,6 +10,7 @@
10
10
  /** @typedef {import("./ChunkGroup")} ChunkGroup */
11
11
  /** @typedef {import("./DependenciesBlock")} DependenciesBlock */
12
12
  /** @typedef {import("./Module")} Module */
13
+ /** @typedef {import(".").Entrypoint} Entrypoint */
13
14
 
14
15
  /**
15
16
  * @param {ChunkGroup} chunkGroup the ChunkGroup to connect
@@ -33,6 +34,16 @@ const connectChunkGroupParentAndChild = (parent, child) => {
33
34
  }
34
35
  };
35
36
 
37
+ /**
38
+ * @param {Entrypoint} entrypoint the entrypoint
39
+ * @param {Entrypoint} dependOnEntrypoint the dependOnEntrypoint
40
+ * @returns {void}
41
+ */
42
+ const connectEntrypointAndDependOn = (entrypoint, dependOnEntrypoint) => {
43
+ entrypoint.addDependOn(dependOnEntrypoint);
44
+ };
45
+
36
46
  module.exports.connectChunkGroupAndChunk = connectChunkGroupAndChunk;
37
47
  module.exports.connectChunkGroupParentAndChild =
38
48
  connectChunkGroupParentAndChild;
49
+ module.exports.connectEntrypointAndDependOn = connectEntrypointAndDependOn;
@@ -54,8 +54,7 @@ class JavascriptMetaInfoPlugin {
54
54
  topLevelDeclarations = buildInfo.topLevelDeclarations = new Set();
55
55
  }
56
56
  for (const name of parser.scope.definitions.asSet()) {
57
- const freeInfo = parser.getFreeInfoFromVariable(name);
58
- if (freeInfo === undefined) {
57
+ if (parser.isVariableDefined(name)) {
59
58
  topLevelDeclarations.add(name);
60
59
  }
61
60
  }
package/lib/Module.js CHANGED
@@ -115,9 +115,10 @@ const makeSerializable = require("./util/makeSerializable");
115
115
  * @property {boolean=} strictHarmonyModule
116
116
  * @property {boolean=} async
117
117
  * @property {boolean=} sideEffectFree
118
- * @property {Record<string, string>=} exportsFinalName
119
118
  * @property {boolean=} isCSSModule
120
119
  * @property {Record<string, string>=} jsIncompatibleExports
120
+ * @property {Record<string, string>=} exportsFinalName
121
+ * @property {string=} factoryExportsBinding
121
122
  */
122
123
 
123
124
  /**
@@ -8,10 +8,10 @@
8
8
  const util = require("util");
9
9
  const ExportsInfo = require("./ExportsInfo");
10
10
  const ModuleGraphConnection = require("./ModuleGraphConnection");
11
+ const HarmonyImportDependency = require("./dependencies/HarmonyImportDependency");
11
12
  const SortableSet = require("./util/SortableSet");
12
13
  const WeakTupleMap = require("./util/WeakTupleMap");
13
14
  const { sortWithSourceOrder } = require("./util/comparators");
14
- const memoize = require("./util/memoize");
15
15
 
16
16
  /** @typedef {import("./Compilation").ModuleMemCaches} ModuleMemCaches */
17
17
  /** @typedef {import("./DependenciesBlock")} DependenciesBlock */
@@ -25,10 +25,6 @@ const memoize = require("./util/memoize");
25
25
  /** @typedef {import("./dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
26
26
  /** @typedef {import("./util/comparators").DependencySourceOrder} DependencySourceOrder */
27
27
 
28
- const getCommonJsSelfReferenceDependency = memoize(() =>
29
- require("./dependencies/CommonJsSelfReferenceDependency")
30
- );
31
-
32
28
  /**
33
29
  * @callback OptimizationBailoutFunction
34
30
  * @param {RequestShortener} requestShortener
@@ -38,66 +34,51 @@ const getCommonJsSelfReferenceDependency = memoize(() =>
38
34
  const EMPTY_SET = new Set();
39
35
 
40
36
  /**
37
+ * @template {Module | null | undefined} T
41
38
  * @param {SortableSet<ModuleGraphConnection>} set input
42
- * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} mapped by origin module
39
+ * @param {(connection: ModuleGraphConnection) => T} getKey function to extract key from connection
40
+ * @returns {readonly Map<T, readonly ModuleGraphConnection[]>} mapped by key
43
41
  */
44
- const getConnectionsByOriginModule = (set) => {
42
+ const getConnectionsByKey = (set, getKey) => {
45
43
  const map = new Map();
46
- /** @type {Module | 0} */
47
- let lastModule = 0;
44
+ /** @type {T | 0} */
45
+ let lastKey = 0;
48
46
  /** @type {ModuleGraphConnection[] | undefined} */
49
47
  let lastList;
50
48
  for (const connection of set) {
51
- const { originModule } = connection;
52
- if (lastModule === originModule) {
49
+ const key = getKey(connection);
50
+ if (lastKey === key) {
53
51
  /** @type {ModuleGraphConnection[]} */
54
52
  (lastList).push(connection);
55
53
  } else {
56
- lastModule = /** @type {Module} */ (originModule);
57
- const list = map.get(originModule);
54
+ lastKey = key;
55
+ const list = map.get(key);
58
56
  if (list !== undefined) {
59
57
  lastList = list;
60
58
  list.push(connection);
61
59
  } else {
62
60
  const list = [connection];
63
61
  lastList = list;
64
- map.set(originModule, list);
62
+ map.set(key, list);
65
63
  }
66
64
  }
67
65
  }
68
66
  return map;
69
67
  };
70
68
 
69
+ /**
70
+ * @param {SortableSet<ModuleGraphConnection>} set input
71
+ * @returns {readonly Map<Module | undefined | null, readonly ModuleGraphConnection[]>} mapped by origin module
72
+ */
73
+ const getConnectionsByOriginModule = (set) =>
74
+ getConnectionsByKey(set, (connection) => connection.originModule);
75
+
71
76
  /**
72
77
  * @param {SortableSet<ModuleGraphConnection>} set input
73
78
  * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} mapped by module
74
79
  */
75
- const getConnectionsByModule = (set) => {
76
- const map = new Map();
77
- /** @type {Module | 0} */
78
- let lastModule = 0;
79
- /** @type {ModuleGraphConnection[] | undefined} */
80
- let lastList;
81
- for (const connection of set) {
82
- const { module } = connection;
83
- if (lastModule === module) {
84
- /** @type {ModuleGraphConnection[]} */
85
- (lastList).push(connection);
86
- } else {
87
- lastModule = module;
88
- const list = map.get(module);
89
- if (list !== undefined) {
90
- lastList = list;
91
- list.push(connection);
92
- } else {
93
- const list = [connection];
94
- lastList = list;
95
- map.set(module, list);
96
- }
97
- }
98
- }
99
- return map;
100
- };
80
+ const getConnectionsByModule = (set) =>
81
+ getConnectionsByKey(set, (connection) => connection.module);
101
82
 
102
83
  /** @typedef {SortableSet<ModuleGraphConnection>} IncomingConnections */
103
84
  /** @typedef {SortableSet<ModuleGraphConnection>} OutgoingConnections */
@@ -845,7 +826,7 @@ class ModuleGraph {
845
826
  for (const connection of connections) {
846
827
  if (
847
828
  !connection.dependency ||
848
- connection.dependency instanceof getCommonJsSelfReferenceDependency()
829
+ !(connection.dependency instanceof HarmonyImportDependency)
849
830
  ) {
850
831
  continue;
851
832
  }
@@ -18,6 +18,7 @@ const memoize = require("./util/memoize");
18
18
  /** @typedef {import("./ModuleGraph")} ModuleGraph */
19
19
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
20
20
  /** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
21
+ /** @typedef {import("./javascript/JavascriptModulesPlugin").ModuleRenderContext} ModuleRenderContext */
21
22
  /** @typedef {import("./util/Hash")} Hash */
22
23
 
23
24
  /**
@@ -44,7 +45,7 @@ class ModuleTemplate {
44
45
  /**
45
46
  * @template AdditionalOptions
46
47
  * @param {string | Tap & IfSet<AdditionalOptions>} options options
47
- * @param {(source: Source, module: Module, chunkRenderContext: ChunkRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
48
+ * @param {(source: Source, module: Module, moduleRenderContext: ModuleRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
48
49
  */
49
50
  (options, fn) => {
50
51
  getJavascriptModulesPlugin()
@@ -69,7 +70,7 @@ class ModuleTemplate {
69
70
  /**
70
71
  * @template AdditionalOptions
71
72
  * @param {string | Tap & IfSet<AdditionalOptions>} options options
72
- * @param {(source: Source, module: Module, chunkRenderContext: ChunkRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
73
+ * @param {(source: Source, module: Module, moduleRenderContext: ModuleRenderContext, dependencyTemplates: DependencyTemplates) => Source} fn fn
73
74
  */
74
75
  (options, fn) => {
75
76
  getJavascriptModulesPlugin()
package/lib/Watching.js CHANGED
@@ -187,8 +187,6 @@ class Watching {
187
187
 
188
188
  const compilation = /** @type {Compilation} */ (_compilation);
189
189
 
190
- if (this.invalid) return this._done(null, compilation);
191
-
192
190
  if (this.compiler.hooks.shouldEmit.call(compilation) === false) {
193
191
  return this._done(null, compilation);
194
192
  }
@@ -18,6 +18,8 @@ const NullDependency = require("./NullDependency");
18
18
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
19
19
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
20
20
  /** @typedef {import("./HarmonyAcceptImportDependency")} HarmonyAcceptImportDependency */
21
+ /** @typedef {import("../Module")} Module */
22
+ /** @typedef {import("../Module").ModuleId} ModuleId */
21
23
 
22
24
  class HarmonyAcceptDependency extends NullDependency {
23
25
  /**
@@ -84,7 +86,57 @@ HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends
84
86
  chunkGraph
85
87
  } = templateContext;
86
88
 
87
- /** @type {HarmonyAcceptImportDependency[]} */
89
+ /**
90
+ * @param {Dependency} dependency the dependency to get module id for
91
+ * @returns {ModuleId | null} the module id or null if not found
92
+ */
93
+ const getDependencyModuleId = (dependency) =>
94
+ chunkGraph.getModuleId(
95
+ /** @type {Module} */ (moduleGraph.getModule(dependency))
96
+ );
97
+
98
+ /**
99
+ * @param {Dependency} a the first dependency
100
+ * @param {Dependency} b the second dependency
101
+ * @returns {boolean} true if the dependencies are related
102
+ */
103
+ const isRelatedHarmonyImportDependency = (a, b) =>
104
+ a !== b &&
105
+ b instanceof HarmonyImportDependency &&
106
+ getDependencyModuleId(a) === getDependencyModuleId(b);
107
+
108
+ /**
109
+ * HarmonyAcceptImportDependency lacks a lot of information, such as the defer property.
110
+ * One HarmonyAcceptImportDependency may need to generate multiple ImportStatements.
111
+ * Therefore, we find its original HarmonyImportDependency for code generation.
112
+ * @param {HarmonyAcceptImportDependency} dependency the dependency to get harmony import dependencies for
113
+ * @returns {HarmonyImportDependency[]} array of related harmony import dependencies
114
+ */
115
+ const getHarmonyImportDependencies = (dependency) => {
116
+ const result = [];
117
+ let deferDependency = null;
118
+ let noDeferredDependency = null;
119
+
120
+ for (const d of module.dependencies) {
121
+ if (deferDependency && noDeferredDependency) break;
122
+ if (isRelatedHarmonyImportDependency(dependency, d)) {
123
+ if (d.defer) {
124
+ deferDependency = /** @type {HarmonyImportDependency} */ (d);
125
+ } else {
126
+ noDeferredDependency = /** @type {HarmonyImportDependency} */ (d);
127
+ }
128
+ }
129
+ }
130
+ if (deferDependency) result.push(deferDependency);
131
+ if (noDeferredDependency) result.push(noDeferredDependency);
132
+ if (result.length === 0) {
133
+ // fallback to the original dependency
134
+ result.push(dependency);
135
+ }
136
+ return result;
137
+ };
138
+
139
+ /** @type {HarmonyImportDependency[]} */
88
140
  const syncDeps = [];
89
141
 
90
142
  /** @type {HarmonyAcceptImportDependency[]} */
@@ -96,7 +148,7 @@ HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends
96
148
  if (connection && moduleGraph.isAsync(connection.module)) {
97
149
  asyncDeps.push(dependency);
98
150
  } else {
99
- syncDeps.push(dependency);
151
+ syncDeps.push(...getHarmonyImportDependencies(dependency));
100
152
  }
101
153
  }
102
154
 
@@ -55,7 +55,12 @@ const getExportsWithDepth = (exportsDepth) =>
55
55
  exports.push({
56
56
  name: key,
57
57
  canMangle: true,
58
- exports: getExportsFromData(data[key], curDepth + 1) || undefined
58
+ exports:
59
+ getExportsFromData(
60
+ /** @type {JsonValue} */
61
+ (data[key]),
62
+ curDepth + 1
63
+ ) || undefined
59
64
  });
60
65
  }
61
66
 
@@ -7,7 +7,6 @@
7
7
 
8
8
  const Dependency = require("../Dependency");
9
9
  const DependencyTemplate = require("../DependencyTemplate");
10
- const RawModule = require("../RawModule");
11
10
 
12
11
  /** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
13
12
  /** @typedef {import("../Module")} Module */
@@ -61,6 +60,8 @@ class ModuleDependency extends Dependency {
61
60
  * @returns {Module} ignored module
62
61
  */
63
62
  createIgnoredModule(context) {
63
+ const RawModule = require("../RawModule");
64
+
64
65
  const module = new RawModule(
65
66
  "/* (ignored) */",
66
67
  `ignored|${context}|${this.request}`,
@@ -6,6 +6,10 @@
6
6
 
7
7
  const RuntimeGlobals = require("../RuntimeGlobals");
8
8
  const RuntimeModule = require("../RuntimeModule");
9
+ const Template = require("../Template");
10
+
11
+ // CompatibilityPlugin renames `__webpack_require__` but doesn’t account for `export { __webpack_require__ }`, so we create a temporary variable to handle it.
12
+ const EXPORT_TEMP_NAME = "__webpack_require_temp__";
9
13
 
10
14
  class ExportWebpackRequireRuntimeModule extends RuntimeModule {
11
15
  constructor() {
@@ -23,7 +27,10 @@ class ExportWebpackRequireRuntimeModule extends RuntimeModule {
23
27
  * @returns {string | null} runtime code
24
28
  */
25
29
  generate() {
26
- return `export default ${RuntimeGlobals.require};`;
30
+ return Template.asString([
31
+ `var ${EXPORT_TEMP_NAME} = ${RuntimeGlobals.require};`,
32
+ `export { ${EXPORT_TEMP_NAME} as ${RuntimeGlobals.require} };`
33
+ ]);
27
34
  }
28
35
  }
29
36