Updates to rules_nodejs 2.2.0. This is the first major release in 7 months and includes a number of features as well
as breaking changes.
Release notes: https://github.com/bazelbuild/rules_nodejs/releases/tag/2.0.0
Features of note for angular/angular:
* stdout/stderr/exit code capture; this could be potentially be useful
* TypeScript (ts_project); a simpler tsc rule that ts_library that can be used in the repo where ts_library is too
heavy weight
Breaking changes of note for angular/angular:
* loading custom rules from npm packages: `ts_library` is no longer loaded from `@npm_bazel_typescript//:index.bzl`
(which no longer exists) but is now loaded from `@npm//@bazel/typescript:index.bzl`
* with the loading changes above, `load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")` is
no longer needed in the WORKSPACE which also means that yarn_install does not need to run unless building/testing
a target that depends on @npm. In angular/angular this is a minor improvement as almost everything depends on @npm.
* @angular/bazel package is also updated in this PR to support the new load location; Angular + Bazel users that
require it for ng_package (ng_module is no longer needed in OSS with Angular 10) will need to load from
`@npm//@angular/bazel:index.bzl`. I investigated if it was possible to maintain backward compatability for the old
load location `@npm_angular_bazel` but it is not since the package itself needs to be updated to load from
`@npm//@bazel/typescript:index.bzl` instead of `@npm_bazel_typescript//:index.bzl` as it depends on ts_library
internals for ng_module.
* runfiles.resolve will now throw instead of returning undefined to match behavior of node require
Other changes in angular/angular:
* integration/bazel has been updated to use both ng_module and ts_libary with use_angular_plugin=true.
The latter is the recommended way for rules_nodejs users to compile Angular 10 with Ivy. Bazel + Angular ViewEngine is
supported with @angular/bazel <= 9.0.5 and Angular <= 8. There is still Angular ViewEngine example on rules_nodejs
https://github.com/bazelbuild/rules_nodejs/tree/stable/examples/angular_view_engine on these older versions but users
that want to update to Angular 10 and are on Bazel must switch to Ivy and at that point ts_library with
use_angular_plugin=true is more performant that ng_module. Angular example in rules_nodejs is configured this way
as well: https://github.com/bazelbuild/rules_nodejs/tree/stable/examples/angular. As an aside, we also have an
example of building Angular 10 with architect() rule directly instead of using ts_library with angular plugin:
https://github.com/bazelbuild/rules_nodejs/tree/stable/examples/angular_bazel_architect.
NB: ng_module is still required for angular/angular repository as it still builds ViewEngine & @angular/bazel
also provides the ng_package rule. ng_module can be removed in the future if ViewEngine is no longer needed in
angular repo.
* JSModuleInfo provider added to ng_module. this is for forward compat for future rules_nodejs versions.
@josephperrott, this touches `packages/bazel/src/external.bzl` which will make the sync to g3 non-trivial.
PR Close#37727
Remove @angular/platform-webworker and @angular/platform-webworker-dynamic
as they were deprecated in v8
BREAKING CHANGE: @angular/platform-webworker and @angular/platform-webworker-dynamic
have been removed as they were deprecated in v8
PR Close#38846
The function was removed by default in Bazel 0.27.
It is still accessible with the flag `--incompatible_new_actions_api`
(which is set in Google code base), but the flag will be deleted very soon.
This change should be a no-op for Bazel users. The change was tested in
Google (cl/318277076) and should be safe as well.
PR Close#38080
The `ng_module` rule supports the generation of flat module bundles. In
View Engine, information about this flat module bundle is exposed
as a Bazel provider. This is helpful as other rules like `ng_package`
could rely on this information to determine entry-points for the APF.
With Ivy this currently does not work because the flat module
information is not exposed in the provider. The reason for this is
unclear. We should also provide this information in Ivy so that rules
like `ng_package` can also determine the correct entry-points when a
package is built specifically with `--config=ivy`.
PR Close#36971
It looks like there is a leftover golden in the `ng_package`
tests that is no longer used anywhere and does not reflect
the latest Angular Package Format v10 changes. We should be
able to remove it to keep our codebase healthy.
PR Close#37623
Refactors the `ng_rollup_bundle` rule to a macro that relies on
the `@bazel/rollup` package. This means that the rule no longer
deals with custom ESM5 flavour output, but rather only builds
prodmode ES2015 output. This matches the common build output
in Angular projects, and optimizations done in CLI where
ES2015 is the default optimization input.
The motiviation for this change is:
* Not duplicating rollup Bazel rules. Instead leveraging the official
rollup rule.
* Not dealing with a third TS output flavor in Bazel.The ESM5 flavour has the
potential of slowing down local development (as it requires compilation replaying)
* Updating the rule to be aligned with current CLI optimizations.
This also _fixes_ a bug that surfaced in the old rollup bundle rule.
Code that is unused, is not removed properly. The new rule fixes this by
setting the `toplevel` flag. This instructs terser to remove unused
definitions at top-level. This matches the optimization applied in CLI
projects. Notably the CLI doesn't need this flag, as code is always
wrapped by Webpack. Hence, the unused code eliding runs by default.
PR Close#37623
Adds the `LinkablePackageInfo` to the `ng_module` rule. This allows
the linker to properly link `ng_module` targets in Node runtime
actions. Currently this does not work properly and packages like
`@angular/core` are not linked, so we cannot rely on the linker.
9a5de3728b/internal/linker/link_node_modules.bzl (L144-L146).
PR Close#37623
As of Angular Package Format v10, we no longer ship a `fesm5` and
`fesm5` output in packages. We made this change to the `ng_package`
rule but intentionally did not clean up related build actions.
This follow-up commit cleans this up by:
* No longer building fesm5 bundles, or providing esm2015 output.
* No longer requesting and building a third flavor for ESM5. We can
use TSC to downlevel ES2015 sources/prodmode output similarly to how it
is done in `ng-packagr`.
The third output flavor (ESM5) resulted in a build slow-down as we
required a full recompilation of sources. Now, we only have a single
compilation for prodmode output, and then downlevel it on-demand
to ES5 for the UMD bundles. Here is timing for building the release
packages in `angular/angular` before this change, and afterwards:
* Before: 462.157s = ~7.7min
* After: 339.703s = ~5.6min
This signifies a time reduction by 27% when running
`./scripts/build/build-packages-dist.sh`.
PR Close#37623
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.
This is a change in anticipation of an update to the general
Typescript build rules to consume this data.
PR Close#36262
This feature is aimed at development tooling that has to translate
production build inputs into their devmode equivalent. The current
process involves guessing the devmode filename based on string
replace patterns. This allows consuming build actions to read the
known mappings instead.
This is a change in anticipation of an update to the general
Typescript build rules to consume this data.
PR Close#36262
This checks for a Bazel flag in `ng_module()` in the `_renderer` attribute
which specifies the renderer to use for the build.
The main advantage of this flag is that it can be overridden with [Bazel
transitions](https://docs.bazel.build/versions/master/skylark/config.html),
giving much more flexibility for migrating individual applications in a
Bazel workspace to Ivy.
This flag is not intended to replace `--config ivy` or
`--define angular_ivy_enabled=True` (although it technically could). As a
result, this flag is not and will not actually be used anywhere in the
`angular/angular` repo. Instead, a `string_flag()` is provided internally
which sets the renderer via a transition. See http://cl/315749946.
Note that this does **not** introduce a dependency on Skylib for
`angular/angular`. The dependency isn't actually necessary because
`BuildSettingInfo` is not used externally anyways. By doing this, it is not
necessary for downstream, external workspaces to depend on Skylib.
PR Close#37529
Close#35157
In the current version of zone.js, zone.js uses it's own package format, and it is not following the rule
of Angualr package format(APF), so it is not easily to be consumed by Angular CLI or other bundle tools.
For example, zone.js npm package has two bundles,
1. zone.js/dist/zone.js, this is a `es5` bundle.
2. zone.js/dist/zone-evergreen.js, this is a `es2015` bundle.
And Angular CLI has to add some hard-coding code to handle this case, o5376a8b139/packages/schematics/angular/application/files/src/polyfills.ts.template (L55-L58)
This PR upgrade zone.js npm package format to follow APF rule, https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/edit#heading=h.k0mh3o8u5hx
The updated points are:
1. in package.json, update all bundle related properties
```
"main": "./bundles/zone.umd.js",
"module": "./fesm2015/zone.js",
"es2015": "./fesm2015/zone.js",
"fesm2015": "./fesm2015/zone.js",
```
2. re-organize dist folder, for example for `zone.js` bundle, now we have
```
dist/
bundles/
zone.js // this is the es5 bundle
fesm2015/
zone.js // this is the es2015 bundle (in the old version is `zone-evergreen.js`)
```
3. have several sub-packages.
1. `zone-testing`, provide zone-testing bundles include zone.js and testing libraries
2. `zone-node`, provide zone.js implemention for NodeJS
3. `zone-mix`, provide zone.js patches for both Browser and NodeJS
All those sub-packages will have their own `package.json` and the bundle will reference `bundles(es5)` and `fesm2015(es2015)`.
4. keep backward compatibility, still keep the `zone.js/dist` folder, and all bundles will be redirected to `zone.js/bundles` or `zone.js/fesm2015` folders.
PR Close#36540
In v7 of Angular we removed `tsickle` from the default `ngc` pipeline.
This had the negative potential of breaking ES2015 output and SSR due
to a limitation in TypeScript.
TypeScript by default preserves type information for decorated constructor
parameters when `emitDecoratorMetadata` is enabled. For example,
consider this snippet below:
```
@Directive()
export class MyDirective {
constructor(button: MyButton) {}
}
export class MyButton {}
```
TypeScript would generate metadata for the `MyDirective` class it has
a decorator applied. This metadata would be needed in JIT mode, or
for libraries that provide `MyDirective` through NPM. The metadata would
look as followed:
```
let MyDirective = class MyDir {}
MyDirective = __decorate([
Directive(),
__metadata("design:paramtypes", [MyButton]),
], MyDirective);
let MyButton = class MyButton {}
```
Notice that TypeScript generated calls to `__decorate` and
`__metadata`. These calls are needed so that the Angular compiler
is able to determine whether `MyDirective` is actually an directive,
and what types are needed for dependency injection.
The limitation surfaces in this concrete example because `MyButton`
is declared after the `__metadata(..)` call, while `__metadata`
actually directly references `MyButton`. This is illegal though because
`MyButton` has not been declared at this point. This is due to the
so-called temporal dead zone in JavaScript. Errors like followed will
be reported at runtime when such file/code evaluates:
```
Uncaught ReferenceError: Cannot access 'MyButton' before initialization
```
As noted, this is a TypeScript limitation because ideally TypeScript
shouldn't evaluate `__metadata`/reference `MyButton` immediately.
Instead, it should defer the reference until `MyButton` is actually
declared. This limitation will not be fixed by the TypeScript team
though because it's a limitation as per current design and they will
only revisit this once the tc39 decorator proposal is finalized
(currently stage-2 at time of writing).
Given this wontfix on the TypeScript side, and our heavy reliance on
this metadata in libraries (and for JIT mode), we intend to fix this
from within the Angular compiler by downleveling decorators to static
properties that don't need to evaluate directly. For example:
```
MyDirective.ctorParameters = () => [MyButton];
```
With this snippet above, `MyButton` is not referenced directly. Only
lazily when the Angular runtime needs it. This mitigates the temporal
dead zone issue caused by a limitation in TypeScript's decorator
metadata output. See: https://github.com/microsoft/TypeScript/issues/27519.
In the past (as noted; before version 7), the Angular compiler by
default used tsickle that already performed this transformation. We
moved the transformation to the CLI for JIT and `ng-packager`, but now
we realize that we can move this all to a single place in the compiler
so that standalone ngc consumers can benefit too, and that we can
disable tsickle in our Bazel `ngc-wrapped` pipeline (that currently
still relies on tsickle to perform this decorator processing).
This transformation also has another positive side-effect of making
Angular application/library code more compatible with server-side
rendering. In principle, TypeScript would also preserve type information
for decorated class members (similar to how it did that for constructor
parameters) at runtime. This becomes an issue when your application
relies on native DOM globals for decorated class member types. e.g.
```
@Input() panelElement: HTMLElement;
```
Your application code would then reference `HTMLElement` directly
whenever the source file is loaded in NodeJS for SSR. `HTMLElement`
does not exist on the server though, so that will become an invalid
reference. One could work around this by providing global mocks for
these DOM symbols, but that doesn't match up with other places where
dependency injection is used for mocking DOM/browser specific symbols.
More context in this issue: #30586. The TL;DR here is that the Angular
compiler does not care about types for these class members, so it won't
ever reference `HTMLElement` at runtime.
Fixes#30106. Fixes#30586. Fixes#30141.
Resolves FW-2196. Resolves FW-2199.
PR Close#37382
Due to an outage with the proxy we rely on for publishing, we need
to temporarily directly publish to NPM using our own angular
credentials again.
PR Close#37378
In #37221 we disabled tsickle passes from transforming the tsc output that is used to publish all
Angular framework and components packages (@angular/*).
This change however revealed a bug in the ngc that caused __decorate and __metadata calls to still
be emitted in the JS code even though we don't depend on them.
Additionally it was these calls that caused code in @angular/material packages to fail at runtime
due to circular dependency in the emitted decorator code documeted as
https://github.com/microsoft/TypeScript/issues/27519.
This change partially rolls back #37221 by reenabling the decorator to static fields (static
properties) downleveling.
This is just a temporary workaround while we are also fixing root cause in `ngc` - tracked as
FW-2199.
Resolves FW-2198.
Related to FW-2196
PR Close#37317
This commit adds a link to the Bazel prototype for orchestrating
multiple CLI architects and also adds a link to the #angular channel in
the Bazel Slack workspace.
PR Close#37190
This commit removes the integration test for schematics in
`@angular/bazel` that is used to generate a Bazel builder. The Bazel
builder has been deprecated.
PR Close#37190
As of TypeScript 3.9, the tsc emit is not compatible with Closure
Compiler due to
https://github.com/microsoft/TypeScript/pull/32011.
There is some hope that this will be fixed by a solution like the one
proposed in
https://github.com/microsoft/TypeScript/issues/38374 but currently it's
unclear if / when that will
happen.
Since the Closure support has been somewhat already broken, and the
tsickle pass has been a source
of headaches for some time for Angular packages, we are removing it for
now while we rethink our
strategy to make Angular Closure compatible outside of Google.
This change has no effect on our Closure compatibility within Google
which work well because all the
code is compiled from sources and passed through tsickle.
This change only disables the tsickle pass but doesn't remove it.
A follow up PR should either remove all the traces of tscikle or
re-enable the fixed version.
BREAKING CHANGE: Angular npm packages no longer contain jsdoc comments
to support Closure Compiler's advanced optimizations
The support for Closure compiler in Angular packages has been
experimental and broken for quite some
time.
As of TS3.9 Closure is unusable with the JavaScript emit. Please follow
https://github.com/microsoft/TypeScript/issues/38374 for more
information and updates.
If you used Closure compiler with Angular in the past, you will likely
be better off consuming
Angular packages built from sources directly rather than consuming the
version we publish on npm
which is primarily optimized for Webpack/Rollup + Terser build pipeline.
As a temporary workaround you might consider using your current build
pipeline with Closure flag
`--compilation_level=SIMPLE`. This flag will ensure that your build
pipeline produces buildable and
runnable artifacts, at the cost of increased payload size due to
advanced optimizations being disabled.
If you were affected by this change, please help us understand your
needs by leaving a comment on https://github.com/angular/angular/issues/37234.
PR Close#37221
Tslib version is bound to the TypeScript version used to compile the library. Thus, we shouldn't list `tslib` as a `peerDependencies`. This is because, a user can install libraries which have been compiled with older versions of TypeScript and thus require multiple `tslib` versions to be installed.
Reference: TOOL-1374 and TOOL-1375
Closes: #37188
PR Close#37198
With this change we drop support for TypeScript 3.8 and remove all related tests.
BREAKING CHANGE:
TypeScript 3.8 is no longer supported, please update to TypeScript 3.9.
PR Close#37129
Since we no longer hardcode the `package.json` for
entry-points, a bug has appeared for `ng_package` in Ivy.
The `package.json` files are populated incorrectly with Ivy
as the flat module bundle name is not propagated from `ng_module`
to the `ng_package` rule. The rule then guesses the index file
to `index.js` and does not respect the flat module bundle shim.
PR Close#36944
In the past we added support for `ts_library` to `ng_package`. For those
targets we never can determine the "index" file. Unlike `ng_module`,
there is no provider data for flat module bundles, so the `ng_package`
rule assumes that the index file is simply called `index`.
This works as expected, but we also added logic in the past that doesn't
allow `ng_package` to add format properties (e.g. `main`, `module`) to a
`package.json` if a package json is handwritten for such a `ts_library` target.
This has been done that way because we assumed that such `package.json` files
might want to set format properties explicitly to different paths due to a
faulty "index" guess.
We want to change this behavior as most of the time a `package.json`
file already exists with just the module name. In those cases, the
packager should still set the format properties. We should only warn
and skip automatic insertion of the format properties if such a
`package.json` explicitly sets format properties.
PR Close#36944
esm5 and fesm5 are no longer needed and have been deprecated in the past.
https://v9.angular.io/guide/deprecations#esm5-and-fesm5-code-formats-in-angular-npm-packages
This commit modifies ng_package to no longer distribute these two formats in npm packages
built by ng_package (e.g. @angular/core).
This commit intentionally doesn't fully clean up the ng_package rule to remove all traces of esm5 and fems5
build artifacts as that is a bigger cleanup and currently we are narrowing down the scope of this change
to the MVP needed for v10, which in this case is 'do not put esm5 and fesm5' into the npm packages.
More cleanup to follow: https://angular-team.atlassian.net/browse/FW-2143
BREAKING CHANGE: esm5 and fesm5 format is no longer distributed in
Angular's npm packages e.g. @angular/core
If you are not using Angular CLI to build your application or library,
and you need to be able to build es5 artifacts, then you will need to
downlevel the distributed Angular code to es5 on your own.
Angular CLI will automatically downlevel the code to es5 if differential
loading is enabled in the Angular project, so no action is required from
Angular CLI users.
PR Close#36944
The legacy HTTP package was deprecated in v5 with the launch of
@angular/common/http. The legacy package hasn't been published
since v7, and will therefore not include a migration.
PR Close#27038
Remove TypeScript 3.6 and 3.7 support from Angular along with tests that
ensure those TS versions work.
BREAKING CHANGE: typescript 3.6 and 3.7 are no longer supported, please
update to typescript 3.8
PR Close#36329
Rebuild the yarn lock file from scratch to collapse instances where
one package is able to satisfy multiple dependencies. Currently we
have some situations where we have multiple versions when one would
work.
Example:
```
"@babel/code-frame@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/cod
integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/code-frame@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/cod
integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQ
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/code-frame@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/cod
integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0j
dependencies:
"@babel/highlight" "^7.8.3"
```
becomes
```
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/cod
integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0j
dependencies:
"@babel/highlight" "^7.8.3"
```
PR Close#36377
Currently, when Angular code is built with Bazel and with Ivy, generated
factory shims (.ngfactory files) are not processed via the majority of
tsickle's transforms. This is a subtle effect of the build infrastructure,
but it boils down to a TsickleHost method `shouldSkipTsickleProcessing`.
For ngc_wrapped builds (Bazel + Angular), this method is defined in the
`@bazel/typescript` (aka bazel rules_typescript) implementation of
`CompilerHost`. The default behavior is to skip tsickle processing for files
which are not present in the original `srcs[]` of the build rule. In
Angular's case, this includes all generated shim files.
For View Engine factories this is probably desirable as they're quite
complex and they've never been tested with tsickle. Ivy factories however
are smaller and very straightforward, and it makes sense to treat them like
any other output.
This commit adjusts two independent implementations of
`shouldSkipTsickleProcessing` to enable transformation of Ivy shims:
* in `@angular/bazel` aka ngc_wrapped, the upstream `@bazel/typescript`
`CompilerHost` is patched to treat .ngfactory files the same as their
original source file, with respect to tsickle processing.
It is currently not possible to test this change as we don't have any test
that inspects tsickle output with bazel. It will be extensively tested in
g3.
* in `ngc`, Angular's own implementation is adjusted to allow for the
processing of shims when compiling with Ivy. This enables a unit test to
be written to validate the correct behavior of tsickle when given a host
that's appropriately configured to process factory shims.
For ngtsc-as-a-plugin, a similar fix will need to be submitted upstream in
tsc_wrapped.
PR Close#35848
PR Close#35975
Updates to the latest `@bazel/ibazel` version that properly
resolves local `@bazel/bazelisk` installations.
The support for this temporarily broke from `0.12.0` to `0.12.2`.
https://github.com/bazelbuild/bazel-watcher/issues/352.
PR Close#36097
This has a couple benefits:
- we now use a .bazelversion file rather than package.json to pin the version of bazel we want. This means even if you install bazel on your computer rather than via yarn, you'll still get a warning if your bazel version is wrong.
- you no longer end up downloading three copies of bazel due to bugs in both npm and yarn where they download all tarballs before checking the metadata to see which are usable on the local platform.
- bazelisk correctly handles the tools/bazel trick for wrapping functionality, which we want to use to instrument developer build latencies
PR Close#36078