The js_image_layer rule returns tar artifacts, suitable to include in the tars attribute of the container_image rule from rules_docker. You can bazel run the target to get the image to load into your Docker daemon. See the rules_docker documentation
Like all lang_image rules in rules_docker, the nodejs_image rule has different behavior under
bazel runwhere the container is booted and executes.
For an example using rules_oci rather than rules_docker, see the js_image_oci folder next to this one.
js_image_layer is a macro that yields two tar files app.tar and node_modules.tar. While app.tar contains first-party sources, node_modules.tar contains all third-party dependencies.
This speeds up developer change-build-push cycle by allowing build and push of only what has changed.
For instance, when a new third-party dependency is added, then only node_modules.tar will change and one will only have to push changes to dependencies. On the other hand, if the application code is changed, then only app.tar will be updated and pushed.
│ Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Cmp Size Command
118 MB FROM 27d8bf01e7ea3c5
78 MB bazel build ...
97 kB bazel build ...
0 B #(nop) ADD file:64c455af1bb18ff2c202a244e058b6e5ac147b89410ed36edc5e29f4b6f02c5d in /
│ Image Details ├───────────────────────────────────────────────────────────────────────────────────────────
Image name: localhost/bazel:image
Total Image size: 196 MB
Potential wasted space: 0 B
Image efficiency score: 100 %
As seen in the dive output the largest layer is our base image which is 118 MB followed by 78 MB which is the dependencies and finally 97 kB which is the app itself. Additionally, we get a 100% efficiency score which means there are no duplicate or whiteout files to waste space.
By default js_binary gets the nodejs interpreter for the host platform. However, this is not the case when including the js_binary in container_image thanks to transitions. See #3373 and #1963 for how this works.
Toolchain selection is controlled by operating_system and architecture attribute on container_image which is linux/amd64 by default.
NodeJS interpreter for a different platform can be obtained by changing operating_system and architecture.
Here is what the final image looks like when the platform is linux/arm64
app |-- main.sh |-- main.sh.runfiles | |-- __main__ | | |-- main.sh | | |-- node_modules | | | `-- chalk -> /app/main.sh.runfiles/__main__/node_modules/.aspect_rules_js/chalk@4.1.2/node_modules/chalk | | `-- src | | |-- ascii.art | | `-- main.js | |-- aspect_rules_js | | `-- js | | `-- private | | `-- node-patches | | |-- fs.cjs | | `-- register.cjs | |-- bazel_tools | | `-- tools | | `-- bash | | `-- runfiles | | `-- runfiles.bash | `-- nodejs_linux_arm64 | `-- bin | `-- nodejs | `-- bin | `-- node `-- main_.sh 17 directories, 9 files