Monorepo: is it possible to read dependencies from package.json?
I read through the docs but I couldn't figure out how to set up bazel for a classic lerna / yarn monorepo. Specifically, I can't figure out if its possible to read the dependencies for a bazel rule from another file i.e. package.json
What I like is to avoid duplication of specifying the dependencies twice, once in package.json for npm/yarn publishing and consumption/installation by other users, and once in Bazel for building via TypeScript in the right order.
Ideally I would have deps be generated from reading the toplevel package.json workspaces entry globs, filtered through the individual package's own dependencies and devDependencies as specified in package.json
I believe what you could do is to write a Bazel macro that takes dependencies as parameters, and based on these dependencies:
- instantiates the
ts_libraryrule - populates the
replacementsparameters ofnpm_packageaccordingly, so that a placeholder in yourpackage.jsonis replaced by the actual dependencies.
Something along these lines:
def _format_dep(name, version):
name = "@prefix/" + name[11:]
return "\"{}\": \"^{}\"".format(name, version)
def my_ts_library(name, deps = [], dev_deps = [], **kwargs):
ts_library(
name = name,
deps = deps + dev_deps,
**kwargs
)
replacements = {
"\"DEPS_PLACEHOLDER\": \"\"": ",\n ".join(
[
_format_dep(dep, "0.0.1") for dep in deps
if dep.startswith("//packages/")
]
),
"\"DEV_DEPS_PLACEHOLDER\": \"\"": ",\n ".join(
[
_format_dep(dep, "0.0.1") for dep in dev_deps
if dep.startswith("//packages/")
]
),
}
npm_package(
name = name + "-package",
srcs = [":package.json"],
deps = [":" + name] + deps,
replacements = replacements,
)
With a package.json formatted as:
{
"name": "@prefix/mypackage",
"version": "0.0.0-PLACEHOLDER",
"dependencies": {
"DEPS_PLACEHOLDER": ""
},
"devDependencies": {
"DEV_DEPS_PLACEHOLDER": ""
}
}
Alternatively, I would write a genfile rule generating the package.json file based on your dependencies
You're right, the deps are repeated right now.
In google, we don't use package.json files at all, so we accidentally brought that idiom with us. I think the best thing is for you to write package.json files in each package, and something like Gazelle generates BUILD files so that Bazel understands the package too.
No longer in scope for rules_nodejs