Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: only create runfiles trees when needed #2279

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ tasks:
build_flags:
# TODO(gregmagolan): figure out how to install missing shared libs
# Without this filter the @cypress external repository will be built and that build will fail due to missing shared libs.
- "--build_tag_filters=-cypress"
- "--build_tag_filters=-cypress,-pkg_npm.pack"
test_flags:
# TODO(gregmagolan): figure out how to install missing shared libs
- "--test_arg=-cypress"
6 changes: 3 additions & 3 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}

# The number of days old an issue can be before marking it stale.
days-before-stale: 60
days-before-stale: 90
# Number of days of inactivity before a stale issue is closed
days-before-close: 14

Expand All @@ -30,14 +30,14 @@ jobs:

stale-issue-message: >
This issue has been automatically marked as stale because it has not had
any activity for 60 days.
any activity for 90 days.
It will be closed if no further activity occurs in two weeks.
Collaborators can add a "cleanup" or "need: discussion" label to keep it open indefinitely.
Thanks for your contributions to rules_nodejs!

stale-pr-message: >
This Pull Request has been automatically marked as stale because it has not had
any activity for 60 days.
any activity for 90 days.
It will be closed if no further activity occurs in two weeks.
Collaborators can add a "cleanup" or "need: discussion" label to keep it open indefinitely.
Thanks for your contributions to rules_nodejs!
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* **example:** remove compression dependencies ([75bf720](https://github.com/bazelbuild/rules_nodejs/commit/75bf720))
* **example:** remove index.html from prodapp srcs ([c7be89b](https://github.com/bazelbuild/rules_nodejs/commit/c7be89b))
* **example:** remove server side compression ([6d5aafb](https://github.com/bazelbuild/rules_nodejs/commit/6d5aafb))
* **exmaple:** add docstring to ngsw_config rule ([481fa21](https://github.com/bazelbuild/rules_nodejs/commit/481fa21))
* **example:** add docstring to ngsw_config rule ([481fa21](https://github.com/bazelbuild/rules_nodejs/commit/481fa21))


### Features
Expand Down
5 changes: 5 additions & 0 deletions common.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ build:debug --compilation_mode=dbg
# This prevents accidentally depending on this feature, which Bazel will remove.
build --nolegacy_external_runfiles

# Do not build runfile forests by default. If an execution strategy relies on runfile
# forests, the forest is created on-demand. See: https://github.com/bazelbuild/bazel/issues/6627
# and https://github.com/bazelbuild/bazel/commit/03246077f948f2790a83520e7dccc2625650e6df
build --nobuild_runfile_links

# Turn on --incompatible_strict_action_env which was on by default
# in Bazel 0.21.0 but turned off again in 0.22.0. Follow
# https://github.com/bazelbuild/bazel/issues/7026 for more details.
Expand Down
24 changes: 11 additions & 13 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@ This JavaScript support lets you build and test code that targets a JavaScript r

## Scope of the project

This repository contains an orthogonal set of rules which covers an opinionated toolchain for JavaScript development. When requesting a new rule, describe your use case, why it's important, and why you can't do it with the existing rules. This is because we have limited resources to maintain additional rules.
This repository contains an orthogonal set of rules which covers an opinionated toolchain for JavaScript development. If you would like to request a new rule, please open a [feature request](https://github.com/bazelbuild/rules_nodejs/issues/new), describe your use case, why it's important, and why you can't do it within the existing rules. Then the maintainers can decide if it is within the scope of the project and will have a large enough impact to warrant the time required to implement.

The repository accepts contributions in terms of bug fixes or implementing new features in existing rules. If you're planning to implement a new rule, please strongly consider opening a [feature request](https://github.com/bazelbuild/rules_nodejs/issues/new) first so the project's maintainers can decide if it belongs to the scope of this project or not.

For rules outside of the scope of the projects we recommend hosting them in your GitHub account or the one of your organization.
If you would like to write a rule outside the scope of the projects we recommend hosting them in your GitHub account or the one of your organization.

## Design

Most bazel rules include package management. That is, the `WORKSPACE` file installs your dependencies as well as the toolchain. In some environments, this is the normal workflow, for example in Java, Gradle and Maven are each both a build tool and a package manager.
Most bazel rules include package management. That is, the `WORKSPACE` file installs both your dependencies and toolchain at the same time. For example, in Java, Gradle and Maven they each install both a build tool and a packagae at the same time.

In nodejs, there are a variety of package managers and build tools which can interoperate. Also, there is a well-known package installation location (`node_modules` directory in your project). Command-line and other tools look in this directory to find packages. So we must either download packages twice (risking version skew between them) or point all tools to Bazel's `external` directory with `NODE_PATH` which would be very inconvenient.

Expand All @@ -38,10 +36,10 @@ Both NPM and Yarn have a lockfile, which ensures that dependencies only change w

References:

- npm: https://docs.npmjs.com/files/package-lock.json
- yarn: https://yarnpkg.com/lang/en/docs/yarn-lock/
- npm: <https://docs.npmjs.com/files/package-lock.json>
- yarn: <https://yarnpkg.com/lang/en/docs/yarn-lock/>

Note that https://github.com/bazelbuild/rules_nodejs/issues/1 will take the guarantee further: by using the lockfile as an input to Bazel, the nodejs rules can verify the integrity of the dependencies. This would make it impossible for a build to be non-reproducible, so long as you have the same lockfile.
Note that <https://github.com/bazelbuild/rules_nodejs/issues/1> will take the guarantee further: by using the lockfile as an input to Bazel, the nodejs rules can verify the integrity of the dependencies. This would make it impossible for a build to be non-reproducible, so long as you have the same lockfile.


## Quickstart
Expand All @@ -67,7 +65,7 @@ $ cd my_workspace

Next we install some development tools.
For this example, we'll use Babel to transpile our JavaScript, Mocha for running tests, and http-server to serve our app.
This is just an arbitrary choice, you probably already have some tools you prefer.
These are arbitrary choices, you may use whatever are your favorites.

```sh
$ npm install @babel/core @babel/cli @babel/preset-env http-server mocha domino
Expand All @@ -80,7 +78,7 @@ Let's run these tools with Bazel. There are two ways to run tools:

In this example we use the auto-generated rules.
First we need to import them, using a load statement.
So edit BUILD.bazel and add:
So edit `BUILD.bazel` and add:

```python
load("@npm//@babel/cli:index.bzl", "babel")
Expand All @@ -90,8 +88,8 @@ load("@npm//http-server:index.bzl", "http_server")

> This shows us that rules_nodejs has told Bazel that a workspace named @npm is available
> (think of the at-sign like a scoped package for Bazel).
> rules_nodejs will add index.bzl files exposing all the binaries the package manager installed
> (the same as the content of the node_modules/.bin folder).
> rules_nodejs will add `index.bzl` files exposing all the binaries the package manager installed
> (the same as the content of the `node_modules/.bin folder`).
> The three tools we installed are in this @npm scope and each has an index file with a .bzl extension.

Next we teach Bazel how to transform our JavaScript inputs into transpiled outputs.
Expand Down Expand Up @@ -150,7 +148,7 @@ Add a `serve` entry to the scripts in `package.json`:
> ibazel is the watch mode for bazel.
>
> Note that on Windows, you need to pass `--enable_runfiles` flag to Bazel.
> That's because Bazel creates a directory where inputs and outputs both appear together, for convenience.
> That's because Bazel creates a directory where inputs and outputs both conveniently appear together.

Now we can serve the app: `npm run serve`

Expand Down
14 changes: 11 additions & 3 deletions e2e/nodejs_image/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,23 @@ yarn_install(

http_archive(
name = "io_bazel_rules_docker",
sha256 = "6287241e033d247e9da5ff705dd6ef526bac39ae82f3d17de1b69f8cb313f9cd",
strip_prefix = "rules_docker-0.14.3",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.3/rules_docker-v0.14.3.tar.gz"],
sha256 = "4521794f0fba2e20f3bf15846ab5e01d5332e587e9ce81629c7f96c793bb7036",
strip_prefix = "rules_docker-0.14.4",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.4/rules_docker-v0.14.4.tar.gz"],
)

load("@io_bazel_rules_docker//repositories:repositories.bzl", container_repositories = "repositories")

container_repositories()

load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")

container_deps()

load("@io_bazel_rules_docker//repositories:pip_repositories.bzl", "pip_deps")

pip_deps()

load("@io_bazel_rules_docker//nodejs:image.bzl", nodejs_image_repositories = "repositories")

nodejs_image_repositories()
11 changes: 10 additions & 1 deletion examples/angular/.bazelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import %workspace%/../../common.bazelrc
# Use the Angular Ivy compiler
# See https://github.com/angular/angular/blob/master/docs/BAZEL.md#various-flags-used-for-tests
build --define=angular_ivy_enabled=True

import %workspace%/../../common.bazelrc

# Workaround bug (?) in rules_docker
# ERROR: /tmp/tmp-28205N6j30S9graIZ/src/BUILD.bazel:279:1:
# ImageLayer src/nodejs_image-layer.tar failed due to unexpected I/O exception:
# execroot/examples_angular/bazel-out/k8-fastbuild/bin/src/prodserver.sh.runfiles/examples_angular/src/pwa (No such file or directory)
# Maybe rules_docker just needs an upgrade?
build --build_runfile_links

27 changes: 24 additions & 3 deletions examples/angular/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ workspace(
# These rules are built-into Bazel but we need to load them first to download more rules
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "bazel_skylib",
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
)

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")

bazel_skylib_workspace()

# Fetch rules_nodejs so we can install our npm dependencies
http_archive(
name = "build_bazel_rules_nodejs",
Expand Down Expand Up @@ -88,15 +101,23 @@ http_archive(

http_archive(
name = "io_bazel_rules_docker",
sha256 = "6287241e033d247e9da5ff705dd6ef526bac39ae82f3d17de1b69f8cb313f9cd",
strip_prefix = "rules_docker-0.14.3",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.3/rules_docker-v0.14.3.tar.gz"],
sha256 = "4521794f0fba2e20f3bf15846ab5e01d5332e587e9ce81629c7f96c793bb7036",
strip_prefix = "rules_docker-0.14.4",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.4/rules_docker-v0.14.4.tar.gz"],
)

load("@io_bazel_rules_docker//repositories:repositories.bzl", container_repositories = "repositories")

container_repositories()

load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")

container_deps()

load("@io_bazel_rules_docker//repositories:pip_repositories.bzl", "pip_deps")

pip_deps()

load("@io_bazel_rules_docker//nodejs:image.bzl", nodejs_image_repos = "repositories")

nodejs_image_repos()
Expand Down
2 changes: 1 addition & 1 deletion examples/angular_bazel_architect/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ There are a few ways to use Angular with Bazel. See https://bazelbuild.github.io
This example showcases building and testing a project with the Angular CLI.
Instead of using the Angular CLI directly we use Architect here, which is the lower level api for the Angular CLI.

This requies one patch, which can be found under ./patches.
This requires one patch, which can be found under [./patches](./patches).
This patch adjusts how the architect-cli prints stdio so that when running under Bazel you don't lose your logs.
14 changes: 11 additions & 3 deletions examples/nestjs/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ yarn_install(

http_archive(
name = "io_bazel_rules_docker",
sha256 = "6287241e033d247e9da5ff705dd6ef526bac39ae82f3d17de1b69f8cb313f9cd",
strip_prefix = "rules_docker-0.14.3",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.3/rules_docker-v0.14.3.tar.gz"],
sha256 = "4521794f0fba2e20f3bf15846ab5e01d5332e587e9ce81629c7f96c793bb7036",
strip_prefix = "rules_docker-0.14.4",
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.14.4/rules_docker-v0.14.4.tar.gz"],
)

load(
Expand All @@ -47,6 +47,14 @@ load(

container_repositories()

load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")

container_deps()

load("@io_bazel_rules_docker//repositories:pip_repositories.bzl", "pip_deps")

pip_deps()

load(
"@io_bazel_rules_docker//nodejs:image.bzl",
nodejs_image_repositories = "repositories",
Expand Down
3 changes: 2 additions & 1 deletion examples/nestjs/src/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ ts_library(
["*.ts"],
exclude = ["*.spec.ts"],
),
module_name = "examples_nestjs",
deps = [
"@npm//@nestjs/common",
"@npm//@nestjs/core",
Expand Down Expand Up @@ -59,7 +60,7 @@ nodejs_binary(
"@npm//@nestjs/core",
"@npm//minimist",
],
entry_point = ":main",
entry_point = ":main.ts",
templated_args = ["--nobazel_patch_module_resolver"],
)

Expand Down
2 changes: 2 additions & 0 deletions examples/react_webpack/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ sass(
)

ts_project(
# Experimental: Start a tsc daemon to watch for changes to make recompiles faster.
supports_workers = True,
deps = [
"@npm//@types",
"@npm//csstype",
Expand Down
15 changes: 12 additions & 3 deletions examples/react_webpack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{
"compilerOptions": {
"jsx": "react",
"lib": ["ES2015", "DOM"]
}
}
"lib": [
"ES2015",
"DOM"
]
},
// When using ts_project in worker mode, we run outside the Bazel sandbox (unless using --worker_sandboxing).
// We list the files that should be part of this particular compilation to avoid TypeScript discovering others.
"include": [
"*.tsx",
"*.ts"
]
}
2 changes: 1 addition & 1 deletion index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ load(
load("//internal/node:node_repositories.bzl", _node_repositories = "node_repositories")
load("//internal/node:npm_package_bin.bzl", _npm_bin = "npm_package_bin")
load("//internal/npm_install:npm_install.bzl", _npm_install = "npm_install", _yarn_install = "yarn_install")
load("//internal/pkg_npm:pkg_npm.bzl", _pkg_npm = "pkg_npm")
load("//internal/pkg_npm:pkg_npm.bzl", _pkg_npm = "pkg_npm_macro")
load("//internal/pkg_web:pkg_web.bzl", _pkg_web = "pkg_web")

check_bazel_version = _check_bazel_version
Expand Down
1 change: 1 addition & 0 deletions internal/linker/test/workspace_link/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ jasmine_node_test(
name = "test",
srcs = ["test.js"],
link_workspace_root = True,
tags = ["fix-windows"],
templated_args = ["--nobazel_patch_module_resolver"],
deps = [
"//internal/linker/test/workspace_link/bar",
Expand Down
12 changes: 10 additions & 2 deletions internal/node/node.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _trim_package_node_modules(package_name):
for n in package_name.split("/"):
if n == "node_modules":
break
segments += [n]
segments.append(n)
return "/".join(segments)

def _compute_node_modules_root(ctx):
Expand Down Expand Up @@ -150,6 +150,9 @@ def _to_execroot_path(ctx, file):

return file.path

def _join(*elements):
return "/".join([f for f in elements if f])

def _nodejs_binary_impl(ctx):
node_modules_manifest = write_node_modules_manifest(ctx, link_workspace_root = ctx.attr.link_workspace_root)
node_modules_depsets = []
Expand Down Expand Up @@ -250,7 +253,12 @@ fi
expanded_args = [expand_location_into_runfiles(ctx, a, ctx.attr.data) for a in expanded_args]

# Next expand predefined variables & custom variables
expanded_args = [ctx.expand_make_variables("templated_args", e, {}) for e in expanded_args]
rule_dir = _join(ctx.bin_dir.path, ctx.label.workspace_root, ctx.label.package)
additional_substitutions = {
"@D": rule_dir,
"RULEDIR": rule_dir,
}
expanded_args = [ctx.expand_make_variables("templated_args", e, additional_substitutions) for e in expanded_args]

substitutions = {
# TODO: Split up results of multifile expansions into separate args and qoute them with
Expand Down
Loading