diff --git a/addon/ng2/models/find-lazy-modules.ts b/addon/ng2/models/find-lazy-modules.ts index 9b98a9079ec2..8874c8802ebe 100644 --- a/addon/ng2/models/find-lazy-modules.ts +++ b/addon/ng2/models/find-lazy-modules.ts @@ -6,39 +6,39 @@ import * as ts from 'typescript'; import {getSource, findNodes, getContentOfKeyLiteral} from '../utilities/ast-utils'; -function flatMap(obj: Array, mapFn: (item: T) => R | R[]): Array { - return obj.reduce((arr: R[], current: T) => { - const result = mapFn.call(null, current); - return result !== undefined ? arr.concat(result) : arr; - }, []); -} - - export function findLoadChildren(tsFilePath: string): string[] { const source = getSource(tsFilePath); const unique: { [path: string]: boolean } = {}; - let nodes = flatMap( - findNodes(source, ts.SyntaxKind.ObjectLiteralExpression), - node => findNodes(node, ts.SyntaxKind.PropertyAssignment)) - .filter((node: ts.PropertyAssignment) => { - const key = getContentOfKeyLiteral(source, node.name); - if (!key) { - // key is an expression, can't do anything. - return false; - } - return key == 'loadChildren'; - }) - // Remove initializers that are not files. - .filter((node: ts.PropertyAssignment) => { - return node.initializer.kind === ts.SyntaxKind.StringLiteral; - }) - // Get the full text of the initializer. - .map((node: ts.PropertyAssignment) => { - return JSON.parse(node.initializer.getText(source)); // tslint:disable-line - }); - - return nodes + return ( + // Find all object literals. + findNodes(source, ts.SyntaxKind.ObjectLiteralExpression) + // Get all their property assignments. + .map(node => findNodes(node, ts.SyntaxKind.PropertyAssignment)) + // Flatten into a single array (from an array of array). + .reduce((prev, curr) => curr ? prev.concat(curr) : prev, []) + // Remove every property assignment that aren't 'loadChildren'. + .filter((node: ts.PropertyAssignment) => { + const key = getContentOfKeyLiteral(source, node.name); + if (!key) { + // key is an expression, can't do anything. + return false; + } + return key == 'loadChildren'; + }) + // Remove initializers that are not files. + .filter((node: ts.PropertyAssignment) => { + return node.initializer.kind === ts.SyntaxKind.StringLiteral; + }) + // Get the full text of the initializer. + .map((node: ts.PropertyAssignment) => { + const literal = node.initializer as ts.StringLiteral; + return literal.text; + }) + // Map to the module name itself. + .map((moduleName: string) => moduleName.split('#')[0]) + // Only get unique values (there might be multiple modules from a single URL, or a module used + // multiple times). .filter((value: string) => { if (unique[value]) { return false; @@ -46,8 +46,7 @@ export function findLoadChildren(tsFilePath: string): string[] { unique[value] = true; return true; } - }) - .map((moduleName: string) => moduleName.split('#')[0]); + })); } diff --git a/packages/ast-tools/src/ast-utils.ts b/packages/ast-tools/src/ast-utils.ts index 0ffe4c6d8580..40ebfb5aa5e2 100644 --- a/packages/ast-tools/src/ast-utils.ts +++ b/packages/ast-tools/src/ast-utils.ts @@ -96,13 +96,9 @@ export function insertAfterLastOccurrence(nodes: ts.Node[], toInsert: string, export function getContentOfKeyLiteral(source: ts.SourceFile, node: ts.Node): string { if (node.kind == ts.SyntaxKind.Identifier) { - return (node).text; + return (node as ts.Identifier).text; } else if (node.kind == ts.SyntaxKind.StringLiteral) { - try { - return JSON.parse(node.getFullText(source)); - } catch (e) { - return null; - } + return (node as ts.StringLiteral).text; } else { return null; } diff --git a/tests/acceptance/find-lazy-module.spec.ts b/tests/acceptance/find-lazy-module.spec.ts new file mode 100644 index 000000000000..4d44804dd549 --- /dev/null +++ b/tests/acceptance/find-lazy-module.spec.ts @@ -0,0 +1,48 @@ +import * as mockFs from 'mock-fs'; +import {stripIndents} from 'common-tags'; +import {expect} from 'chai'; + +import {findLazyModules} from '../../addon/ng2/models/find-lazy-modules'; + + +describe('find-lazy-module', () => { + beforeEach(() => { + mockFs({ + 'project-root': { + 'fileA.ts': stripIndents` + const r1 = { + "loadChildren": "moduleA" + }; + const r2 = { + loadChildren: "moduleB" + }; + const r3 = { + 'loadChildren': 'moduleC' + }; + const r4 = { + "loadChildren": 'app/+workspace/+settings/settings.module#SettingsModule' + }; + const r5 = { + loadChildren: 'unexistentModule' + }; + `, + // Create those files too as they have to exist. + 'moduleA.ts': '', + 'moduleB.ts': '', + 'moduleC.ts': '', + 'moduleD.ts': '', + 'app': { '+workspace': { '+settings': { 'settings.module.ts': '' } } } + } + }); + }); + afterEach(() => mockFs.restore()); + + it('works', () => { + expect(findLazyModules('project-root')).to.eql([ + 'moduleA', + 'moduleB', + 'moduleC', + 'app/+workspace/+settings/settings.module' + ]); + }); +});