Add a reference to this repository in your WORKSPACE
file:
http_archive(
name = "aprils_rules",
urls = ["https://github.com/aschleck/bazel_rules/archive/master.tar.gz"],
strip_prefix = "bazel_rules-master",
)
The official rules are very complicated. There's probably some good reasons, but I just wanted things to be easy while allowing me to specify packages to install at build time.
The Docker rule is very incomplete. In particular, it only allows building
with root buildah
(because I use it with Kubernetes without a registry.)
Additionally, while it allows specifying an Alpine image, note that Bazel
must be configured to build with musl
or else the binaries wont work inside
the container.
- First, allow password-less
buildah
invocations in your `/etc/sudoers' file.april ALL=(ALL) NOPASSWD: /usr/bin/buildah
- Then use the BUILD rules. If the binary target is a Python binary, Python
will be automatically installed.
load("@aprils_rules//docker:defs.bzl", "container") cc_binary( name = "app", srcs = glob(["*.cpp"]) + glob(["*.hpp"]), ) container( name = "container", binary = ":app", image_name = "package/app", base_image = "debian:sid" extra_packages = [ "pulseaudio", # the list of apk or apt-get packages to install ], )
I found the official rules to be annoying, so I've made a less safe alternative.
- Create a directory with the same name as the Pip package anywhere in your workspace:
mkdir -p pip/flask
- Create a BUILD file for it with the following contents:
package(default_visibility = ["//visibility:public"]) load("@aprils_rules//python/pip:pip_package.bzl", "pip_package") pip_package()
- Depend on the package from your Python target:
py_binary( name = "mabel", srcs = glob(["*.py"]), deps = [ "//pip/flask", ], )
- And load it in your Python file:
import pip.flask # mirrors the file layout, in this case pip/flask import flask app = flask.Flask(__name__)
The official rules are made for using NodeJS, which seemed annoying to set up. Naturally, I've made an incredibly hacky alternative.
Four additions beyond simple Typescript support:
- This uses System.JS module loading
- This allows forcing specific modules to load when the DOM is ready
- This allows using code from raw JS files (provided there is a .d.ts file) in your Typescript
- This allows compiling and using Soy templates
- Add the following to your
WORKSPACE
file.load("@aprils_rules//typescript:repositories.bzl", "ts_repositories") ts_repositories() load("@aprils_rules//typescript:repositories_deps.bzl", "repositories_deps") repositories_deps()
- Write your Typescript files.
import { hello } from './same_directory_file'; import { goodbye } from 'relative/to/workspace/root/file'; export function act(): void { hello(); goodbye(); }
- Define your Typescript libraries.
load("@aprils_rules//typescript:defs.bzl", "ts_library") ts_library( name = "example", srcs = glob(["*.ts"]), deps = [ "//relative/to/workspace/root", ], )
- Define your Typescript binary.
load("@aprils_rules//typescript:defs.bzl", "ts_binary") # Generates a file named app.js ts_binary( name = "app", deps = [ "//app/lib:example", ], )
If you need code to run after the page loads, define a base module.
- As an example, create
app/bootstrap.ts
.module Bootstrap { console.log('hello!'); }
- Then, reference it from the
ts_binary
rule.load("@aprils_rules//typescript:defs.bzl", "ts_binary", "ts_library") ts_library( name = "app_lib", srcs = glob(["*.ts"]), ) ts_binary( name = "app", deps = [ ":app_lib", ], base_modules = [ "app/bootstrap", ], )
- Create a raw Javascript file.
function be_nice() { console.log("you're amazing!"); }
- Create a Typescript declarations file. This file must match the name of the
raw JS file (for example, if the JS is
nice.js
this must benice.d.ts
.)export declare function be_nice(): void;
- Create a Typescript library for it.
load("@aprils_rules//typescript:defs.bzl", "ts_library") ts_library( name = "nice", srcs = ["nice.d.ts"]), js_srcs = [ "nice.js", ], )
- Depend on it like any other Typescript library.
Please note that there is currently no type checking on inputs passed to Soy.
- Create an amazing Soy file, for example
app/app.soy
.{namespace not.actually.used} {template .message} {@param name: string} Hello world, {$name}! {/template}
- Make a
BUILD
rule for it and have your code depend on it like any other Typescript library.load("@aprils_rules//typescript:template_defs.bzl", "ts_library_from_soy") ts_library( name = "app_lib", deps = [ ":soy", ], ) ts_library_from_soy( name = "soy", srcs = glob(["*.soy"]), soy_deps = [ "//app:app_soy", ], )
- Reference it by full path (not relative!) in your Typescript code.
import * as templates from 'app/app_soy'; export function render_message(): string { return templates.message({name: 'April'}); }