tree: a072c18c833e800fbcd3cdf306273db825c5c54d [path history] [tgz]
  1. .bazelignore
  2. .bazelrc
  3. bar.js
  4. BUILD.bazel
  5. bundle.golden.js_
  6. foo.js
  7. package-lock.json
  8. package.json
  9. parcel.bzl
  10. README.md
  11. WORKSPACE
examples/parcel/README.md

Parcel example

This example shows how to write a simple Bazel rule which wraps a binary from npm.

We chose Parcel because it's a build tool not yet supported in our own Bazel rules.

We start from the Parcel Getting Started.

Parcel can do many jobs which overlap with Bazel, such as development serving and watching.

Parcel can do file-system watching, but this overlaps with ibazel so this mode is probably undesirable under Bazel.

Also, Parcel has a development server. This could be an alternative to the ts_devserver we recommend under Bazel. It would need to be hosted properly to see generated Bazel outputs from other build steps. See https://github.com/angular/angular-bazel-example/wiki/Running-a-devserver-under-Bazel

In this example we'll only use Parcel for production bundling, as documented at https://parceljs.org/production.html

1. Installing and running Parcel

The package.json file lists a devDependency on parcel-bundler.

Next, in WORKSPACE we run the yarn_install rule. This fetches the packages into the Bazel output_base folder, here: $(bazel info output_base)/external/npm. It also generates Bazel configuration files. Since parcel-bundler/package.json declares a bin: {"parcel"} key, Bazel will generate a corresponding target.

$ bazel query --output=label_kind @npm//parcel-bundler/bin:*
alias rule @npm//parcel-bundler/bin:parcel
source file @npm//parcel-bundler/bin:BUILD.bazel

So with no other code, we can already run Parcel itself.

$ bazel run @npm//parcel-bundler/bin:parcel
Server running at http://localhost:1234 
🚨  No entries found.
    at Bundler.bundle (execroot/examples_parcel/bazel-out/k8-fastbuild/bin/external/npm/node_modules/parcel-bundler/parcel__bin.runfiles/npm/node_modules/parcel-bundler/src/Bundler.js:261:17)

2. Wrapping parcel in a rule (plugin)

Bazel‘s idiomatic naming scheme for rules is [name of tool]_[type of rule] where types of rules include “library”, “binary”, “test”, “package”, “bundle”, etc. Since Parcel is a bundler, we’ll name our rule parcel_bundle. The rule describes the inputs, not what to do with them.

In BUILD.bazel we show an example usage of the new rule.

In parcel.bzl you can see how the rule is implemented. It returns two outputs: the bundle file and a sourcemap.

To try the rule, run

$ bazel build :bundle
INFO: From Running Parcel to produce bazel-out/k8-fastbuild/bin/bundle.js:
✨  Built in 499ms.

bazel-out/k8-fastbuild/bin/bundle.js     1.3 KB    191ms
bazel-out/k8-fastbuild/bin/bundle.map     399 B      2ms
Target //:bundle up-to-date:
  bazel-bin/bundle.js
  bazel-bin/bundle.map

3. Testing the rule

Currently, we just demonstrate how to test it end-to-end by bundling foo.js and bar.js into a UMD bundle. Then in parcel.spec.js we require() that bundle in Node.js and assert that it had the right side-effect. (It prints Hello, Bob)

You can run the test:

$ bazel test :all
//:test (cached) PASSED in 0.3s

Executed 0 out of 1 test: 1 test passes.