Skip to content

Commit

Permalink
docs: update docs entry point with better quickstart content
Browse files Browse the repository at this point in the history
This teaches you to use generated npm_package_bin rules rather than getting into details about writing custom rules with nodejs_binary

Fixes bazel-contrib#1727
  • Loading branch information
alexeagle committed Mar 26, 2020
1 parent 682bd26 commit 3bf8631
Showing 1 changed file with 94 additions and 40 deletions.
134 changes: 94 additions & 40 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,80 +15,134 @@ This JavaScript support lets you build and test code that targets a JavaScript r

## Quickstart

First we create a new workspace, which will be in a new directory.
We can use the `@bazel/create` npm package to do this in one command.
This is the fastest way to get started for most use cases.
See [the installation page](install.html) for details and alternative methods.

> See [the installation page](install.html) for details and alternative methods.
```sh
$ npm init @bazel
$ npm init @bazel my_workspace
$ cd my_workspace
```

or if you prefer yarn,
> You could do the same thing with yarn:
> ```sh
> $ yarn create @bazel my_workspace
> $ cd my_workspace
> ```
> Both of these commands are equivalent to `npx @bazel/create` which downloads the latest version of the `@bazel/create` package from npm and runs the program it contains.
> Run the tool with no arguments for command-line options and next steps.
Next we install some development tools.
For this example, we'll use Babel to transpile our JavaScript, Mocha for running tests, and http-server to serve our app.
This is just an arbitrary choice, you probably already have some tools you prefer.
```sh
$ yarn create @bazel
$ npm install @babel/core @babel/cli @babel/preset-env http-server mocha domino
```
> These commands are equivalent to `npx @bazel/create` which downloads the latest version of the `@bazel/create` package from npm and runs the program contained.
Let's run these tools with Bazel. There are two ways to run tools:
See the output of the tool for command-line options and next steps.
- Use an auto-generated Bazel rule by importing from an `index.bzl` file in the npm package
- Use a custom rule in rules_nodejs or write one yourself
## Usage
In this example we use the auto-generated rules.
First we need to import them, using a load statement.
So edit BUILD.bazel and add:
### Running a program from npm
```python
load("@npm//@babel/cli:index.bzl", "babel")
load("@npm//mocha:index.bzl", "mocha_test")
load("@npm//http-server:index.bzl", "http_server")
```
The `nodejs_binary` rule lets you run a program with Node.js.
See [Built-ins](Built-ins.html)
> This shows us that rules_nodejs has told Bazel that a workspace named @npm is available
> (think of the at-sign like a scoped package for Bazel).
> rules_nodejs will add index.bzl files exposing all the binaries the package manager installed
> (the same as the content of the node_modules/.bin folder).
> The three tools we installed are in this @npm scope and each has an index file with a .bzl extension.
If you have installed the [rollup] package, you could write this rule:
Next we teach Bazel how to transform our JavaScript inputs into transpiled outputs.
Here we assume that you have `app.js` and `es5.babelrc` in your project. See [our example webapp](https://github.com/bazelbuild/rules_nodejs/tree/1.4.0/examples/webapp) for an example of what those files might look like.
Now we want Babel to produce `app.es5.js` so we add to `BUILD.bazel`:

```python
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")

nodejs_binary(
name = "rollup",
entry_point = "//:node_modules/rollup/bin/rollup",
babel(
name = "compile",
data = [
"app.js",
"es5.babelrc",
"@npm//@babel/preset-env",
],
outs = ["app.es5.js"],
args = [
"app.js",
"--config-file",
"$(execpath es5.babelrc)",
"--out-file",
"$(execpath app.es5.js)",
],
)
```

and run it with
> This just calls the Babel CLI, so you can see [their documentation](https://babeljs.io/docs/en/babel-cli) for what arguments to pass.
> We use the $(execpath) helper in Bazel so we don't need to hardcode paths to the inputs or outputs.
```sh
$ bazel run :rollup -- --help
We can now build the application: `npm run build`

and we see the .js outputs from babel appear in the `dist/bin` folder.

Let's serve the app to see how it looks, by adding to `BUILD.bazel`:

```
http_server(
name = "server",
data = [
"index.html",
"app.es5.js",
],
args = ["."],
)
```

[rollup]: https://www.npmjs.com/package/rollup
Add a `serve` entry to the scripts in `package.json`:

You can also wrap an npm program with a Bazel rule, making it easy to integrate with a Bazel build.
See the `examples/parcel` example.
```json
{
"scripts": {
"serve": "ibazel run :server"
}
}
```

### Running a program from local sources
> ibazel is the watch mode for bazel.
>
> Note that on Windows, you need to pass `--enable_runfiles` flag to Bazel.
> That's because Bazel creates a directory where inputs and outputs both appear together, for convenience.
We can reference a path in the local workspace to run a program we write.
Now we can serve the app: `npm run serve`

```python
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
Finally we'll add a test using Mocha, and the domino package so we don't need a browser. Add to `BUILD.bazel`:

nodejs_binary(
name = "example",
data = [
"@//:node_modules",
"main.js",
```python
mocha_test(
name = "unit_tests",
args = ["*.spec.js"],
data = glob(["*.spec.js"]) + [
"@npm//domino",
"app.es5.js",
],
entry_point = ":main.js",
args = ["--node_options=--expose-gc"],
)
```

This example illustrates how to pass arguments to nodejs (as opposed to passing arguments to the program).

The `data` attribute is optional, by default it includes the `node_modules` directory. To include your own
sources, include a file or target that produces JavaScript.
Run the tests: `npm test`

See the `examples/user_managed_deps` directory in this repository.
## Next steps

### Testing
Look through the `/examples` directory in this repo for many examples of running tools under Bazel.

The `examples/user_managed_deps/index.spec.js` file illustrates testing. Another usage is in https://github.com/angular/tsickle/blob/master/test/BUILD
You might want to look through the API docs for custom rules such as TypeScript, Rollup, and Terser which add support beyond what you get from calling the CLI of those tools.

### Debugging

Expand Down

0 comments on commit 3bf8631

Please sign in to comment.