Skip to content

Commit a535933

Browse files
committed
chunk dependency detection
1 parent 18aab53 commit a535933

File tree

2 files changed

+85
-22
lines changed

2 files changed

+85
-22
lines changed

bundler/bundler-general.js

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,14 @@ class BundlerGeneral {
8484
let mainName = this.config.order[0];
8585

8686
/** @var {Object.<string, string[]>} */
87-
let notBundledMap = {};
87+
const notBundledMap = {};
88+
/** @var {Object.<string, string> */
89+
const moduleChunkMap = {};
90+
/** @var {Object.<string, string[]>} */
91+
const chunkDirectDependenctModulesMap = {};
8892

8993
this.config.order.forEach((name, i) => {
90-
let data = this.#bundleChunk(name, i === 0, {
94+
const data = this.#bundleChunk(name, i === 0, {
9195
files: files,
9296
templateFiles: templateFiles,
9397
});
@@ -100,13 +104,21 @@ class BundlerGeneral {
100104

101105
console.log(` Chunk '${name}' done, ${data.files.length} files.`)
102106

107+
chunkDirectDependenctModulesMap[name] = data.directDependencyModules;
108+
109+
if (i > 0) {
110+
for (const m of data.modules) {
111+
moduleChunkMap[m] = name;
112+
}
113+
}
114+
103115
if (i === 0 && this.config.order.length > 1) {
104116
return;
105117
}
106118

107119
data.modules.forEach(item => mapping[item] = name);
108120

109-
let bundleFile = this.filePattern.replace('{*}', name);
121+
const bundleFile = this.filePattern.replace('{*}', name);
110122

111123
let requires = [].concat(this.config.chunks[name].requires ?? []);
112124

@@ -115,15 +127,44 @@ class BundlerGeneral {
115127
}
116128

117129
if (requires.length) {
118-
let part = JSON.stringify(requires);
130+
const part = JSON.stringify(requires);
119131

120132
result[mainName] += `Espo.loader.mapBundleDependencies('${name}', ${part});\n`;
121133
}
122134

123135
result[mainName] += `Espo.loader.mapBundleFile('${name}', '${bundleFile}');\n`;
124136
});
125137

126-
let notBundledModules = [];
138+
this.config.order.slice(1).forEach(name => {
139+
const dependsOnChunks = [];
140+
const deps = [];
141+
142+
for (const m of chunkDirectDependenctModulesMap[name]) {
143+
const dependeeChunk = moduleChunkMap[m];
144+
145+
if (!dependeeChunk) {
146+
continue;
147+
}
148+
149+
deps.push(m);
150+
151+
if (!dependsOnChunks.includes(dependeeChunk)) {
152+
dependsOnChunks.push(dependeeChunk);
153+
}
154+
}
155+
156+
if (dependsOnChunks.length) {
157+
const part = dependsOnChunks.map(it => `'${it}'`).join(', ');
158+
159+
console.warn(`\nWarning: Chunk '${name}' depends on chunk(s) ${part}.`);
160+
console.log('Depends on:');
161+
console.log(deps);
162+
163+
console.log('\nRecommended to fix.');
164+
}
165+
});
166+
167+
const notBundledModules = [];
127168

128169
this.config.order.forEach(name => {
129170
notBundledMap[name]
@@ -133,7 +174,7 @@ class BundlerGeneral {
133174
});
134175

135176
if (notBundledModules.length) {
136-
let part = notBundledModules
177+
const part = notBundledModules
137178
.map(item => ' ' + item)
138179
.join('\n');
139180

@@ -156,17 +197,20 @@ class BundlerGeneral {
156197
* templateFiles: string[],
157198
* notBundledModules: string[],
158199
* dependencyModules: [],
200+
* directDependencyModules: string[],
159201
* }}
160202
*/
161203
#bundleChunk(name, isMain, alreadyBundled) {
162204
let contents = '';
163205
let modules = [];
164206
let dependencyModules = [];
207+
let directDependencyModules = [];
208+
209+
const params = this.config.chunks[name];
165210

166-
let params = this.config.chunks[name];
211+
const patterns = params.patterns;
167212

168-
let patterns = params.patterns;
169-
let lookupPatterns = []
213+
const lookupPatterns = []
170214
.concat(this.config.lookupPatterns)
171215
.concat(params.lookupPatterns || []);
172216

@@ -175,7 +219,7 @@ class BundlerGeneral {
175219
let notBundledModules = [];
176220

177221
if (params.patterns) {
178-
let bundler = new Bundler(
222+
const bundler = new Bundler(
179223
this.config.modulePaths,
180224
this.config.basePath,
181225
this.config.transpiledPath
@@ -188,7 +232,7 @@ class BundlerGeneral {
188232
ignoreFiles = ignoreFiles.concat(alreadyBundled.files);
189233
}
190234

191-
let data = bundler.bundle({
235+
const data = bundler.bundle({
192236
name: name,
193237
files: params.files,
194238
patterns: patterns,
@@ -212,14 +256,15 @@ class BundlerGeneral {
212256

213257
notBundledModules = data.notBundledModules;
214258
dependencyModules = data.dependencyModules;
259+
directDependencyModules = data.directDependencyModules;
215260
}
216261

217262
// Pre-compiled templates turned out to be slower if too many are bundled.
218263
// To be used sparingly.
219264
if (params.templatePatterns) {
220-
let ignoreFiles = params.noDuplicates ? [].concat(alreadyBundled.templateFiles) : [];
265+
const ignoreFiles = params.noDuplicates ? [].concat(alreadyBundled.templateFiles) : [];
221266

222-
let data = (new Precompiler()).precompile({
267+
const data = (new Precompiler()).precompile({
223268
patterns: params.templatePatterns,
224269
modulePaths: this.config.modulePaths,
225270
ignoreFiles: ignoreFiles,
@@ -236,6 +281,7 @@ class BundlerGeneral {
236281
templateFiles: bundledTemplateFiles,
237282
notBundledModules: notBundledModules,
238283
dependencyModules: dependencyModules,
284+
directDependencyModules: directDependencyModules,
239285
};
240286
}
241287
}

bundler/bundler.js

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class Bundler {
7676
* modules: string[],
7777
* notBundledModules: string[],
7878
* dependencyModules: string[],
79+
* directDependencyModules: string[],
7980
* }}
8081
*/
8182
bundle(params) {
@@ -98,7 +99,7 @@ class Bundler {
9899

99100
let notBundledModules = [];
100101

101-
let {files: sortedFiles, depModules} = this.#sortFiles(
102+
const {files: sortedFiles, depModules, directDepModules} = this.#sortFiles(
102103
params.name,
103104
fullPathFiles,
104105
allFiles,
@@ -115,14 +116,17 @@ class Bundler {
115116
this.#mapToTraspiledFiles(sortedFiles)
116117
.forEach(file => contents += this.#normalizeSourceFile(file) + '\n');
117118

118-
let modules = sortedFiles.map(file => this.#obtainModuleName(file));
119+
const modules = sortedFiles.map(file => this.#obtainModuleName(file));
120+
121+
const filteredDirectDepModules = directDepModules.filter(m => !modules.includes(m));
119122

120123
return {
121124
contents: contents,
122125
files: sortedFiles,
123126
modules: modules,
124127
notBundledModules: notBundledModules,
125128
dependencyModules: depModules,
129+
directDependencyModules: filteredDirectDepModules,
126130
};
127131
}
128132

@@ -179,6 +183,7 @@ class Bundler {
179183
* @return {{
180184
* files: string[],
181185
* depModules: string[],
186+
* directDepModules: string[],
182187
* }}
183188
*/
184189
#sortFiles(
@@ -193,11 +198,15 @@ class Bundler {
193198
libs
194199
) {
195200
/** @var {Object.<string, string[]>} */
196-
let map = {};
201+
let moduleDepsMap = {};
197202
let standalonePathList = [];
198203
let modules = [];
199204
let moduleFileMap = {};
200205

206+
// All direct dependency modules, including dependency to this chunk.
207+
// To be filtered in the upper method call.
208+
const directDepModules = [];
209+
201210
let ignoreModules = ignoreFiles.map(file => this.#obtainModuleName(file));
202211

203212
allFiles.forEach(file => {
@@ -213,7 +222,7 @@ class Bundler {
213222
return;
214223
}
215224

216-
map[data.name] = data.deps;
225+
moduleDepsMap[data.name] = data.deps;
217226
moduleFileMap[data.name] = file;
218227

219228
if (isTarget) {
@@ -226,7 +235,7 @@ class Bundler {
226235

227236
modules
228237
.forEach(name => {
229-
let deps = this.#obtainAllDeps(name, map);
238+
const deps = this.#obtainAllDeps(name, moduleDepsMap);
230239

231240
deps
232241
.filter(item => !modules.includes(item))
@@ -251,10 +260,10 @@ class Bundler {
251260
/** @var {string[]} */
252261
let pickedModules = [];
253262

254-
for (let module of modules) {
263+
for (const module of modules) {
255264
this.#buildTreeItem(
256265
module,
257-
map,
266+
moduleDepsMap,
258267
depthMap,
259268
ignoreLibs,
260269
dependentOn,
@@ -275,6 +284,13 @@ class Bundler {
275284

276285
modules = modules.filter(item => !discardedModules.includes(item));
277286

287+
288+
for (const m of modules) {
289+
(moduleDepsMap[m] || [])
290+
.filter(it => !directDepModules.includes(it))
291+
.forEach(it => directDepModules.push(it));
292+
}
293+
278294
let modulePaths = modules.map(name => {
279295
if (!moduleFileMap[name] && mapDependencies) {
280296
return null;
@@ -284,8 +300,8 @@ class Bundler {
284300
return moduleFileMap[name];
285301
}
286302

287-
for (let item of libs) {
288-
let libId = item.amdId;
303+
for (const item of libs) {
304+
const libId = item.amdId;
289305

290306
if (libId && libId === name) {
291307
return null;
@@ -300,6 +316,7 @@ class Bundler {
300316
return {
301317
files: standalonePathList.concat(modulePaths),
302318
depModules: allDepModules,
319+
directDepModules: directDepModules,
303320
};
304321
}
305322

0 commit comments

Comments
 (0)