Bazel: most scalable polyglot Build System.
JavaScript & TypeScript: most popular languages.
I Co-founded Aspect Development to make Bazel the industry-standard full-stack build system
The JS ecosystem took a wrong turn
ModernWeb Meetup: Layering in JS tooling
https://www.aspect.dev/resources last one
Like Gulp or Grunt, but way (way) better.
Let's use Bazel!
JavaScript engine that runs outside the browser.
Typically used for running dev tools to
build and test JavaScript programs.
Deno is an up-and-coming alternative, see rules_deno
rules_nodejs
Bazel rules forked from Google-internal
DeclarationInfo
rules_js
rules_js is a layer on top of rules_nodejs
About rules_js: My talk from Bazel eXchange 2022
Slides: https://hackmd.io/@aspect/rules_js
Video: https://aspect.dev/resources (first video)
pnpm
rules_js
Client runtime: Browser
Server runtime: Node.js
Both use the same virtual machine (V8), stdlib differs
rules_nodejs
supports both, though confusingly namedrules_js
also supports bothModules
digraph G {
rankdir="TB"
fontname="courier"
subgraph cluster_bazelbuild {
label = "github.com/bazelbuild"
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
nodejs_binary
nodejs_star [label="nodejs_*"]
yarn_install
label = "build_bazel_rules_nodejs";
}
subgraph cluster_1 {
toolchain
label = "rules_nodejs";
color=blue
}
}
subgraph cluster_npm {
label = "npm"
subgraph cluster_2 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
ts [label="ts_project"]
label = "@bazel/typescript";
}
subgraph cluster_6 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
other [label="..."]
label = "@bazel/*";
}
}
subgraph cluster_aspect {
label = "github.com/aspect-build"
subgraph cluster_3 {
js_binary
js_star [label="js_*"]
npm_star [label="npm_*"]
label = "rules_js";
color=blue
}
subgraph cluster_4 {
ts_project
label = "rules_ts";
color=blue
}
subgraph cluster_7 {
other_rules [label="..."]
label = "rules_*"
color=blue
}
subgraph cluster_8 {
copy_to_bin
label = "bazel_lib"
color=blue
}
}
other_rules -> js_binary
ts -> nodejs_binary
nodejs_binary -> toolchain
js_binary -> toolchain
ts_project -> js_binary
js_binary -> copy_to_bin
}
NEWS: Shaded boxes are no longer maintained!
npm install
Install everything needed for the whole
package/workspace
Any build/test script can depend on all npm packages
Vendor the world: copy npm ecosystem sources into VCS
You could do it this way too.
Just wrap [npm|yarn] install
- install the world
Guaranteed slow when repo rule invalidates
Extra bad when "eager fetching" npm deps
Port pnpm to Starlark
@pnpm/lifecycle
to run hooks
node_modules
https://blog.aspect.dev/rulesjs-npm-benchmarks
Best case:
NodeJS programs rely on a node_modules
folder
"Was a big mistake" says NodeJS creator, and
Deno fixes it (but here we are )
The location of node_modules
is expected to be relative to the location of the importing script.
require
Same strategy as "PnP", e.g. Yarn PnP.
not compatible. Many npm packages wrote their own
require
implementation.
Similar to npm link
: use symlinks to make monorepo libraries appear in the node_modules tree
Slow beginning of every NodeJS spawn
Links appear in source tree w/o sandbox
Bins don't work with
genrule
/ctx.actions.run
Not compatible with "persistent workers"
Linker is now just a standard Bazel target
Node.js tools assume the working dir is a single tree of src/gen/node_modules: we can do that!
bazel-bin/node_modules/...
bazel-bin
cd bazel-out/[arch]/bin
https://github.com/aspect-build/bazel-examples/tree/main/vue
WORKSPACE
: read 3p npm package lockfileBUILD
: declare dependencies on npm packagesrules_js 1.0.0 is available now
Coming soon
BUILD
files from srcsWORKSPACE