The APF v13 `ng_package` rule will generate the `exports` field if not
set. Currently it allows for additional subpath entries to be configured
manually. The packager does not allow for custom conditions in subpath
exports which are auto-generated.
This is sometimes useful and necessary though. e.g. in Angular Material,
we also need to expose the index Sass file through a `sass` conditional
that the Webpack Sass loader will pick up. For this, the packager needs
to support manual additional conditions (as long as they do not
conflict).
PR Close#43764
In addition to the existing `exports` conditional exports we ship
as part of APF v13, we want to expose the non-bundled ESM2020 output
through the `esm2020` conditional name. Additionally we will expose
the flat ES2020 files through the `es2020` conditional field, allowing
consumers (like the CLI) to prioritize certain formats.
e.g. consider the case with RXJS where it currently defaults to
the ESM5 output. The CLI could now set `es2015` as the conditional
to leverage the ES2015 output of RXJS. This unveils a problem though
since this would also mean that `ES2015` output of the framework Angular
packages would be used instead of the available ES2020 output. Here is
the additional `es2020` conditional helpful as it allows the CLI to
prioritize `es2020`, fallback to `es2015` and lastly fallback to `default`.
if none do match for a certain package.
PR Close#43740
Currently when `ngc-wrapped` runs in external/consumer workspaces, like
in the Angular Components project, the `ngc-wrapped` binary relies on
the linker due to the patched module resolution in `rules_nodejs` no
longer being default. The reliance on the linker of `rules_nodejs` is
problematic for workers as the required `node_modules` are not
re-linked for every build. This was previously not an issue before the
APF v13 changes because the `compiler-cli` module was loaded only once
through an import statement.
As of APF v13, the compiler-cli module is loaded dynamically for every
build. This dynamic import can then break as the worker does not
initially load the compiler-cli module when becoming online. Instead,
the module is loaded on the first build where the node modules might not
be linked properly anymore (due to e.g. other targets running at the same time).
We fix thi issue by doing the following things:
1. Enabling the patched module resolution for consumer/external
workspaces. This would match how we use ngc-wrapped inside FW as
well.
2. Caching the compiler CLI module. Instead of re-fetching the module
through dynamic imports for every build (in a worker), we should use
the cached version. This is semantically the same as with APF v12
where a single import statement at file top-level was used.
Technically, NodeJS should cache the module, but it doesn't hurt
directly caching it as the module resolution will be patched by
`rules_nodejs` and could perform unnecessary tasks.
PR Close#43690
In the current Bazel setup, we run CommonJS as devmode output, and ESM
for prodmode output. This means that consumers of the
`@angular/bazel` package will end up using the prodmode-built ESM
package of the compiler-cli. This commit adds interop logic to be able
to load the compiler-cli as strict ESM package.
We cannot switch devmode to ESM, as this would require some changes
in `rules_nodejs` and potentially the reduction of both output flavors
into a single one (which is a future project anyway). This is out of
scope for now and inside g3, there is still devmode output as well.
PR Close#43431
As outlined in the previous commit which enabled the `esModuleInterop`
TypeScript compiler option, we need to update all namespace imports
for `typescript` to default imports. This is needed to allow for
TypeScript to be imported at runtime from an ES module.
Similar changes are needed for modules like `semver` where the types incorrectly
suggest named exports that will not exist at runtime when imported from ESM.
This commit refactors all imports to match with the lint rule we have
configured in the previous commit. See the previous commit for more
details on why certain imports have been changed.
A special case are the imports to `@babel/core` and `@babel/types`. For
these a special interop is needed as both default imports, or named
imports break the other module format. e.g default imports would work
well for ESM, but it breaks for CJS. For CJS, the named imports would
only work, but in ESM, only the default export exist. We work around
this for now until the devmode is using ESM as well (which would be
consistent with prodmode and gives us more valuable test results). More
details on the interop can be found in the `babel_core.ts` files (two
interops are needed for both localize/or the compiler-cli).
PR Close#43431
Enables the `esModuleInterop` for all TypeScript compilations in the
project. This allows us to emit proper ESM-compatible code. e.g.
consider the following import:
```ts
import * as ts from 'typescript';
```
This import currently will break at runtime in NodeJS because the
`typescript` package is not shipping ESM. It's still a CommonJS module.
ES modules are able to import from `typescript` though, using an import
statement as above, but everything in `module.exports` is being exposed
as the `default` named export. TypeScript at runtime does not have any
other named exports, so for actual ESM compatibility, all of our imports
need to be switched to:
```
import ts from 'typescript';
```
The `esModuleInterop` option allows this to work even though the
`d.ts` file of TS currently suggests that there are _only_ named exports.
The TypeScript language service will now suggest the correct import form as
shown above. It doesn't enforce that unfortunately, but this commit also
adds a lint rule that enforces certain patterns so that we emit imports
that are compatible with both ESM and CJS output (CJS still needed here
since tests run with CJS devmode output still; this is a future project
to switch that over to ESM!)
PR Close#43431
The Angular Core and localize package currently use deep imports for
code that is shipped. This is problematic as we want to ship the
compiler-cli as full-ESM. To achieve this we need to use a bundler and
this breaks deep imports.
We use a bundler for the compiler CLI because for full ESM
compatibility, we would need to explicitly add the `.js` extension
to all relative imports. This is very cumbersome and prone to mistakes
so to mitigate this problem in a safe way, we bundle the compiler-cli.
Note: Deep imports continue to exist for the language service as it
bundles the compiler-cli.
PR Close#43431
This commit implements partial compilation APF v13 for the
`ng_package` rule. The changes involve the following things:
1. Requesting the partial compilation output for all targets (and
its transitives) in the `deps` or `srcs` attributes.
2. Downleveling of ES2020 prodmode output to a FESM2015 file.
3. Cleanup of file resolution. Previusly, execroot file paths (which are
passed to the packager tool) were composed manually. This is prone to
mistakes and breaks with transitions.
A lot of this code can be simplified by passing the necessary Bazel
`File` information as JSON. This also simplifies the packager tool
significantly (and makes it more readable..)
4. Remoal of UMD bundles. This also allows us remove the `globals` rule
attribute with `externals` (we do not need any UMD global identifier
names anymore).
5. The `package.json` will set the `exports` field and use subpath
exports to make module resolution work for ESM consumers.
6. TSLib is also always set as `external` now. Previously it had to be
added as `dep` to the `ng_package` rule as UMD files bundled `tslib`.
7. The `include_devmode_srcs` option has been removed. This option was
an addition to APF that allowed the `@angular/compiler` to ship
non-flattened ES5 CommonJS sources. We want to keep APF consistent
and not allow such exceptions. Compiler is now a strict APF package
as well, and the compiler-cli just needs to go through the primary
entry-point for things it needs (or it bundles the necessary parts
into the CLI.)
Overall, these are all changes. A lot of changes to make the packager
rule and tool more readable and Bazel-idiomatic were made as well. This
allows us to easier make packaging changes in the future, and it's more
future-proof if we ever change how inputs (like `ng_module` targets) are
generated (e.g. consider a case where we'd use the `ts_project` rule).
PR Close#43431
We should no longer generate VE shims for workspaces which are not named
`angular`. The default is Ivy compilation and this should be opt-in. The
components repository for example does not need any shims as it is using
Ivy for the common development workflows.
PR Close#43431
Previously, the prodmode output was using ES2015 for `ng_module` and
`ts_library` targets. This commit changes it to `ES2020`. This is
necessary as we want to ship es2020 output in APF v13.
PR Close#43431
In preparation for using the partial compilation transition on the
packager, we need to be able to have a reference to the flat module
out file (that is used as "index" file for entry-point ng_module targets).
We need a reference to the file because with transitions applied, the
inputs are not necessarily in the default `bazel-out` directory. The
packager currently only guesses such paths (this worked most of the
time) but guessing the output directory with transitions will become
impossible.. so the paths need to be computed in a Bazel-idiomatic way.
This is more future-proof and correct (and more clean IMO).
PR Close#43431
Removes the `compilation_mode` attribute for the `ng_module` rule. We
remove the attribute since we intend to control the compilation mode
through the partial compilation build setting we have added before.
Note: We could have named the build setting more generically, something
like `ng_compilation_mode`, but I think it's more readable only assuming
there is `partial` compilation, or `full`. We can always change this in
the future as it is not part of the public API.
PR Close#43431
Previously, `ng_module` generated a second `d.ts` bundle in case the
built target was the Angular core target. This was done so that the
packager later on can ship the `r3_symbols.d.ts` file along with the
APF v13 output. Ngcc relied on this file when it processed the Angular
core package. This is no longer needed for Angular Core v13 since it
will come as partially-compiled without the need for ngcc.
The major benefit of no longer generating multiple dts files here is
that we can reasonably pass the bundle through a provider to the packager
which can then use this for determining the `d.ts` file it should link
in the `package.json`.
This is beneficial and needed for using a transition since the packager
input files are no longer in the default `bazel-out`, so it's important
to keep an reference to the actual Bazel `<File>` instance, allowing
us to determine the path properly in the packager (without any
assumptions on the `bazel-out` path..).
PR Close#43431
We created a build setting (bool flag) for controlling whether partial
compilation should be enabled or not. This commit wires up the build
setting so that all `ng_module` targets respect the flag.
This will later be useful when we apply the transition (which always
sets the partial compilation flag to `True`).
PR Close#43431
Moves the `ng_module.bzl` file into a sub-directory called `ng_module`.
This is consistent with other rules in the package. And it also allows
us to ship the `ng_module.bzl` code next to other tightly-coupled files
like the partial compilation transition/flag.
PR Close#43431
Creates, a currently still unused, Bazel transition that will control
a build setting that is enabling the partial compilation mode for
`ng_module` rule targets. This is in preparation of implementing the
Angular Package Format v13 (which should ship in partial compilation).
Note: Various other approaches aside from the `transition` has been
considered. Here is a small summary of the largest ideas that have
been tried for the APF v13 partial compilation refactor.
**Using an aspect for partial compilation in `ng_package`**
Similar to how we had an aspect for ESM5 compilation in the past,
an aspect could be used to create partial compilation prodmode output
for packaging. The aspect would take the existing prodmode compilation
details and "replay" the compilation with a modified tsconfig that
enables partial compilation.
This _can_ work but requires lots of caution and is very prone to
issues. In order to avoid conflicts with the existing prodmode output,
the partial compilation outputs would need to be written to a
sub-directory. This makes module resolution extremely difficult when
`ng_package` creates the FESM bundles. Also it is difficult to merge
multiple of these aspect-compiled folders into a single one for exposing
the non-bundled ESM output. It becomes especially difficult to ensure
that such an aspect target will actually use the _correct_ dependency
type definition when compiled.
e.g. consider a case where a partial compiled target relies on another
Angular target. The dependency will be compiled partially first, but
the other target _needs_ to rely on the partial compilation `d.ts`
output of the dependency (and *NOT* the devmode `.d.ts` output). This
is incorrect and can cause other type-checking issues / or invalid
output. To make this work, the module resolution when invoking
tsc_wrapped would also need to be updated/patched. This is out of scope
and not reasonable to maintain.
**Exposing a third output flavor directly in the rule**
Instead of replying a compilation, we could expose an output flavor
next to `devmode` and `prodmode`. This sounded like the easiest
solution at first, but it will have the same problems as the aspect
approach (in terms of module resoltion and avoiding conflicts of files).
We cannot control how TS emits `.d.ts` or `.js` files (without patching
into the compiler host), so we would need to store the compilation
output in a sub-folder similar to the aspect.. resulting in the same
issues. This is do-able but would require module resolution to be
patched and we do not have control over `@bazel/typescript`. Also,
`@bazel/typescript` does not forsee a third output flavor, so that
logic would need to be changed significantly as well.
PR Close#43431
Removes the unused `modify_tsconfig.js` file located in the
`@angular/bazel` package. This file existed in the past for the
ESM5 compilation aspect relying on the TS compilation to be replayed.
We just forgot removing the file and associated `nodejs_binary`.
PR Close#43431
Updates the API extractor tool used by the `ng_module` rule to only
accept a single entry-point file. This change is made in preparation
for APF v13 where this logic is no longer needed.
The logic previously only existed to also bundle the `r3_symbols` file.
This file is no longer needed in APF v13 because Angular core no longer needs
to be processed with `ngcc`. This allows us to clean up this logic which
helps simplifying `ng_module`.
Consumers that use an older version of `@angular/core` should
respectively also use a compiler-cli version matching the core
version.
PR Close#43431
Refs #42966.
Previously if _any_ diagnostics were emitted, regardless of their category, the manifest would not be generated. This means that if a target emits only warnings and no errors, it would still fail to build because it does not generate all the required output files (specifically the `.es5.MF` file). Now the manifest file is generated as long as there are no error diagnostics in the result. This makes `ng_module()` support compiler warnings as a user would expect.
Added a test which uses extended template diagnostics to trigger the invalid banana in box diagnostic. This generates a warning and uses Skylib's `build_test()` to verify that it builds successfully. Unfortunately there is no easy way to verify that the warning diagnostic is emitted at all. `expected_diagnostics` should be able to do that, but it doesn't seem to have any effect on `ng_module()` and may not be integrated. Instead, testing that a target with warnings builds correctly is the best we can easily do here without a deeper investigation.
PR Close#43582
Refs #42966.
Fixes#33452.
This allows `ng_module()` targets to be built with strict templates enabled, it mostly works the way we already do this internally. Also adds extended template diagnostics behind an experimental option so it can be used internally and for tests.
`strict_templates` can only be used if `type_check` is also enabled and `experimental_extended_template_diagnostics` can only be used if `strict_templates` is enabled.
PR Close#43582
This commit extracts the patching operation that adds `fileNameToModuleName`
to the Angular compiler's `ts.CompilerHost` into a separate function, so
that it can be invoked in other compilation flows besides the one outlined
in `ngc-wrapped`. This is primarily needed for the xi18n operation in g3.
PR Close#42974
This commit applies changes to `@angular/bazel` which are necessary
to support the Bazel NodeJS rules v4.0.0. The Bazel NodeJS rules
no longer support the `_tslibrary` option for the `LinkablePackageInfo`
provider and therefore we need to stop using it. Due to this removal,
we also need to add two new attributes called `package_name` and
`package_path` so that the API of `ng_module` matches `ts_library`.
Note: This is denoted as `refactor` as we currently are not able to
merge feature commits into patch branches, but we want the tooling
to not diverge significantly between the patch and next branch. It is
planned to update the merge tooling to allow for such changes to land.
PR Close#42760
Skydoc is no longer used as `@angular/bazel` is no longer a
public API. The Sass rules were only used in a single place
in the repo where Sass is not really needed and has just been
added by accident most likely. We want to remove the Sass dependency
in preparation for Rules NodeJS v4.x where the Sass rules currently
still use an older version of `@bazel/worker` that is incompatible.
PR Close#42760
In version 12, applications will only be allowed to be built in Ivy, this makes the minified UMDs redundant since they cannot be processed by NGCC.
With this change, we remove the minified UMDs from the generated APF package.
BREAKING CHANGE: Minified UMD bundles are no longer included in the distributed NPM packages.
PR Close#41425
Adds a new attribute to the `ng_module` rule that allows users to
set the Angular compiler `compilationMode` flag. An alternative
would have been to just enable the option in the user-specified
tsconfig. Though that is more inconvenient if a Bazel workspace
wants to change the compilation mode conditionally at anaylsis
phase through build settings.
Related to: https://github.com/angular/components/pull/22351t
PR Close#41366
A previous commit implemented a streamlined performance metric reporting
system for the compiler-cli, controlled via the compiler option
`tracePerformance`.
This commit adds a custom Bazel flag rule //packages/compiler-cli:ng_perf
to the repository, and wires it through to the `ng_module` implementation
such that if the flag is set, `ng_module` will produce perf results as part
of the build. The underlying mechanism of `//:ng_perf` is not exported from
`@angular/bazel` as a public rule that consumers can use, so there is little
risk of accidental dependency on the contents of these perf traces.
An alias is added so that `--ng_perf` is a Bazel flag which works in our
repository.
PR Close#41125
ngtsc has an internal performance tracing package, which previously has not
really seen much use. It used to track performance statistics on a very
granular basis (microseconds per actual class analysis, for example). This
had two problems:
* it produced voluminous amounts of data, complicating the analysis of such
results and providing dubious value.
* it added nontrivial overhead to compilation when used (which also affected
the very performance of the operations being measured).
This commit replaces the old system with a streamlined performance tracing
setup which is lightweight and designed to be always-on. The new system
tracks 3 metrics:
* time taken by various phases and operations within the compiler
* events (counters) which measure the shape and size of the compilation
* memory usage measured at various points of the compilation process
If the compiler option `tracePerformance` is set, the compiler will
serialize these metrics to a JSON file at that location after compilation is
complete.
PR Close#41125
`@angular/platform-server` provides the foundation for rendering an
Angular app on the server. In order to achieve that, it uses a
server-side DOM implementation (currently [domino][1]).
For rendering on the server to work as closely as possible to running
the app on the browser, we need to make DOM globals (such as `Element`,
`HTMLElement`, etc.), which are normally provided by the browser,
available as globals on the server as well.
Currently, `@angular/platform-server` achieves this by extending the
`global` object with the DOM implementation provided by `domino`. This
assignment happens in the [setDomTypes()][2] function, which is
[called in a `PLATFORM_INITIALIZER`][3]. While this works in most cases,
there are some scenarios where the DOM globals are needed sooner (i.e.
before initializing the platform). See, for example, #24551 and #39950
for more details on such issues.
This commit provides a way to solve this problem by exposing a
side-effect-ful entry-point (`@angular/platform-server/init`), that
shims the `global` object with DOM globals. People will be able to
import this entry-point in their server-rendered apps before
bootstrapping the app (for example, in their `main.server.ts` file).
(See also [#39950 (comment)][4].)
In a future update, the [`universal` schematics][5] will include such an
import by default in newly generated projects.
[1]: https://www.npmjs.com/package/domino
[2]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/domino_adapter.ts#L17-L21
[3]: https://github.com/angular/angular/blob/0fc8466f1be392917e0c/packages/platform-server/src/server.ts#L33
[4]: https://github.com/angular/angular/issues/39950#issuecomment-747598403
[5]: https://github.com/angular/angular-cli/blob/cc51432661eb4ab4b6a3/packages/schematics/angular/universal
PR Close#40559
Updates to rules_nodejs@2.3.3 to take advantage of windows specific fixes.
rules_nodejs@2.3.3 was created as a patch specifically with a fix for
the issues we found updating to rules_nodejs@2.2.2.
PR Close#40581
Alex Eagle wrote an external article on our decision to move Bazel out of
Angular repo, and it's useful for users who want to know more about what's next.
PR Close#39507
Previously the volatile status file was always provided to the ng_rollup
action which prevented it from being cacheable remotely. This change to
only provide this file as an input when the --stamp flag is used will allow
for the action to be remotely cached and prevent needing to run the action
on every CI run.
PR Close#39392
Removes `ViewEncapsulation.Native` which has been deprecated for several major versions.
BREAKING CHANGES:
* `ViewEncapsulation.Native` has been removed. Use `ViewEncapsulation.ShadowDom` instead. Existing
usages will be updated automatically by `ng update`.
PR Close#38882
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.
PR Close#39182
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