2016-04-29 00:57:16 -04:00
|
|
|
# Angular Template Compiler
|
|
|
|
|
|
|
|
Angular applications are built with templates, which may be `.html` or `.css` files,
|
|
|
|
or may be inline `template` attributes on Decorators like `@Component`.
|
|
|
|
|
|
|
|
These templates are compiled into executable JS at application runtime (except in `interpretation` mode).
|
|
|
|
This compilation can occur on the client, but it results in slower bootstrap time, and also
|
|
|
|
requires that the compiler be included in the code downloaded to the client.
|
|
|
|
|
|
|
|
You can produce smaller, faster applications by running Angular's compiler as a build step,
|
|
|
|
and then downloading only the executable JS to the client.
|
|
|
|
|
2016-04-29 13:35:36 -04:00
|
|
|
## Install and use
|
|
|
|
|
|
|
|
```
|
2016-05-03 15:26:59 -04:00
|
|
|
# First install angular, see https://github.com/angular/angular/blob/master/CHANGELOG.md#200-rc0-2016-05-02
|
|
|
|
$ npm install @angular/compiler-cli typescript@next @angular/platform-server @angular/compiler
|
|
|
|
# Optional sanity check, make sure TypeScript can compile.
|
2016-04-29 13:35:36 -04:00
|
|
|
$ ./node_modules/.bin/tsc -p path/to/project
|
2016-05-03 15:26:59 -04:00
|
|
|
# ngc is a drop-in replacement for tsc.
|
|
|
|
$ ./node_modules/.bin/ngc -p path/to/project
|
2016-04-29 13:35:36 -04:00
|
|
|
```
|
|
|
|
|
|
|
|
In order to write a `bootstrap` that imports the generated code, you should first write your
|
2016-05-03 15:26:59 -04:00
|
|
|
top-level component, and run `ngc` once to produce a generated `.ngfactory.ts` file.
|
2016-04-29 13:35:36 -04:00
|
|
|
Then you can add an import statement in the `bootstrap` allowing you to bootstrap off the
|
2016-06-10 20:35:06 -04:00
|
|
|
generated code:
|
|
|
|
|
|
|
|
```typescript
|
2016-10-24 18:10:03 -04:00
|
|
|
main.module.ts
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
|
|
|
-------------
|
|
|
|
import {BrowserModule} from '@angular/platform-browser';
|
2016-07-18 06:50:31 -04:00
|
|
|
import {Component, NgModule, ApplicationRef} from '@angular/core';
|
2016-06-10 20:35:06 -04:00
|
|
|
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
|
|
|
@Component(...)
|
|
|
|
export class MyComponent {}
|
2016-06-10 20:35:06 -04:00
|
|
|
|
2016-07-18 06:50:31 -04:00
|
|
|
@NgModule({
|
|
|
|
imports: [BrowserModule],
|
|
|
|
declarations: [MyComponent],
|
2016-07-25 03:36:30 -04:00
|
|
|
entryComponents: [MyComponent]
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
|
|
|
})
|
|
|
|
export class MainModule {
|
|
|
|
constructor(appRef: ApplicationRef) {
|
|
|
|
appRef.bootstrap(MyComponent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bootstrap.ts
|
|
|
|
-------------
|
|
|
|
|
2016-10-24 18:10:03 -04:00
|
|
|
import {MainModuleNgFactory} from './main.module.ngfactory';
|
2016-08-15 16:44:01 -04:00
|
|
|
import {platformBrowser} from '@angular/platform-browser';
|
feat(browser): use AppModules for bootstrap in the browser
This introduces the `BrowserModule` to be used for long form
bootstrap and offline compile bootstrap:
```
@AppModule({
modules: [BrowserModule],
precompile: [MainComponent],
providers: […], // additional providers
directives: […], // additional platform directives
pipes: […] // additional platform pipes
})
class MyModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MainComponent);
}
}
// offline compile
import {bootstrapModuleFactory} from ‘@angular/platform-browser’;
bootstrapModuleFactory(MyModuleNgFactory);
// runtime compile long form
import {bootstrapModule} from ‘@angular/platform-browser-dynamic’;
bootstrapModule(MyModule);
```
The short form, `bootstrap(...)`, can now creates a module on the fly,
given `directives`, `pipes, `providers`, `precompile` and `modules`
properties.
Related changes:
- make `SanitizationService`, `SecurityContext` public in `@angular/core` so that the offline compiler can resolve the token
- move `AnimationDriver` to `platform-browser` and make it
public so that the offline compiler can resolve the token
BREAKING CHANGES:
- short form bootstrap does no longer allow
to inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead.
To provide custom providers for the compiler,
create a custom compiler via `browserCompiler({providers: [...]})`
and pass that into the `bootstrap` method.
2016-06-30 16:07:17 -04:00
|
|
|
|
2016-08-15 16:44:01 -04:00
|
|
|
platformBrowser().bootstrapModuleFactory(MainModuleNgFactory);
|
2016-06-10 20:35:06 -04:00
|
|
|
```
|
2016-04-29 13:35:36 -04:00
|
|
|
|
2016-04-29 00:57:16 -04:00
|
|
|
## Configuration
|
|
|
|
|
2016-04-29 13:35:36 -04:00
|
|
|
The `tsconfig.json` file may contain an additional configuration block:
|
2016-04-29 00:57:16 -04:00
|
|
|
```
|
|
|
|
"angularCompilerOptions": {
|
2016-06-15 17:56:56 -04:00
|
|
|
"genDir": ".",
|
|
|
|
"debug": true
|
2016-04-29 00:57:16 -04:00
|
|
|
}
|
|
|
|
```
|
2016-06-15 17:56:56 -04:00
|
|
|
|
|
|
|
### `genDir`
|
|
|
|
|
2016-04-29 00:57:16 -04:00
|
|
|
the `genDir` option controls the path (relative to `tsconfig.json`) where the generated file tree
|
2016-04-29 13:35:36 -04:00
|
|
|
will be written. If `genDir` is not set, then the code will be generated in the source tree, next
|
|
|
|
to your original sources. More options may be added as we implement more features.
|
2016-04-29 00:57:16 -04:00
|
|
|
|
|
|
|
We recommend you avoid checking generated files into version control. This permits a state where
|
|
|
|
the generated files in the repository were created from sources that were never checked in,
|
|
|
|
making it impossible to reproduce the current state. Also, your changes will effectively appear
|
|
|
|
twice in code reviews, with the generated version inscrutible by the reviewer.
|
|
|
|
|
|
|
|
In TypeScript 1.8, the generated sources will have to be written alongside your originals,
|
|
|
|
so set `genDir` to the same location as your files (typicially the same as `rootDir`).
|
2017-03-09 16:11:13 -05:00
|
|
|
Add `**/*.ngfactory.ts` and `**/*.ngsummary.json` to your `.gitignore` or other mechanism for your
|
|
|
|
version control system.
|
2016-04-29 00:57:16 -04:00
|
|
|
|
|
|
|
In TypeScript 1.9 and above, you can add a generated folder into your application,
|
|
|
|
such as `codegen`. Using the `rootDirs` option, you can allow relative imports like
|
|
|
|
`import {} from './foo.ngfactory'` even though the `src` and `codegen` trees are distinct.
|
|
|
|
Add `**/codegen` to your `.gitignore` or similar.
|
|
|
|
|
|
|
|
Note that in the second option, TypeScript will emit the code into two parallel directories
|
|
|
|
as well. This is by design, see https://github.com/Microsoft/TypeScript/issues/8245.
|
|
|
|
This makes the configuration of your runtime module loader more complex, so we don't recommend
|
|
|
|
this option yet.
|
|
|
|
|
2016-06-15 17:56:56 -04:00
|
|
|
### `debug`
|
|
|
|
|
|
|
|
Set the `debug` option to true to generate debug information in the generate files.
|
|
|
|
Default to `false`.
|
|
|
|
|
2016-04-29 00:57:16 -04:00
|
|
|
See the example in the `test/` directory for a working example.
|
|
|
|
|
|
|
|
## Compiler CLI
|
|
|
|
|
|
|
|
This program mimics the TypeScript tsc command line. It accepts a `-p` flag which points to a
|
|
|
|
`tsconfig.json` file, or a directory containing one.
|
|
|
|
|
|
|
|
This CLI is intended for demos, prototyping, or for users with simple build systems
|
|
|
|
that run bare `tsc`.
|
|
|
|
|
2017-01-27 01:30:42 -05:00
|
|
|
Users with a build system should expect an Angular template plugin. Such a plugin would be
|
2017-01-27 20:39:48 -05:00
|
|
|
based on the `public_api.ts` in this directory, but should share the TypeScript compiler instance
|
2016-04-29 00:57:16 -04:00
|
|
|
with the one already used in the plugin for TypeScript typechecking and emit.
|
|
|
|
|
|
|
|
## Design
|
|
|
|
At a high level, this program
|
2017-09-20 12:54:47 -04:00
|
|
|
- collects static metadata about the sources
|
2017-01-27 01:30:42 -05:00
|
|
|
- uses the `OfflineCompiler` from `@angular/compiler` to codegen additional `.ts` files
|
2016-04-29 00:57:16 -04:00
|
|
|
- these `.ts` files are written to the `genDir` path, then compiled together with the application.
|
|
|
|
|
|
|
|
## For developers
|
|
|
|
```
|
2017-01-27 01:30:42 -05:00
|
|
|
# Build Angular and the compiler
|
2016-05-27 19:22:16 -04:00
|
|
|
./build.sh
|
2016-07-09 13:12:39 -04:00
|
|
|
|
2016-05-27 19:22:16 -04:00
|
|
|
# Run the test once
|
|
|
|
# (First edit the LINKABLE_PKGS to use npm link instead of npm install)
|
2017-03-05 04:49:10 -05:00
|
|
|
$ ./scripts/ci/offline_compiler_test.sh
|
2016-07-09 13:12:39 -04:00
|
|
|
|
2016-05-27 19:22:16 -04:00
|
|
|
# Keep a package fresh in watch mode
|
2017-03-07 14:04:30 -05:00
|
|
|
./node_modules/.bin/tsc -p packages/compiler/tsconfig-build.json -w
|
2016-07-09 13:12:39 -04:00
|
|
|
|
2016-06-28 12:54:42 -04:00
|
|
|
# Recompile @angular/core module (needs to use tsc-ext to keep the metadata)
|
2016-07-09 13:12:39 -04:00
|
|
|
$ export NODE_PATH=${NODE_PATH}:$(pwd)/dist/all:$(pwd)/dist/tools
|
2017-09-20 12:54:47 -04:00
|
|
|
$ node dist/tools/@angular/compiler-cli/src/main -p packages/core/tsconfig-build.json
|
2016-07-09 13:12:39 -04:00
|
|
|
|
2016-05-27 19:22:16 -04:00
|
|
|
# Iterate on the test
|
2016-07-09 13:12:39 -04:00
|
|
|
$ cd /tmp/wherever/e2e_test.1464388257/
|
|
|
|
$ ./node_modules/.bin/ngc
|
|
|
|
$ ./node_modules/.bin/jasmine test/*_spec.js
|
2016-04-29 13:35:36 -04:00
|
|
|
```
|