Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

Angular rules

Alex Eagle edited this page Nov 18, 2018 · 5 revisions

The Angular rules run the Angular compiler (ngc) on individual packages, produce Angular libraries for distribution on npm, and more.

Source location: Angular bazel package.

API Documentation: https://angular.github.io/bazel-builds/

Issues: https://github.com/angular/angular/issues where we'll add a comp: bazel label.

Setup

Angular libraries are distributed on npm, including the Bazel rules. First install the npm dependency using one of the equivalent commands below:

$ yarn add -dev @angular/bazel
# OR
$ npm install --save-dev @angular/bazel
# OR
$ bazel run @nodejs//:bin/yarn -- add -dev @angular/bazel # On windows, it's @nodejs//:bin/yarn.cmd

We also need to tell Bazel how to find the Angular rules in the WORKSPACE. In addition, we want Bazel to be able to find RxJS source files to compile them, so we add both:

local_repository(
    name="angular",
    path="node_modules/@angular/bazel"
)
local_repository(
    name = "rxjs",
    path = "node_modules/rxjs/src",
)

See the example.

We must also do an extra step to generate code for our dependencies. Since Angular libraries (including @angular/common) are distributed only with JavaScript and Angular Metadata, they are incomplete. In a non-Bazel setup, the ngc command compiles the whole world, including the libraries in node_modules. Since we only compile one package at a time in Bazel, we must bootstrap this by compiling the libraries first before any ng_module rules execute.

Currently we recommend doing this in your package.json as a postinstall script. We'll just run ngc like any standard non-Bazel application does, but with zero application sources. This will just leave the generated code in the library directories under node_modules. Any time you re-install your dependencies, this postinstall script makes sure they have generated code too.

Around the time of Angular 6 we expect this step can be removed, follow https://github.com/angular/angular/issues/18810

{
    "scripts": {
        "postinstall": "ngc -p angular.tsconfig.json",
    }
}

This requires an extra angular.tsconfig.json file inside your project, which can be short:

{
    "compilerOptions": {
        "lib": [
            "dom",
            "es2015"
        ],
        "experimentalDecorators": true,
        "types": []
    },
    "include": [
        "node_modules/@angular/**/*"
    ],
    "exclude": [
        "node_modules/@angular/bazel/**",
        "node_modules/@angular/compiler-cli/**",
        "node_modules/@angular/tsc-wrapped/**"
    ]
}

Usage

Compiling Angular templates

ng_module runs the Angular compiler on one package of Angular code. At Google, we make our packages small, typically 1:1 with an @NgModule declaration in the code, so the rule is named to be synonymous with this convention.

ng_module behaves exactly the same as ts_library, except that it accepts additional attributes:

  • assets point to .html and .css inputs. If you use SASS, the asset should be the label of the sass_binary rule. The angular compiler produces extra JavaScript output corresponding with these inputs.

Outputs:

  • same as for ts_library, with the addition of .ngsummary.json files which are for ngc what .d.ts files are for tsc
  • also produces .ngfactory.d.ts/.ngfactory.js files, but we plan to stop producing these for Angular 6

Unit testing

You can use the ts_web_test rule to test Angular components. See the example for a spec file, and the BUILD.bazel file where the test target is defined.

End-to-end testing

This is still under development, but you can do it today by running the build with Bazel, then testing the result outside of Bazel.

The example repo currently uses a protractor.conf.json file (see example). You can see this points to Bazel-compiled JavaScript outputs dist/bin/test/e2e/*.spec.js, since Protractor is running outside of Bazel.

To execute it, we need three things in the package.json file:

  • Install the webdriver extensions to remote-control your browser, webdriver-manager update
  • Run the bazel build to create the *.spec.js files, eg. bazel build test/...
  • Run the application and protractor at the same time, using the concurrently package from npm. Note that we don't have a production server yet, but we can run the devserver: concurrently "bazel run //src:devserver" protractor --kill-others --success first

See the example package.json where these are all combined.