angular-cn/packages/compiler-cli
Alex Rickabaugh 1eafd04eb3 build(ivy): support alternate compilation modes to enable Ivy testing (#24056)
Bazel has a restriction that a single output (eg. a compiled version of
//packages/common) can only be produced by a single rule. This precludes
the Angular repo from having multiple rules that build the same code. And
the complexity of having a single rule produce multiple outputs (eg. an
ngc-compiled version of //packages/common and an Ivy-enabled version) is
too high.

Additionally, the Angular repo has lots of existing tests which could be
executed as-is under Ivy. Such testing is very valuable, and it would be
nice to share not only the code, but the dependency graph / build config
as well.

Thus, this change introduces a --define flag 'compile' with three potential
values. When --define=compile=X is set, the entire build system runs in a
particular mode - the behavior of all existing targets is controlled by
the flag. This allows us to reuse our entire build structure for testing
in a variety of different manners. The flag has three possible settings:

* legacy (the default): the traditional View Engine (ngc) build
* local: runs the prototype ngtsc compiler, which does not rely on global
  analysis
* jit: runs ngtsc in a mode which executes tsickle, but excludes the
  Angular related transforms, which approximates the behavior of plain
  tsc. This allows the main packages such as common to be tested with
  the JIT compiler.

Additionally, the ivy_ng_module() rule still exists and runs ngc in a mode
where Ivy-compiled output is produced from global analysis information, as
a stopgap while ngtsc is being developed.

PR Close #24056
2018-05-29 18:02:29 -04:00
..
integrationtest build(ivy): support alternate compilation modes to enable Ivy testing (#24056) 2018-05-29 18:02:29 -04:00
src build(ivy): support alternate compilation modes to enable Ivy testing (#24056) 2018-05-29 18:02:29 -04:00
test test: switch to ts_web_test_suite (#23859) 2018-05-15 11:40:56 -07:00
BUILD.bazel feat(ivy): first steps towards ngtsc mode (#23455) 2018-04-25 13:25:33 -07:00
README.md build: remove references to `tsc-wrapped` (#19298) 2017-09-21 13:55:52 -07:00
browser-rollup.config.js refactor: make all rollup config ES5 compatible (#20028) 2017-10-30 23:09:17 -04:00
index.ts fix(compiler-cli): don't report emit diagnostics when --noEmitOnError is off (#20063) 2017-11-02 14:49:38 -07:00
ngtools2.ts refactor(compiler-cli): expose ngtools api separately (#18978) 2017-08-31 14:37:13 -07:00
package.json build: upgrade to TypeScript 2.8 (#23782) 2018-05-15 15:31:12 -07:00
tsconfig-build.json fix(bazel): ng_package should include private exports in fesms (#23054) 2018-03-29 14:11:12 -07:00
tsconfig-tools.json build: remove references to `tsc-wrapped` (#19298) 2017-09-21 13:55:52 -07:00
tsconfig.json build(compiler-cli): fix tsconfig.json circularity issue (#22722) 2018-03-15 21:18:07 -07:00

README.md

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.

Install and use

# 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.
$ ./node_modules/.bin/tsc -p path/to/project
# ngc is a drop-in replacement for tsc.
$ ./node_modules/.bin/ngc -p path/to/project

In order to write a bootstrap that imports the generated code, you should first write your top-level component, and run ngc once to produce a generated .ngfactory.ts file. Then you can add an import statement in the bootstrap allowing you to bootstrap off the generated code:

main.module.ts
-------------
import {BrowserModule} from '@angular/platform-browser';
import {Component, NgModule, ApplicationRef} from '@angular/core';

@Component(...)
export class MyComponent {}

@NgModule({
  imports: [BrowserModule],
  declarations: [MyComponent],
  entryComponents: [MyComponent]
})
export class MainModule {
  constructor(appRef: ApplicationRef) {
    appRef.bootstrap(MyComponent);
  }
}

bootstrap.ts
-------------

import {MainModuleNgFactory} from './main.module.ngfactory';
import {platformBrowser} from '@angular/platform-browser';

platformBrowser().bootstrapModuleFactory(MainModuleNgFactory);

Configuration

The tsconfig.json file may contain an additional configuration block:

 "angularCompilerOptions": {
   "genDir": ".",
   "debug": true
 }

genDir

the genDir option controls the path (relative to tsconfig.json) where the generated file tree 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.

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). Add **/*.ngfactory.ts and **/*.ngsummary.json to your .gitignore or other mechanism for your version control system.

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.

debug

Set the debug option to true to generate debug information in the generate files. Default to false.

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.

Users with a build system should expect an Angular template plugin. Such a plugin would be based on the public_api.ts in this directory, but should share the TypeScript compiler instance with the one already used in the plugin for TypeScript typechecking and emit.

Design

At a high level, this program

  • collects static metadata about the sources
  • uses the OfflineCompiler from @angular/compiler to codegen additional .ts files
  • these .ts files are written to the genDir path, then compiled together with the application.

For developers

# Build Angular and the compiler
./build.sh

# Run the test once
# (First edit the LINKABLE_PKGS to use npm link instead of npm install)
$ ./scripts/ci/offline_compiler_test.sh

# Keep a package fresh in watch mode
./node_modules/.bin/tsc -p packages/compiler/tsconfig-build.json -w

# Recompile @angular/core module (needs to use tsc-ext to keep the metadata)
$ export NODE_PATH=${NODE_PATH}:$(pwd)/dist/all:$(pwd)/dist/tools
$ node dist/tools/@angular/compiler-cli/src/main -p packages/core/tsconfig-build.json

# Iterate on the test
$ cd /tmp/wherever/e2e_test.1464388257/
$ ./node_modules/.bin/ngc
$ ./node_modules/.bin/jasmine test/*_spec.js