Skip to content

Commit

Permalink
fix(@ngtools/webpack): find aliased lazy route factories
Browse files Browse the repository at this point in the history
Fix #14707
  • Loading branch information
filipesilva authored and vikerman committed Jul 29, 2019
1 parent 6b2b51f commit 95686a4
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 2 deletions.
16 changes: 15 additions & 1 deletion packages/ngtools/webpack/src/transformers/import_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import * as ts from 'typescript';
import { forwardSlashPath } from '../utils';


// Check if a ts.Symbol is an alias.
const isAlias = (symbol: ts.Symbol) => symbol.flags & ts.SymbolFlags.Alias;

/**
* Given this original source code:
*
Expand Down Expand Up @@ -193,15 +196,26 @@ function replaceImport(

// Try to resolve the import. It might be a reexport from somewhere and the ngfactory will only
// be present next to the original module.
const exportedSymbol = typeChecker.getSymbolAtLocation(exportNameId);
let exportedSymbol = typeChecker.getSymbolAtLocation(exportNameId);
if (!exportedSymbol) {
return warnAndBail();
}
// Named exports are also a declaration in the re-exporting module so we have to follow the
// re-exports to find the original symbol.
if (isAlias(exportedSymbol)) {
exportedSymbol = typeChecker.getAliasedSymbol(exportedSymbol);
if (!exportedSymbol) {
return warnAndBail();
}
}

// Find declarations of the original symbol so we can get their source file name.
const exportedSymbolDecl = exportedSymbol.getDeclarations();
if (!exportedSymbolDecl || exportedSymbolDecl.length === 0) {
return warnAndBail();
}

// Let's guess the first declaration is the one we want, because we don't have a better criteria.
// Get the relative path from the containing module to the imported module.
const relativePath = relative(dirname(fileName), exportedSymbolDecl[0].getSourceFile().fileName);

Expand Down
76 changes: 75 additions & 1 deletion packages/ngtools/webpack/src/transformers/import_factory_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('@ngtools/webpack transformers', () => {
expect(warningCalled).toBeTruthy();
});

it('should support resolving reexports', () => {
it('should support resolving * re-exports', () => {
const additionalFiles: Record<string, string> = {
'shared/index.ts': `
export * from './path/to/lazy/lazy.module';
Expand Down Expand Up @@ -97,5 +97,79 @@ describe('@ngtools/webpack transformers', () => {

expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
});

it('should support resolving named re-exports', () => {
const additionalFiles: Record<string, string> = {
'shared/index.ts': `
export { LazyModule } from './path/to/lazy/lazy.module';
`,
'shared/path/to/lazy/lazy.module.ts': `
export const LazyModule = {};
`,
};
const input = tags.stripIndent`
const ɵ0 = () => import('./shared').then(m => m.LazyModule);
const routes = [{
path: 'lazy',
loadChildren: ɵ0
}];
`;

const output = tags.stripIndent`
const ɵ0 = () => import("./shared/path/to/lazy/lazy.module.ngfactory").then(m => m.LazyModuleNgFactory);
const routes = [{
path: 'lazy',
loadChildren: ɵ0
}];
`;

const { program, compilerHost } = createTypescriptContext(input, additionalFiles, true);
const transformer = importFactory(() => { }, () => program.getTypeChecker());
const result = transformTypescript(undefined, [transformer], program, compilerHost);

expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
});


it('should support resolving re-export chains', () => {
const additionalFiles: Record<string, string> = {
'shared/index.ts': `
export { LazyModule } from './index2';
`,
'shared/index2.ts': `
export * from './index3';
`,
'shared/index3.ts': `
export { LazyModule } from './index4';
`,
'shared/index4.ts': `
export * from './path/to/lazy/lazy.module';
`,
'shared/path/to/lazy/lazy.module.ts': `
export const LazyModule = {};
`,
};
const input = tags.stripIndent`
const ɵ0 = () => import('./shared').then(m => m.LazyModule);
const routes = [{
path: 'lazy',
loadChildren: ɵ0
}];
`;

const output = tags.stripIndent`
const ɵ0 = () => import("./shared/path/to/lazy/lazy.module.ngfactory").then(m => m.LazyModuleNgFactory);
const routes = [{
path: 'lazy',
loadChildren: ɵ0
}];
`;

const { program, compilerHost } = createTypescriptContext(input, additionalFiles, true);
const transformer = importFactory(() => { }, () => program.getTypeChecker());
const result = transformTypescript(undefined, [transformer], program, compilerHost);

expect(tags.oneLine`${result}`).toEqual(tags.oneLine`${output}`);
});
});
});

0 comments on commit 95686a4

Please sign in to comment.