Skip to content

Commit 2c8ce07

Browse files
fix: initial work on aot compilation (#17)
1 parent 23410f0 commit 2c8ce07

File tree

13 files changed

+151
-83
lines changed

13 files changed

+151
-83
lines changed

package-lock.json

Lines changed: 30 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"zone.js": "^0.8.26"
7070
},
7171
"dependencies": {
72+
"@angular/compiler-cli": "^6.1.0-beta.2",
7273
"ajv": "^6.5.1",
7374
"chalk": "^2.4.1",
7475
"favicons": "^5.1.1",
@@ -77,7 +78,7 @@
7778
"npm": "^6.1.0",
7879
"rxjs": "^6.2.1",
7980
"ts-node": "^6.1.2",
80-
"typescript": "^2.9.2",
81+
"typescript": "2.7.2",
8182
"uglify-js": "^3.4.1",
8283
"yargs": "^11.0.0"
8384
},

src/commands/serve.ts

Lines changed: 27 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,31 @@ import { FuseBox, JSONPlugin, QuantumPlugin } from 'fuse-box'
55
import { resolve } from 'path'
66
import { NgProdPlugin } from '../fusebox/ng.prod.plugin'
77
import { NgPolyfillPlugin } from '../fusebox/ng.polyfill.plugin'
8+
import { NgCompilerPlugin } from '../fusebox/ng.compiler.plugin'
89
import readConfig_ from '../utilities/read-config'
910

10-
// function test() {
11-
// // const fuseBrowser = FuseBox.init({
12-
// // homeDir: "src/browser",
13-
// // output: ".dist/public/js/$name.js",
14-
// // target: 'browser@es5',
15-
// // plugins: [
16-
// // // NgProdPlugin({ enabled: opts.productionBuild }),
17-
// // // NgPolyfillPlugin(),
18-
// // // NgCompilerPlugin({ enabled: opts.enableAotCompilaton }),
19-
// // // NgOptimizerPlugin({ enabled: opts.enableAngularBuildOptimizer }),
20-
// // // opts.productionBuild && QuantumPlugin({
21-
// // // warnings: false,
22-
// // // uglify: false,
23-
// // // treeshake: false,
24-
// // // bakeApiIntoBundle: 'vendor'
25-
// // // // replaceProcessEnv: false,
26-
// // // // processPolyfill: true,
27-
// // // // ensureES5: true
28-
// // // })
29-
// // ] as any
30-
// // })
31-
32-
// const fuseServer = FuseBox.init({
33-
// target: 'server@es5',
34-
// homeDir,
35-
// output: `${outputDir}/$name.js`,
36-
// plugins: [
37-
// // NgProdPlugin({ enabled: opts.productionBuild, fileTest: 'server.angular.module' }),
38-
// // NgPolyfillPlugin({ isServer: true, fileTest: 'server.angular.module' })
39-
// ]
40-
// })
41-
42-
// // const mainAppEntry = opts.enableAotCompilaton
43-
// // ? 'main.aot.ts'
44-
// // : 'main.ts'
45-
46-
// // fuseBrowser
47-
// // .bundle('vendor')
48-
// // .instructions(` ~ ${mainAppEntry}`)
49-
50-
// // fuseBrowser
51-
// // .bundle('app')
52-
// // .watch('src/**')
53-
// // .instructions(` !> [${mainAppEntry}]`)
54-
55-
// fuseServer
56-
// .bundle("server")
57-
// .watch("src/**")
58-
// .instructions(" > [server/server.ts]")
59-
// .completed(proc => proc.start())
60-
// }
61-
6211
command(
63-
'serve [port][prod]',
12+
'serve [port][prod][aot][sw]',
6413
'serve your application',
6514
args => {
6615
return args
6716
},
6817
args => {
69-
serve(args.prod)
18+
serve(args.prod, args.aot)
7019
}
7120
)
7221
.option('prod', {
7322
default: false,
7423
description: 'Run with optimizations enabled'
7524
})
25+
.option('aot', {
26+
default: false,
27+
description: 'Pass through AOT Compiler'
28+
})
29+
.option('sw', {
30+
default: false,
31+
description: 'Enable service-worker'
32+
})
7633
.option('port', {
7734
default: 5000,
7835
description: 'Http server port number'
@@ -82,7 +39,7 @@ function logServeCommandStart() {
8239
logInfo('Launching Serve Command')
8340
}
8441

85-
function serve(isProdBuild = false) {
42+
function serve(isProdBuild = false, isAotBuild = false) {
8643
readConfig_()
8744
.pipe(
8845
tap(logServeCommandStart),
@@ -91,10 +48,14 @@ function serve(isProdBuild = false) {
9148
.subscribe(config => {
9249
const cache = !isProdBuild
9350
const log = config.fusebox.verbose || false
94-
const homeDir = resolve(config.fusebox.server.homeDir)
51+
const homeDir = resolve('.')
9552
const serverOutput = resolve(config.fusebox.server.outputDir)
9653
const browserOutput = resolve(config.fusebox.browser.outputDir)
9754
const modulesFolder = resolve(process.cwd(), 'node_modules')
55+
const watchDir = `${homeDir}/src/**`
56+
const browserModule = isAotBuild
57+
? config.fusebox.browser.aotBrowserModule
58+
: config.fusebox.browser.browserModule
9859

9960
const fuseBrowser = FuseBox.init({
10061
log,
@@ -103,10 +64,11 @@ function serve(isProdBuild = false) {
10364
cache,
10465
output: `${browserOutput}/$name.js`,
10566
target: 'browser@es5',
67+
useTypescriptCompiler: true,
10668
plugins: [
10769
NgProdPlugin({ enabled: isProdBuild }),
70+
NgCompilerPlugin({ enabled: isAotBuild }),
10871
NgPolyfillPlugin(),
109-
// NgCompilerPlugin({ enabled: opts.enableAotCompilaton }),
11072
// NgOptimizerPlugin({ enabled: opts.enableAngularBuildOptimizer }),
11173
isProdBuild &&
11274
QuantumPlugin({
@@ -131,29 +93,29 @@ function serve(isProdBuild = false) {
13193
plugins: [
13294
JSONPlugin(),
13395
NgProdPlugin({
134-
enabled: isProdBuild,
135-
fileTest: 'server.angular.module'
96+
enabled: true,
97+
fileTest: 'server.angular.module.ts'
13698
}),
13799
NgPolyfillPlugin({
138100
isServer: true,
139-
fileTest: 'server.angular.module'
101+
fileTest: 'server.angular.module.ts'
140102
})
141103
]
142104
})
143105

144106
fuseBrowser
145107
.bundle('vendor')
146-
.watch(`**`)
147-
.instructions(` ~ ${config.fusebox.browser.browserModule}`)
108+
.watch(watchDir)
109+
.instructions(` ~ ${browserModule}`)
148110

149111
fuseBrowser
150112
.bundle('app')
151-
.watch(`**`)
152-
.instructions(` !> [${config.fusebox.browser.browserModule}]`)
113+
.watch(watchDir)
114+
.instructions(` !> [${browserModule}]`)
153115

154116
fuseServer
155117
.bundle('server')
156-
.watch(`**`)
118+
.watch(watchDir)
157119
.instructions(` > [${config.fusebox.server.serverModule}]`)
158120
.completed(proc => proc.start())
159121

src/fusebox/ng.compiler.plugin.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { main as ngc } from '@angular/compiler-cli/src/main'
2+
import { Plugin, File } from 'fuse-box'
3+
import { resolve } from 'path'
4+
5+
// tslint:disable:no-class
6+
// tslint:disable:no-this
7+
// tslint:disable:no-if-statement
8+
// tslint:disable:no-object-mutation
9+
// tslint:disable:readonly-keyword
10+
const defaults: NgcPluginOptions = {}
11+
12+
export interface NgcPluginOptions {
13+
enabled?: boolean
14+
}
15+
16+
export class NgcPluginClass implements Plugin {
17+
constructor(private opts: NgcPluginOptions = defaults) {}
18+
public test: RegExp = /-routing.module.js/
19+
bundleStart() {
20+
this.opts.enabled && ngc(['-p', resolve('tsconfig.aot.json')])
21+
}
22+
23+
transform(file: File) {
24+
const regex1 = new RegExp(/.module'/, 'g')
25+
const regex2 = new RegExp(/Module\);/, 'g')
26+
file.contents = file.contents.replace(regex1, ".module.ngfactory'")
27+
file.contents = file.contents.replace(regex2, 'ModuleNgFactory);')
28+
}
29+
}
30+
31+
export const NgCompilerPlugin = (options?: NgcPluginOptions) =>
32+
new NgcPluginClass(options)

src/fusebox/ng.polyfill.plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class NgPolyfillPluginClass implements Plugin {
5555
constructor(private opts: NgPolyfillPluginOptions = defaults) {}
5656
public test: RegExp =
5757
(this.opts.fileTest && new RegExp(this.opts.fileTest)) ||
58-
/(app.browser.module.ts)/
58+
/(app.browser.module.(ts|js))/
5959
public dependencies: ['zone.js', 'core-js']
6060

6161
onTypescriptTransform(file: File) {

src/fusebox/ng.prod.plugin.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class NgProdPluginClass implements Plugin {
2323
}
2424

2525
public dependencies: ['@angular/core']
26-
public test = this.regex || /(main.ts|main.aot.ts)/
26+
public test = this.regex || /app.browser.module.(ts|js)/
2727

2828
get regex() {
2929
return (
@@ -34,8 +34,10 @@ export class NgProdPluginClass implements Plugin {
3434

3535
onTypescriptTransform(file: File) {
3636
if (!this.opts.enabled || !this.test.test(file.relativePath)) return
37-
file.contents = `import { enableProdMode } from '@angular/core';
38-
enableProdMode()
37+
file.contents = `
38+
import { enableProdMode } from '@angular/core';
39+
enableProdMode();
40+
3941
${file.contents}`
4042
}
4143
}

src/generators/deps.const.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ export const ANGULAR_UNIVERSAL_DEPS = {
2727
}
2828

2929
export const ANGULAR_UNIVERSAL_DEV_DEPS = {
30+
'@types/compression': '^0.0.36',
3031
'@types/cookie-parser': '^1.4.1',
3132
'@types/express': '^4.16.0'
3233
}
3334

3435
export const ANGULAR_UNIVERSAL_EXPRESS_DEPS = {
36+
compression: '^1.7.2',
3537
'cookie-parser': '^1.4.3',
3638
express: '^4.16.3',
3739
'express-minify-html': '^0.12.0'

src/generators/tsconfig.gen.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import { writeFile_, writeFileSafely_ } from '../utilities/rx-fs'
22
import { resolve } from 'path'
3+
import { forkJoin } from 'rxjs'
34
import * as tsconfig from '../templates/tsconfig.json.txt'
5+
import * as aotTsconfig from '../templates/tsconfig.aot.json.txt'
46

57
const configPath = 'tsconfig.json'
8+
const configPath2 = 'tsconfig.aot.json'
69

710
export default function generateTsConfig(dir: string, overwrite = false) {
811
return overwrite
9-
? writeFile_(resolve(dir, configPath), tsconfig)
10-
: writeFileSafely_(resolve(dir, configPath), tsconfig)
12+
? forkJoin([
13+
writeFile_(resolve(dir, configPath), tsconfig),
14+
writeFile_(resolve(dir, configPath2), aotTsconfig)
15+
])
16+
: forkJoin([
17+
writeFileSafely_(resolve(dir, configPath), tsconfig),
18+
writeFileSafely_(resolve(dir, configPath2), aotTsconfig)
19+
])
1120
}

src/templates/core/server/server.app.ts.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import * as express from 'express'
22
import * as cookieParser from 'cookie-parser'
3+
import * as compression from 'compression'
34
import { resolve } from 'path'
45
import { ngExpressEngine } from '@nguniversal/express-engine'
56
import { AppServerModule } from './server.angular.module'
67
import { stat, writeFile } from 'fs'
78
import * as config from '../../fusing-angular.json'
89

9-
// const shrinkRay = require('shrink-rayed')
1010
// const minifyHTML = require('express-minify-html')
1111
// const xhr2 = require('xhr2')
1212

@@ -32,7 +32,7 @@ const publicDir = `${dir}/public`
3232
// }
3333

3434
expressApp.use(cookieParser())
35-
// expressApp.use(shrinkRay())
35+
expressApp.use(compression())
3636

3737
expressApp.use('/favicon.ico', (req, res) => res.sendStatus(204)) // TODO: FAVICONS
3838
expressApp.use('/js', express.static(`${publicDir}/js`, { fallthrough: false }))

src/templates/fusebox.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
export const FUSEBOX_DEFAULTS = {
22
verbose: false,
33
browser: {
4-
homeDir: 'src',
54
outputDir: '.dist/public/js',
6-
browserModule: 'browser/app.browser.module.ts',
5+
browserModule: 'src/browser/app.browser.jit.entry.ts',
6+
aotBrowserModule: '.aot/src/browser/app.browser.aot.entry.js',
77
prod: {
88
uglify: true,
99
treeshake: true
1010
}
1111
},
1212
server: {
13-
homeDir: 'src',
1413
outputDir: '.dist',
1514
serverModule: 'server/server.ts'
1615
}

0 commit comments

Comments
 (0)