Skip to content

Commit de5139b

Browse files
committed
First implementation of get lazy modules entries.
1 parent 539c57d commit de5139b

File tree

6 files changed

+453
-18
lines changed

6 files changed

+453
-18
lines changed

addon/ng2/blueprints/ng2/files/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"core-js": "^2.4.0",
2424
"reflect-metadata": "0.1.3",
2525
"rxjs": "5.0.0-beta.6",
26+
"systemjs": "^0.19.36",
2627
"ts-helpers": "^1.1.1",
2728
"zone.js": "0.6.12"
2829
},

addon/ng2/models/find-lazy-modules.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import * as fs from 'fs';
2+
import * as glob from 'glob';
3+
import * as path from 'path';
4+
import * as ts from 'typescript';
5+
6+
import {Observable} from 'rxjs/Observable';
7+
import {getSource, findNodes, getContentOfKeyLiteral} from '../utilities/ast-utils';
8+
9+
10+
const loadChildrenRegex = /(\{[^{}]+?(loadChildren|['"]loadChildren['"])\s*:\s*)('[^']+'|"[^"]+")/gm;
11+
12+
13+
interface Array<T> {
14+
flatMap: <R>(mapFn: (item: T) => Array<R>) => Array<R>;
15+
}
16+
Array.prototype.flatMap = function<T, R>(mapFn: (item: T) => Array<R>): Array<R> {
17+
if (!mapFn) {
18+
return [];
19+
}
20+
21+
return this.reduce((arr, current) => {
22+
const result = mapFn.call(null, current);
23+
return result !== undefined ? arr.concat(result) : arr;
24+
}, []);
25+
};
26+
27+
28+
export function findLoadChildren(tsFilePath: string): string[] {
29+
const source = getSource(tsFilePath);
30+
const unique = {};
31+
32+
return findNodes(source, ts.SyntaxKind.ObjectLiteralExpression)
33+
.flatMap(node => findNodes(node, ts.SyntaxKind.PropertyAssignment))
34+
.filter((node: ts.PropertyAssignment) => {
35+
const key = getContentOfKeyLiteral(source, node.name);
36+
if (!key) {
37+
// key is an expression, can't do anything.
38+
return false;
39+
}
40+
return key == 'loadChildren'
41+
})
42+
// Remove initializers that are not files.
43+
.filter((node: ts.PropertyAssignment) => {
44+
return node.initializer.kind === ts.SyntaxKind.StringLiteral;
45+
})
46+
// Get the full text of the initiliazer.
47+
.map((node: ts.PropertyAssignment) => {
48+
return eval(node.initializer.getText(source));
49+
})
50+
.flatMap((value: string) => unique[value] ? undefined : unique[value] = value)
51+
.map((moduleName: string) => moduleName.split('#')[0]);
52+
}
53+
54+
55+
export function findLazyModules(projectRoot: any): string[] {
56+
const allTs = glob.sync(path.join(projectRoot, '/**/*.ts'));
57+
const result = {};
58+
allTs
59+
.flatMap(tsPath => {
60+
findLoadChildren(tsPath).forEach(moduleName => {
61+
const fileName = path.resolve(path.dirname(tsPath), moduleName) + '.ts';
62+
if (fs.existsSync(fileName)) {
63+
result[moduleName] = fileName;
64+
}
65+
});
66+
});
67+
return result;
68+
}

addon/ng2/models/webpack-build-common.ts

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,27 @@ import * as path from 'path';
22
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
33
import * as HtmlWebpackPlugin from 'html-webpack-plugin';
44
import * as webpack from 'webpack';
5-
import { ForkCheckerPlugin } from 'awesome-typescript-loader';
6-
import { CliConfig } from './config';
5+
import * as atl from 'awesome-typescript-loader';
6+
7+
import {SystemJSRegisterPublicModules} from './webpack-plugin-systemjs-registry';
8+
import {findLazyModules} from './find-lazy-modules';
9+
710

811
export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
12+
const lazyModules = findLazyModules(path.resolve(projectRoot, sourceDir));
13+
const entries = Object.assign({
14+
main: [path.resolve(projectRoot, `./${sourceDir}/main.ts`)],
15+
polyfills: path.resolve(projectRoot, `./${sourceDir}/polyfills.ts`)
16+
}, lazyModules);
17+
918
return {
1019
devtool: 'inline-source-map',
1120
resolve: {
1221
extensions: ['', '.ts', '.js'],
1322
root: path.resolve(projectRoot, `./${sourceDir}`)
1423
},
1524
context: path.resolve(__dirname, './'),
16-
entry: {
17-
main: [path.resolve(projectRoot, `./${sourceDir}/main.ts`)],
18-
polyfills: path.resolve(projectRoot, `./${sourceDir}/polyfills.ts`)
19-
},
25+
entry: entries,
2026
output: {
2127
path: path.resolve(projectRoot, './dist'),
2228
filename: '[name].bundle.js'
@@ -30,7 +36,16 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
3036
path.resolve(projectRoot, 'node_modules/rxjs'),
3137
path.resolve(projectRoot, 'node_modules/@angular'),
3238
]
33-
}
39+
},
40+
{
41+
test: /(systemjs_component_resolver|system_js_ng_module_factory_loader)\.js$/,
42+
loader: 'string-replace-loader',
43+
query: {
44+
search: '(lang_1(.*[\\n\\r]\\s*\\.|\\.))?(global(.*[\\n\\r]\\s*\\.|\\.))?(System|SystemJS)(.*[\\n\\r]\\s*\\.|\\.)import',
45+
replace: 'System.import',
46+
flags: 'g'
47+
}
48+
},
3449
],
3550
loaders: [
3651
{
@@ -42,8 +57,7 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
4257
useForkChecker: true,
4358
tsconfig: path.resolve(projectRoot, `./${sourceDir}/tsconfig.json`)
4459
}
45-
},
46-
{
60+
}, {
4761
loader: 'angular2-template-loader'
4862
}
4963
],
@@ -59,13 +73,13 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
5973
]
6074
},
6175
plugins: [
62-
new ForkCheckerPlugin(),
76+
new atl.ForkCheckerPlugin(),
6377
new HtmlWebpackPlugin({
6478
template: path.resolve(projectRoot, `./${sourceDir}/index.html`),
6579
chunksSortMode: 'dependency'
6680
}),
6781
new webpack.optimize.CommonsChunkPlugin({
68-
name: ['polyfills']
82+
name: 'polyfills'
6983
}),
7084
new webpack.optimize.CommonsChunkPlugin({
7185
minChunks: Infinity,
@@ -77,7 +91,35 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
7791
context: path.resolve(projectRoot, './public'),
7892
from: '**/*',
7993
to: path.resolve(projectRoot, './dist')
80-
}])
94+
}]),
95+
// new SystemJSRegisterPublicModules({
96+
// // automatically configure SystemJS to load webpack chunks (defaults to true)
97+
// bundlesConfigForChunks: true,
98+
//
99+
// // select which modules to expose as public modules
100+
// registerModules: [
101+
// // "default" filters provided are "local" and "public"
102+
// { filter: 'public' },
103+
// //
104+
// // // keyname allows a custom naming system for public modules
105+
// // {
106+
// // filter: 'local',
107+
// // keyname: 'app/[relPath]'
108+
// // },
109+
// //
110+
// // // keyname can be a function
111+
// // {
112+
// // filter: 'public',
113+
// // keyname: (module) => 'publicModule-' + module.id
114+
// // },
115+
// //
116+
// // // filter can also be a function
117+
// // {
118+
// // filter: (m) => m.relPath.match(/src/),
119+
// // keyname: 'random-naming-system-[id]'
120+
// // }
121+
// ]
122+
// })
81123
],
82124
node: {
83125
fs: 'empty',
@@ -88,4 +130,4 @@ export function getWebpackCommonConfig(projectRoot: string, sourceDir: string) {
88130
setImmediate: false
89131
}
90132
}
91-
};
133+
}

0 commit comments

Comments
 (0)