Skip to content

Commit 04d605e

Browse files
committed
feat(@ngtools/webpack): compile a module map for commonjs bundles
1 parent 5932dc7 commit 04d605e

2 files changed

Lines changed: 59 additions & 12 deletions

File tree

packages/@ngtools/webpack/src/loader.ts

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,15 +435,12 @@ function _diagnoseDeps(reasons: ModuleReason[], plugin: AotPlugin, checked: Set<
435435
}
436436

437437

438-
export function _stuff(plugin: AotPlugin, refactor: TypeScriptFileRefactor) {
439-
if (!plugin.replaceExport) {
440-
return;
441-
}
442-
438+
export function _getModuleExports(plugin: AotPlugin,
439+
refactor: TypeScriptFileRefactor): ts.Identifier[] {
443440
const exports = refactor
444441
.findAstNodes(refactor.sourceFile, ts.SyntaxKind.ExportDeclaration, true);
445442

446-
exports
443+
return exports
447444
.filter(node => {
448445

449446
const identifiers = refactor.findAstNodes(node, ts.SyntaxKind.Identifier, false);
@@ -452,7 +449,15 @@ export function _stuff(plugin: AotPlugin, refactor: TypeScriptFileRefactor) {
452449
.filter(node => node.getText() === plugin.entryModule.className);
453450

454451
return identifiers.length > 0;
455-
})
452+
}) as ts.Identifier[];
453+
}
454+
455+
456+
export function _stuff(plugin: AotPlugin, refactor: TypeScriptFileRefactor) {
457+
if (!plugin.replaceExport) {
458+
return;
459+
}
460+
_getModuleExports(plugin, refactor)
456461
.forEach(node => {
457462
const factoryPath = _getNgFactoryPath(plugin, refactor);
458463
const factoryClassName = plugin.entryModule.className + 'NgFactory';
@@ -462,6 +467,43 @@ export function _stuff(plugin: AotPlugin, refactor: TypeScriptFileRefactor) {
462467
}
463468

464469

470+
export function _stuff2(plugin: AotPlugin, refactor: TypeScriptFileRefactor) {
471+
if (!plugin.replaceExport) {
472+
return;
473+
}
474+
475+
_getModuleExports(plugin, refactor)
476+
.forEach(node => {
477+
const routes: any[] = Object.keys(plugin.discoveredLazyRoutes)
478+
.map(routeKey => {
479+
let lazyRouteKey = routeKey.split('#')[0];
480+
if (!plugin.skipCodeGeneration) {
481+
lazyRouteKey += '.ngfactory';
482+
}
483+
return {
484+
loadChildrenString: routeKey,
485+
path: plugin.lazyRoutes[lazyRouteKey],
486+
name: routeKey.split('#')[1]
487+
};
488+
});
489+
let map: { [key: string]: string } = {};
490+
routes.forEach(module => {
491+
const append = plugin.skipCodeGeneration ? '' : 'NgFactory';
492+
map[module.loadChildrenString] = module.name + append;
493+
});
494+
495+
let exportStatement = `export const moduleMap = ${JSON.stringify(map)};`;
496+
routes.forEach((module, index) => {
497+
const moduleName = map[module.loadChildrenString];
498+
exportStatement = exportStatement.replace(
499+
`"${moduleName}"`, `__lazy_${index}__.${moduleName}`);
500+
refactor.prependBefore(node, `import * as __lazy_${index}__ from '${module.path}'`);
501+
});
502+
refactor.appendAfter(node, exportStatement);
503+
});
504+
}
505+
506+
465507
// Super simple TS transpiler loader for testing / isolated usage. does not type check!
466508
export function ngcLoader(this: LoaderContext & { _compilation: any }, source: string | null) {
467509
const cb = this.async();
@@ -492,11 +534,13 @@ export function ngcLoader(this: LoaderContext & { _compilation: any }, source: s
492534
return Promise.resolve()
493535
.then(() => _removeDecorators(refactor))
494536
.then(() => _refactorBootstrap(plugin, refactor))
495-
.then(() => _stuff(plugin, refactor));
537+
.then(() => _stuff(plugin, refactor))
538+
.then(() => _stuff2(plugin, refactor));
496539
} else {
497540
return Promise.resolve()
498541
.then(() => _replaceResources(refactor))
499-
.then(() => _removeModuleId(refactor));
542+
.then(() => _removeModuleId(refactor))
543+
.then(() => _stuff2(plugin, refactor));
500544
}
501545
})
502546
.then(() => {

packages/@ngtools/webpack/src/plugin.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export class AotPlugin implements Tapable {
5050
private _rootFilePath: string[];
5151
private _compilerHost: WebpackCompilerHost;
5252
private _resourceLoader: WebpackResourceLoader;
53+
private _discoveredLazyRoutes: LazyRouteMap;
5354
private _lazyRoutes: LazyRouteMap = Object.create(null);
5455
private _tsConfigPath: string;
5556
private _entryModule: string;
@@ -97,6 +98,8 @@ export class AotPlugin implements Tapable {
9798
get i18nFormat() { return this._i18nFormat; }
9899
get locale() { return this._locale; }
99100
get firstRun() { return this._firstRun; }
101+
get lazyRoutes() { return this._lazyRoutes; }
102+
get discoveredLazyRoutes() { return this._discoveredLazyRoutes; }
100103

101104
private _setupOptions(options: AotPluginOptions) {
102105
// Fill in the missing options.
@@ -497,7 +500,7 @@ export class AotPlugin implements Tapable {
497500
.then(() => {
498501
// We need to run the `listLazyRoutes` the first time because it also navigates libraries
499502
// and other things that we might miss using the findLazyRoutesInAst.
500-
let discoveredLazyRoutes: LazyRouteMap = this.firstRun ?
503+
this._discoveredLazyRoutes = this.firstRun ?
501504
__NGTOOLS_PRIVATE_API_2.listLazyRoutes({
502505
program: this._program,
503506
host: this._compilerHost,
@@ -507,9 +510,9 @@ export class AotPlugin implements Tapable {
507510
: this._findLazyRoutesInAst();
508511

509512
// Process the lazy routes discovered.
510-
Object.keys(discoveredLazyRoutes)
513+
Object.keys(this.discoveredLazyRoutes)
511514
.forEach(k => {
512-
const lazyRoute = discoveredLazyRoutes[k];
515+
const lazyRoute = this.discoveredLazyRoutes[k];
513516
k = k.split('#')[0];
514517
if (lazyRoute === null) {
515518
return;

0 commit comments

Comments
 (0)