Skip to content
This repository was archived by the owner on Apr 4, 2025. It is now read-only.

Commit 1c40392

Browse files
gregmagolanalexeagle
authored andcommitted
Build angular from source (#160)
* Build angular from source & switch to protractor_web_test_suite for e2e tests * Pull rules_typescript from npm (@bazel/typescript package) * Add comments * Add comment * Remove skydoc_repositories() call from WORKSPACE * Update README * Address review comments * Add comment about protractor onPrepare function * Address review comments
1 parent 8d147b7 commit 1c40392

21 files changed

+321
-483
lines changed

.circleci/bazel.rc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ build --experimental_repository_cache=/home/circleci/bazel_repository_cache
2323

2424
# Workaround https://github.com/bazelbuild/bazel/issues/3645
2525
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
26-
# Limit Bazel to consuming 3072K of RAM
27-
build --local_resources=3072,2.0,1.0
26+
# Limit Bazel to consuming 2560K of RAM
27+
build --local_resources=2560,1.0,1.0
2828
# Also limit Bazel's own JVM heap to stay within our 4G container limit
29-
startup --host_jvm_args=-Xmx2G
29+
startup --host_jvm_args=-Xmx1g

.circleci/config.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ jobs:
6060
- run: bazel info release
6161

6262
# Install the dependencies from NPM
63-
- run: bazel run @nodejs//:yarn install
63+
# TODO(gmagolan): Use `bazel run :install` once bootstrap issue resolved.
64+
# See https://github.com/bazelbuild/rules_nodejs/issues/275.
65+
- run: yarn
6466

6567
# Build and Test
6668
# Use bazel query so that we explicitly ask for all buildable targets to
@@ -70,10 +72,6 @@ jobs:
7072

7173
# Run the benchmark
7274
- run: node_modules/.bin/ibazel-benchmark-runner //src:devserver src/hello-world/hello-world.component.ts --url=http://localhost:5432
73-
74-
# Run the protractor end-to-end test - it's not a Bazel target because
75-
# we didn't write a protractor rule yet.
76-
- run: xvfb-run -a yarn e2e
7775

7876
- store_artifacts:
7977
path: dist/bin/src/bundle.min.js

BUILD.bazel

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ alias(
55
actual = "@nodejs//:yarn",
66
)
77

8+
# ts_library and ng_module use the `//:tsconfig.json` target
9+
# by default. This alias allows omitting explicit tsconfig
10+
# attribute.
11+
alias(
12+
name = "tsconfig.json",
13+
actual = "//src:tsconfig.json",
14+
)
15+
816
# This export allows targets in other packages to reference files that live
917
# in this package.
1018
exports_files([
11-
# Let ts_library targets reference the root tsconfig.json file
12-
"tsconfig.json",
1319
# Let devserver and testing targets reference zone.js distro
1420
"node_modules/zone.js/dist/zone.min.js",
1521
"node_modules/zone.js/dist/zone-testing-bundle.js",
@@ -18,46 +24,33 @@ exports_files([
1824
# NOTE: this will move to node_modules/BUILD in a later release
1925
filegroup(
2026
name = "node_modules",
21-
# NB: rxjs is not in this list, because we build it from sources using the
22-
# label @rxjs//:rxjs
27+
# NB: angular & rxjs are not in this list, because we build them from sources
2328
srcs = glob(["/".join([
2429
"node_modules",
2530
pkg,
2631
"**",
2732
ext,
2833
]) for pkg in [
29-
"@angular",
3034
"@ngrx",
3135
"@types",
36+
"bytebuffer",
37+
"protobufjs",
3238
"protractor",
39+
"reflect-metadata",
3340
"tsickle",
41+
"tslib",
3442
"tsutils",
3543
"typescript",
44+
"zone.js",
3645
] for ext in [
3746
"*.js",
3847
"*.json",
3948
"*.d.ts",
40-
]]),
41-
)
42-
43-
ANGULAR_TESTING = [
44-
"node_modules/@angular/*/bundles/*-testing.umd.js",
45-
# We use AOT, so the compiler and the dynamic platform-browser should be
46-
# visible only in tests
47-
"node_modules/@angular/compiler/bundles/*.umd.js",
48-
"node_modules/@angular/platform-browser-dynamic/bundles/*.umd.js",
49-
]
50-
51-
filegroup(
52-
name = "angular_bundles",
53-
srcs = glob(
54-
["node_modules/@angular/*/bundles/*.umd.js"],
55-
exclude = ANGULAR_TESTING,
56-
),
57-
)
58-
59-
filegroup(
60-
name = "angular_test_bundles",
61-
testonly = 1,
62-
srcs = glob(ANGULAR_TESTING),
49+
]] + [
50+
"node_modules/protractor/**",
51+
]) + ["@build_bazel_rules_typescript//:node_modules"],
52+
# "@build_bazel_rules_typescript//:node_modules" is incluced
53+
# in `//:node_modules` so that npm dependencies that are hoisted to
54+
# node_modules/@bazel/typescript/node_modules because of conflicting
55+
# versions can be resolved correctly
6356
)

README.md

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,23 @@ npm install -g @bazel/ibazel
3838
## Setup
3939

4040
Before building the app, we install packages, just as with any npm-based development workflow.
41-
However, to get the same version of the toolchain as co-workers and our continuous integration, let's have Bazel run the
42-
package manager using a pinned version it manages. You should not even need
43-
node, npm, or yarn installed on a machine where you develop with Bazel.
4441

4542
```bash
46-
$ bazel run :install
43+
$ yarn install
4744
```
4845

46+
or
47+
48+
```bash
49+
$ npm install
50+
```
51+
52+
For the time being, you need to run your locally installed `yarn` or `npm` to install dependencies
53+
as shown above. This is because we pull down the `@bazel/typescript` bazel dependency from npm and
54+
that dependency needs to be in place before we can build the project. We're investigating
55+
how to resolve this bootstrapping issue so in the future you will be able run `bazel run :install` to
56+
install your npm packages without needing a local installation of `node`, `yarn` or `npm`.
57+
4958
## Development
5059

5160
Next we'll run the development server:
@@ -68,15 +77,29 @@ is less than two seconds, even for a large application.
6877

6978
Control-C twice to kill the devserver and also stop `ibazel`.
7079

71-
We can also run all the unit tests:
80+
## Testing
81+
82+
We can also run all the unit and e2e tests:
7283

7384
```bash
7485
$ ibazel test ...
7586
```
7687

77-
This will run all the tests. In this example, there is a test for the
78-
`hello-world` component. Note that Bazel will only re-run the tests whose inputs
79-
changed since the last run.
88+
This will run all the tests.
89+
90+
In this example, there is a unit test for the `hello-world` component which uses
91+
the `ts_web_test_suite` rule. There are also protractor e2e tests for both the
92+
`prodserver` and `devserver` which use the `protractor_web_test_suite` rule.
93+
94+
You can also run these tests individually using,
95+
96+
```bash
97+
$ bazel test //src/hello-world:test
98+
$ bazel test //test/e2e:prodserver_test
99+
$ bazel test //test/e2e:devserver_test
100+
```
101+
102+
Note that Bazel will only re-run the tests whose inputs changed since the last run.
80103

81104
## Production
82105

@@ -89,14 +112,6 @@ bundlers can be integrated with Bazel.
89112
$ ibazel run src:prodserver
90113
```
91114

92-
We also use Protractor to run end-to-end tests. We don't have a protractor rule
93-
yet, so we'll take the build results from Bazel and run the test outside of Bazel.
94-
95-
```bash
96-
$ yarn e2e
97-
```
98-
99115
## Coming soon
100116

101-
- Protractor bazel rule
102117
- Code-splitting and lazy loading (planned for Q2/Q3 2018)

WORKSPACE

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@ workspace(name = "angular_bazel_example")
1414
# Allows Bazel to run tooling in Node.js
1515
http_archive(
1616
name = "build_bazel_rules_nodejs",
17-
urls = ["https://github.com/bazelbuild/rules_nodejs/archive/0.10.0.zip"],
18-
strip_prefix = "rules_nodejs-0.10.0",
19-
sha256 = "2f77623311da8b5009b1c7eade12de8e15fa3cd2adf9dfcc9f87cb2082b2211f",
17+
urls = ["https://github.com/bazelbuild/rules_nodejs/archive/0.11.3.zip"],
18+
strip_prefix = "rules_nodejs-0.11.3",
19+
sha256 = "e8842fa5f5e38f2c826167ff94323d4b5aabd13217cee867d971d6f860cfd730"
20+
)
21+
22+
# build_bazel_rules_nodejs depends on skylib
23+
http_archive(
24+
name = "bazel_skylib",
25+
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.3.1.zip"],
26+
strip_prefix = "bazel-skylib-0.3.1",
27+
sha256 = "95518adafc9a2b656667bbf517a952e54ce7f350779d0dd95133db4eb5c27fb1",
2028
)
2129

2230
# The Bazel buildtools repo contains tools like the BUILD file formatter, buildifier
@@ -33,21 +41,32 @@ http_archive(
3341
)
3442

3543
# Runs the TypeScript compiler
36-
http_archive(
44+
local_repository(
3745
name = "build_bazel_rules_typescript",
38-
url = "https://github.com/bazelbuild/rules_typescript/archive/0.15.3.zip",
39-
strip_prefix = "rules_typescript-0.15.3",
40-
sha256 = "a2b26ac3fc13036011196063db1bf7f1eae81334449201dc28087ebfa3708c99",
46+
path = "node_modules/@bazel/typescript",
47+
)
48+
49+
# build_bazel_rules_typescript depends on io_bazel_skydoc
50+
http_archive(
51+
name = "io_bazel_skydoc",
52+
urls = ["https://github.com/bazelbuild/skydoc/archive/0ef7695c9d70084946a3e99b89ad5a99ede79580.zip"],
53+
strip_prefix = "skydoc-0ef7695c9d70084946a3e99b89ad5a99ede79580",
54+
sha256 = "491f9e142b870b18a0ec8eb3d66636eeceabe5f0c73025706c86f91a1a2acb4d",
4155
)
4256

4357
# Used by the ts_web_test_suite rule to provision browsers
4458
http_archive(
4559
name = "io_bazel_rules_webtesting",
46-
# Use a commit SHA because we need a release
47-
# https://github.com/bazelbuild/rules_webtesting/issues/273
48-
url = "https://github.com/bazelbuild/rules_webtesting/archive/bbfc846d98dacb0fb40dd9173acfe4070e3e0f62.zip",
49-
strip_prefix = "rules_webtesting-bbfc846d98dacb0fb40dd9173acfe4070e3e0f62",
50-
sha256 = "a79e2d681b7c9ddc51e7974ddb385b9ee2b389cdc823dd3e78e18936337e4c5a",
60+
url = "https://github.com/bazelbuild/rules_webtesting/archive/0.2.1.zip",
61+
strip_prefix = "rules_webtesting-0.2.1",
62+
sha256 = "7d490aadff9b5262e5251fa69427ab2ffd1548422467cb9f9e1d110e2c36f0fa",
63+
)
64+
65+
# bazel_gazelle is a transitive dep of rules_typescript and rules_webtesting
66+
http_archive(
67+
name = "bazel_gazelle",
68+
urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.13.0/bazel-gazelle-0.13.0.tar.gz"],
69+
sha256 = "bc653d3e058964a5a26dcad02b6c72d7d63e6bb88d94704990b908a1445b8758",
5170
)
5271

5372
# Runs the Sass CSS preprocessor
@@ -65,13 +84,12 @@ http_archive(
6584
sha256 = "ba79c532ac400cefd1859cbc8a9829346aa69e3b99482cd5a54432092cbc3933",
6685
)
6786

68-
####################################
69-
# Tell Bazel about some workspaces that were installed from npm.
70-
7187
# The @angular repo contains rule for building Angular applications
72-
local_repository(
88+
http_archive(
7389
name = "angular",
74-
path = "node_modules/@angular/bazel",
90+
url = "https://github.com/angular/angular/archive/6.1.2.zip",
91+
strip_prefix = "angular-6.1.2",
92+
sha256 = "e7553542cebd1113069a92d97a464a2d2aa412242926686653b8cf0101935617",
7593
)
7694

7795
# The @rxjs repo contains targets for building rxjs with bazel
@@ -83,7 +101,7 @@ local_repository(
83101
####################################
84102
# Load and install our dependencies downloaded above.
85103

86-
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
104+
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories", "yarn_install")
87105

88106
node_repositories(package_json = ["//:package.json"])
89107

@@ -100,14 +118,25 @@ browser_repositories(
100118
firefox = True,
101119
)
102120

103-
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
121+
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace", "check_rules_typescript_version")
104122

105123
ts_setup_workspace()
106124

125+
# 0.16.0: tsc_wrapped uses user's typescript version & check_rules_typescript_version
126+
check_rules_typescript_version("0.16.0")
127+
107128
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
108129

109130
sass_repositories()
110131

132+
#
133+
# Load and install our dependencies from local repositories
134+
#
135+
136+
load("@angular//:index.bzl", "ng_setup_workspace")
137+
138+
ng_setup_workspace()
139+
111140
####################################
112141
# Setup our local toolchain
113142

package.json

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,29 @@
44
"description": "Demo of bazel rules for angular",
55
"license": "Apache 2.0",
66
"dependencies": {
7-
"@angular/animations": "6.0.4",
8-
"@angular/common": "6.0.4",
9-
"@angular/core": "6.0.4",
10-
"@angular/forms": "6.0.4",
11-
"@angular/platform-browser": "6.0.4",
12-
"@angular/router": "6.0.4",
13-
"@angular/upgrade": "6.0.4",
147
"@ngrx/store": "6.1.0",
158
"rxjs": "6.2.2",
9+
"tslib": "1.9.3",
1610
"zone.js": "0.8.26"
1711
},
1812
"devDependencies": {
19-
"@angular/bazel": "6.0.4",
20-
"@angular/compiler": "6.0.4",
21-
"@angular/compiler-cli": "6.0.4",
22-
"@angular/platform-browser-dynamic": "6.0.4",
13+
"@angular/compiler": "6.1.2",
14+
"@angular/compiler-cli": "6.1.2",
15+
"@angular/core": "6.1.2",
2316
"@bazel/benchmark-runner": "0.1.0",
2417
"@bazel/ibazel": "0.4.0",
18+
"@bazel/typescript": "0.16.0",
2519
"@types/jasmine": "2.8.8",
20+
"@types/node": "6.0.88",
2621
"clang-format": "1.2.3",
27-
"concurrently": "3.6.1",
2822
"husky": "0.14.3",
2923
"protractor": "5.4.0",
30-
"typescript": "2.7.2"
24+
"tsickle": "0.32.1",
25+
"typescript": "2.9.1"
3126
},
3227
"scripts": {
33-
"postinstall": "concurrently \"webdriver-manager update $CHROMEDRIVER_VERSION_ARG\" \"ngc -p postinstall.tsconfig.json\"",
28+
"postinstall": "ngc -p postinstall.tsconfig.json",
3429
"serve": "ibazel run //src:devserver",
35-
"pree2e": "bazel build test/...",
36-
"e2e": "yarn e2e-prodserver && yarn e2e-devserver",
37-
"e2e-prodserver": "concurrently \"bazel run //src:prodserver\" \"while ! nc -z 127.0.0.1 5432; do sleep 1; done && protractor\" --kill-others --success first",
38-
"e2e-devserver": "concurrently \"bazel run //src:devserver\" \"while ! nc -z 127.0.0.1 5432; do sleep 1; done && protractor\" --kill-others --success first",
3930
"prebuildifier": "bazel build @com_github_bazelbuild_buildtools//buildifier",
4031
"buildifier": "note: working around https://github.com/alexeagle/angular-bazel-example/issues/60",
4132
"buildifier": "find . -type f \\( -name BUILD -or -name BUILD.bazel \\) ! -path \"./node_modules/*\" | xargs $(bazel info bazel-bin)/external/com_github_bazelbuild_buildtools/buildifier/*/buildifier",

postinstall.tsconfig.json

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
// WORKAROUND https://github.com/angular/angular/issues/18810
2-
// This file is required to run ngc on angular and other libraries,
3-
// to write files like node_modules/@angular/core/core.ngsummary.json
2+
//
3+
// This file is required to run ngc on 3rd party libraries such as @ngrx,
4+
// to write files like node_modules/@ngrx/store/store.ngsummary.json.
5+
//
6+
// Using ngc to create generated files is sufficient as long
7+
// as there are no components or directives in the 3rd party library
8+
// that are used. If there are, then there is an existing issue where
9+
// components & modules that use these 3rd party components or directives
10+
// can't be tested with ts_web_test_suite().
11+
// See https://github.com/bazelbuild/rules_typescript/issues/192
12+
//
13+
// The work-around for this right now is to compile the 3rd party
14+
// from source using Bazel so that Bazel is used to create
15+
// its generated files.
416
{
517
"compilerOptions": {
618
"lib": [
@@ -11,14 +23,9 @@
1123
"types": []
1224
},
1325
"include": [
14-
"node_modules/@angular/**/*",
1526
"node_modules/@ngrx/**/*"
1627
],
1728
"exclude": [
18-
"node_modules/@angular/bazel/**",
19-
"node_modules/@angular/compiler-cli/**",
20-
"node_modules/@angular/tsc-wrapped/**",
21-
"node_modules/@angular/*/testing/**",
2229
"node_modules/@ngrx/store/migrations/**",
2330
"node_modules/@ngrx/store/schematics/**",
2431
"node_modules/@ngrx/store/schematics-core/**"

0 commit comments

Comments
 (0)