How to build nodejs and python projects using Bazel build tool
Managing a multi-language project with Bazel, such as one that includes both Node.js and Python sub-projects, can be effectively done by leveraging Bazel's extensibility and its support for multiple languages. Below is a step-by-step guide to setting up Bazel for a project that includes both Node.js and Python components.
Step 1: Install Bazel
Ensure you have Bazel installed. You can install it following the instructions on the Bazel website.
Step 2: Create a WORKSPACE File
The WORKSPACE file defines the root of your Bazel project and sets up external dependencies. For a project with both Node.js and Python, you need to load the appropriate rules for each language.
Here’s an example WORKSPACE file:
workspace(name = "multi_language_project")
# Load npm repository rules
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_nodejs",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.3.2/rules_nodejs-4.3.2.tar.gz"],
sha256 = "f0ad6a9573498482e5447a3b0958b8c2b1f02b640dd3a5099a1d7584f4a313d1",
strip_prefix = "rules_nodejs-4.3.2",
)
load("@rules_nodejs//node:repositories.bzl", "node_repositories")
node_repositories()
# Load Python repository rules
http_archive(
name = "rules_python",
urls = ["https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz"],
sha256 = "c3d889a8364d7b0bc5df77d32e61b4b4afdafd2822c2297de6adbd0e1de2c639",
)
load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
Step 3: Set Up Node.js Sub-Project
In your Node.js sub-project, you need a BUILD file that defines the build rules and targets for your Node.js application.
Here’s an example BUILD file for the Node.js sub-project:
# nodejs_project/BUILD
load("@rules_nodejs//node:defs.bzl", "nodejs_binary", "npm_package")
# Define an npm package
npm_package(
name = "node_modules",
package_json = "package.json",
package_lock_json = "package-lock.json",
)
# Define a Node.js binary
nodejs_binary(
name = "app",
entry_point = "src/index.js",
data = ["//nodejs_project:node_modules"],
)
Ensure you have package.json and package-lock.json files in your Node.js project directory.
Step 4: Set Up Python Sub-Project
In your Python sub-project, you need a BUILD file that defines the build rules and targets for your Python application.
Here’s an example BUILD file for the Python sub-project:
# python_project/BUILD
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
# Define a Python library
py_library(
name = "lib",
srcs = glob(["lib/**/*.py"]),
)
# Define a Python binary
py_binary(
name = "app",
srcs = ["app.py"],
deps = [":lib"],
)
Step 5: Directory Structure
Ensure your directory structure looks something like this:
multi_language_project/
├── WORKSPACE
├── nodejs_project/
│ ├── BUILD
│ ├── package.json
│ ├── package-lock.json
│ └── src/
│ └── index.js
└── python_project/
├── BUILD
├── app.py
└── lib/
└── my_module.py
Step 6: Build and Run
You can now build and run your sub-projects using Bazel commands:
-
To build the Node.js project:
bazel build //nodejs_project:app -
To run the Node.js project:
bazel run //nodejs_project:app -
To build the Python project:
bazel build //python_project:app -
To run the Python project:
bazel run //python_project:app