Supercharge your builds with Bazel
Wassim Chegham
#Always_Bet_On_JavaScript
I love open source...
hexa.run
angular.run
xLayers.dev
nitr.ooo
ngx.tools
@rules_nodejs// on master and ⬢ v13.7.0
➜ find ./ -iname "WORKSPACE"
.//WORKSPACE
.//examples/angular/WORKSPACE
.//examples/kotlin/WORKSPACE
.//examples/angular_view_engine/WORKSPACE
.//examples/nestjs/WORKSPACE
.//packages/labs/src/WORKSPACE
.//packages/typescript/src/WORKSPACE
.//packages/karma/src/WORKSPACE
.//packages/rollup/src/WORKSPACE
.//packages/terser/src/WORKSPACE
.//packages/jasmine/src/WORKSPACE
.//packages/protractor/src/WORKSPACE
.//e2e/jasmine/WORKSPACE
...
workspace(name = "angular_bazel_example")
# This rule is built-into Bazel but we need to load it first to download more rules
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
# Fetch rule implementation as an archive
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "9473b207f1c5a61b603442cbfeeea8aaf2aa62870673fce2a1c52087f6ff4dc9",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.2.4/rules_nodejs-1.2.4.tar.gz"],
)
# Load rule definition
load("@build_bazel_rules_nodejs//:index.bzl", "npm_install")
# Invoke rule
npm_install(
name = "npm",
package_json = "//:package.json",
package_lock_json = "//:package-lock.json"
)
# Fetch rule implementation from a GIT repo
git_repository(
name = "io_bazel_rules_k8s",
commit = "d72491924369868a13532af9f15cb766e5943855",
remote = "https://github.com/bazelbuild/rules_k8s.git",
)
# Load rule definition
load("@io_bazel_rules_k8s//k8s:k8s.bzl", "k8s_defaults")
# Invoke rule
k8s_repositories()
@rules_nodejs// on master and ⬢ v13.7.0
➜ find ./ -iname "BUILD.bazel"
./internal/BUILD.bazel
./internal/linker/test/BUILD.bazel
./internal/linker/BUILD.bazel
./internal/pkg_npm/test/BUILD.bazel
./internal/pkg_npm/BUILD.bazel
./internal/golden_file_test/BUILD.bazel
./internal/providers/BUILD.bazel
./internal/js_library/BUILD.bazel
./internal/common/test/BUILD.bazel
./internal/common/BUILD.bazel
./internal/bazel_integration_test/BUILD.bazel
./internal/node/test/lib1/BUILD.bazel
./internal/node/test/BUILD.bazel
...
package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary")
load("@io_bazel_rules_rust//wasm_bindgen:wasm_bindgen.bzl", "rust_wasm_bindgen")
rust_binary(
name = "hello_world_rust",
srcs = ["main.rs"],
edition = "2018",
deps = [
"@io_bazel_rules_rust//wasm_bindgen/raze:wasm_bindgen"
]
)
rust_wasm_bindgen(
name = "hello_world_bindgen",
wasm_file = ":hello_world_rust",
bindgen_flags = ["--nodejs"]
)
package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary")
load("@io_bazel_rules_rust//wasm_bindgen:wasm_bindgen.bzl", "rust_wasm_bindgen")
rust_binary(
name = "hello_world_rust",
srcs = ["main.rs"],
edition = "2018",
deps = [
"@io_bazel_rules_rust//wasm_bindgen/raze:wasm_bindgen"
]
)
rust_wasm_bindgen(
name = "hello_world_bindgen",
wasm_file = ":hello_world_rust",
bindgen_flags = ["--nodejs"]
)
Workspace name
Package
Target
Workspace Root
# //src/lib/shorten/BUILD.bazel
ts_library(
name = "shorten",
srcs = ["shorten.ts"],
module_name = "@bazel/shorten",
module_root = "shorten",
deps = [
"//some/dep",
"@npm//other/dep",
],
)
# Output:
# - shorten.d.ts
# - shorten.js
@angular/core/**/*.ts
./core.js
./core.d.ts
./bundles/core.umd.js
ts_library()
rollup_bundle()
tsc -p tsconfig.json ...
ts_library()
def fizz_buzz(n):
"""Print Fizz Buzz numbers from 1 to n."""
for i in range(1, n + 1):
s = ""
if i % 3 == 0:
s += "Fizz"
if i % 5 == 0:
s += "Buzz"
print(s if s else i)
fizz_buzz(20)
NO: class, import, while, yield, lambda and nested functions, try, raise, except, finally...
Starlark’s syntax is inspired by Python3
# index.bzl
def _empty_impl(ctx):
print("This rule does nothing")
empty = rule(implementation = _empty_impl)
#-----------------------------------------
# BUILD.bazel
load("//:index.bzl", "empty")
empty(name = "nothing")
$ bazel build //:nothing
$ ls
.
├── WORKSPACE
├── index.bzl
└── BUILD.bazel
tsc file-1.ts file-2.ts \
--target es6 \
--outFile main.bundle.js
# WORKSPACE
workspace(name = "tsc_binary_example")
# BUILD.bazel
load("//:index.bzl", "tsc_binary")
tsc_binary(
name = "bazel_tsc",
srcs = [
":file-1.ts",
":file-2.ts"
],
)
# index.bzl
# See next slide...
$ tree
.
├── WORKSPACE
├── BUILD
├── file-1.ts
├── file-2.ts
└── index.bzl
script_template = """\
#!/bin/bash
tsc {ts_files} --target es6 --outFile {out_file}
"""
def _tsc_binary_impl(ctx):
output = ctx.actions.declare_file("%s.sh" % ctx.label.name)
script_content = script_template.format(
out_file = "%s.bundle.js" % output.short_path,
ts_files = " ".join([f.path for f in ctx.files.srcs]),
)
# tsc file-1.ts file-2.ts --target es6 --outFile bazel_tsc.sh.bundle.js
ctx.actions.write(output, script_content, is_executable = True)
runfiles = ctx.runfiles(files = ctx.files.srcs)
return [DefaultInfo(executable = output, runfiles = runfiles)]
tsc_binary = rule(
implementation = _tsc_binary_impl,
attrs = {
"srcs": attr.label_list(
allow_files = True,
doc = "Input TypeScript files",
),
},
executable = True,
)
* Needs to be configured separately! (https://docs.bazel.build/versions/main/remote-execution-ci.html)
bazel query 'deps(//...)' --output graph | dot -Tpng > docs/graph.png
dev.to/wassimchegham
dev.to/angular
dev.to/bazel