rules_vite
Bazel rules for Vitest under aspect_rules_js. Hermetic js_test wrapper for vitest.
| Latest | 0.1.1 |
|---|---|
| Versions | 2 |
| Category | Bazel rules |
| Compat level | 1 |
| Maintainers | Matt Marshall |
| Registry | https://registry.tbzl.dev/modules/rules_vite/ |
| Source | github.com/tomato-bazel/rules_vite |
bazel_dep(name = "rules_vite", version = "0.1.1")
View source & releases on GitHub ↗
Bazel rules for Vitest under aspect_rules_js.
Wraps a vitest run as a hermetic js_test: the consumer’s package-local
node_modules/vitest is resolved at runtime; the test sources are
passed explicitly via argv; the launcher rewrites runfiles-relative
paths so config and srcs survive chdir into the consumer’s package.
- rules:
vitest_test—bazel test //path:target→ runs vitest in a hermetic sandbox with declared inputs only. See docs/defs.md.
The consumer brings its own vitest npm dep (so the version isn’t
pinned by rules_vite). The macro doesn’t impose any project key or
config shape — pass any vitest config file as config, or accept the
minimal default.
Install
Add the registry to your .bazelrc:
common --registry=https://registry.fastverk.com/
common --registry=https://bcr.bazel.build/
In your MODULE.bazel:
bazel_dep(name = "rules_vite", version = "0.1.0")
bazel_dep(name = "aspect_rules_js", version = "3.1.2")
bazel_dep(name = "rules_nodejs", version = "6.7.4")
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
node.toolchain(node_version = "22.11.0")
npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm")
npm.npm_translate_lock(
name = "npm",
pnpm_lock = "//:pnpm-lock.yaml", # must include vitest
)
use_repo(npm, "npm")
Quick start
In a BUILD.bazel:
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@rules_vite//vite:defs.bzl", "vitest_test")
npm_link_all_packages(name = "node_modules")
vitest_test(
name = "test_node",
srcs = ["foo.test.ts", "bar.test.ts"],
deps = [
":node_modules/vitest",
# ...workspace deps the tests import...
],
)
The macro:
- Sets
chdirto the consumer’s package, soprocess.cwd()puts the test inside<consumer>/node_modules/...for module resolution. - Resolves vitest’s bin via
vitest/package.json(vitest doesn’t expose the bin file in itsexportsmap, so direct subpath resolution fails withERR_PACKAGE_PATH_NOT_EXPORTED). - Rewrites
VITEST_CONFIGand argv test-source paths to absolute paths anchored at$JS_BINARY__RUNFILES/_main, so they survivechdir.
Config
Pass config to override the default minimal config:
vitest_test(
name = "test_with_setup",
srcs = ["foo.test.ts"],
config = "//:vitest.config.ts",
deps = [
":node_modules/vitest",
"//:vitest.config.ts.lib", # js_library wrapping the config
# plus any plugins the config imports
],
)
If config is omitted the macro injects a minimal config that:
- Sets
environment: 'node' - Disables
globals,setupFiles, coverage, plugins - Lets
testTimeout/hookTimeoutdefault to vitest’s settings
Tests that need richer setup (browser env, plugins, globalSetup, etc.)
provide their own config and materialize its transitive deps in
runfiles via standard js_library wrappers.
Smoke test
bazel test @rules_vite//examples/smoke:...
Runs a real vitest invocation against a tiny pnpm workspace pinned in examples/smoke. Used as a release gate.
Usage#
Real usage, taken from the module’s examples/.
examples/smoke/BUILD.bazel
load("@rules_vite//vite:defs.bzl", "vitest_test")
load("@smoke_npm//:defs.bzl", "npm_link_all_packages")
package(default_visibility = ["//visibility:public"])
npm_link_all_packages(name = "node_modules")
exports_files(["pnpm-lock.yaml"])
# Smoke: a real `vitest_test` exercising the macro end-to-end against
# the pinned smoke npm workspace. Used as a release gate.
vitest_test(
name = "smoke_test",
srcs = ["sum.test.ts"],
deps = [":node_modules/vitest"],
)Rules & providers#
Generated with Stardoc from the module's .bzl sources.
from docs/defs.md
Public rules for rules_vite.
vitest_test
load("@rules_vite//vite:defs.bzl", "vitest_test")
vitest_test(name, srcs, config, deps, data, env, tags, timeout, **kwargs)
Run vitest against the given test sources under a hermetic Bazel sandbox.
The consumer must call npm_link_all_packages(name = "node_modules") at
the top of its BUILD.bazel and include :node_modules/vitest in
deps (plus any test-time npm packages the suite imports). The
launcher resolves vitest via Node’s standard walk-up from
chdir = package_name().
PARAMETERS
Conformance#
No gate findings. 17 contested atoms. See how gating works or the full report.
Contested atoms
Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.
| Atom | Resolved here | Elsewhere |
|---|---|---|
apple_support | 1.24.2 | 2.2.0 ×1 |
aspect_bazel_lib | 2.22.5 | 2.8.1 ×1 |
aspect_rules_js | 3.1.2 | 2.1.3 ×1 |
bazel_lib | 3.2.2 | 3.0.0 ×12 |
bazel_skylib | 1.8.2 | 1.9.0 ×2 |
gawk | 5.3.2.bcr.3 | 5.3.2.bcr.1 ×12 |
jq.bzl | 0.4.0 | 0.1.0 ×12 |
nlohmann_json | 3.6.1 | 3.12.0.bcr.1 ×1 |
package_metadata | 0.0.2 | 0.0.5 ×3 |
protobuf | 33.4 | 34.0.bcr.1 ×2 |
rules_jvm_external | 6.7 | 6.8 ×4 |
rules_nodejs | 6.7.4 | 6.3.0 ×16.7.3 ×1 |
rules_python | 1.7.0 | 2.0.1 ×1 |
rules_swift | 3.1.2 | 3.6.1 ×1 |
tar.bzl | 0.10.4 | 0.5.1 ×110.6.0 ×1 |
upb | 0.0.0-20220923-a547704 | 0.0.0-20230516-61a97ef ×1 |
yq.bzl | 0.3.4 | 0.1.1 ×12 |
Dependencies#
Depends on
Used by (4 in the registry)
Versions#
2 published versions, newest first. Each resolves to an immutable, integrity-checked archive.
| Version | Integrity (sha256) | Source archive |
|---|---|---|
0.1.1 latest | N88/msgXjjFCQqxM… | tag archive ↗ |
0.1.0 | rTAcQUqfTd+HX+vs… | tag archive ↗ |
Changelog#
All notable changes to rules_vite. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.
0.1.0 — initial release
- Initial release of Bazel rules for [Vitest] under
aspect_rules_js. Wraps a vitest run as a hermeticjs_test: the consumer’s package-localnode_modules/vitestis resolved at runtime, test sources are passed explicitly via argv, and the launcher rewrites runfiles-relative paths so config + srcs survive thechdirinto the consumer’s package. - Ships one rule,
vitest_test(bazel test //path:target), running vitest in a hermetic sandbox with declared inputs only. - The consumer brings its own
vitestnpm dep — rules_vite doesn’t pin a version or impose a project key / config shape; pass any vitest config viaconfigor use the minimal default.