4 Commits

Author SHA1 Message Date
eric
49a5054b02 chore(release): v0.2.1
Some checks failed
CI / test (ubuntu-latest, linux-x64) (push) Failing after 31s
Copilot Setup Steps / copilot-setup-steps (push) Failing after 38s
CI / test (macos-14, darwin-arm64) (push) Has been cancelled
CI / test (windows-latest, windows) (push) Has been cancelled
2026-03-06 20:55:09 +01:00
eric
10758aa20a docs: Refactor code structure for improved readability
Some checks failed
CI / test (macos-14, darwin-arm64) (push) Has been cancelled
CI / test (windows-latest, windows) (push) Has been cancelled
CI / test (ubuntu-latest, linux-x64) (push) Has been cancelled
Docs Pages / deploy (push) Failing after 33s
2026-03-06 20:54:28 +01:00
eric
fb7afbb138 chore(release): v0.2.0
Some checks failed
CI / test (ubuntu-latest, linux-x64) (push) Failing after 38s
Docs Pages / deploy (push) Failing after 44s
Copilot Setup Steps / copilot-setup-steps (push) Failing after 34s
CI / test (macos-14, darwin-arm64) (push) Has been cancelled
CI / test (windows-latest, windows) (push) Has been cancelled
2026-03-06 20:34:27 +01:00
eric
3a07d02c0d fix: tests pass 2026-03-06 20:34:11 +01:00
34 changed files with 530 additions and 2348 deletions

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env bash
set -e
if [[ ! -d "/Users/eric/Projects/rules_bun" ]]; then
echo "Cannot find source directory; Did you move it?"
echo "(Looking for "/Users/eric/Projects/rules_bun")"
echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
exit 1
fi
# rebuild the cache forcefully
_nix_direnv_force_reload=1 direnv exec "/Users/eric/Projects/rules_bun" true
# Update the mtime for .envrc.
# This will cause direnv to reload again - but without re-building.
touch "/Users/eric/Projects/rules_bun/.envrc"
# Also update the timestamp of whatever profile_rc we have.
# This makes sure that we know we are up to date.
touch -r "/Users/eric/Projects/rules_bun/.envrc" "/Users/eric/Projects/rules_bun/.direnv"/*.rc

View File

@@ -1 +0,0 @@
/nix/store/7f0478ddr51i3r708dpkljnvmzwc2fhn-source

View File

@@ -1 +0,0 @@
/nix/store/affmc6lhad8f6q3iaa3iydcdjwr8lwgp-source

View File

@@ -1 +0,0 @@
/nix/store/g5v3sgqy6a0fsmas7mnapc196flrplix-source

View File

@@ -1 +0,0 @@
/nix/store/jzfmmjnq1cip816awnliw7ir69pcyg00-source

View File

@@ -1 +0,0 @@
/nix/store/kx00h535s3jzb9803vnylxllij3zhix5-source

View File

@@ -1 +0,0 @@
/nix/store/ngdfag0pfs1h54pbjs9ywah4zhqsphf1-source

View File

@@ -1 +0,0 @@
/nix/store/nk13680f34w3q01a1q69c48my6fi7cxz-source

View File

@@ -1 +0,0 @@
/nix/store/wmfpcy0yqb4igdizfrdcy5i3a9b3yjlg-nix-shell-env

File diff suppressed because one or more lines are too long

4
.gitignore vendored
View File

@@ -11,6 +11,7 @@
build/ build/
dist/ dist/
node_modules/ node_modules/
*/node_modules/
# Directories for the Bazel IntelliJ plugin containing the generated # Directories for the Bazel IntelliJ plugin containing the generated
# IntelliJ project files and plugin configuration. Seperate directories are # IntelliJ project files and plugin configuration. Seperate directories are
@@ -20,3 +21,6 @@ node_modules/
/.clwb/ /.clwb/
.env .env
!tests/.env
!examples/.env
.direnv

View File

@@ -1 +1 @@
/nix/store/wrsbzz8sgxnp8xawaxy8nvc3sdwfl5s6-pre-commit-config.json /nix/store/vq88dl8yys4hbw4gq6kwypah5ykqr8xs-pre-commit-config.json

View File

@@ -1,13 +1,15 @@
module( module(
name = "rules_bun", name = "rules_bun",
version = "0.1.0", version = "0.2.1",
) )
# Core ruleset dependencies.
bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "rules_shell", version = "0.6.1")
bazel_dep(name = "bazel_skylib", version = "1.8.2") bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "stardoc", version = "0.7.2") bazel_dep(name = "stardoc", version = "0.7.2")
# Repository-local setup for this ruleset's own tests and examples.
bun_ext = use_extension("//bun:extensions.bzl", "bun") bun_ext = use_extension("//bun:extensions.bzl", "bun")
use_repo( use_repo(
bun_ext, bun_ext,
@@ -18,6 +20,16 @@ use_repo(
"bun_windows_x64", "bun_windows_x64",
) )
# Test fixture dependency installation used by //tests/script_test.
bun_install_ext = use_extension("//bun:extensions.bzl", "bun_install")
bun_install_ext.install(
name = "script_test_vite_node_modules",
package_json = "//tests/script_test:vite_app/package.json",
bun_lockfile = "//tests/script_test:vite_app/bun.lock",
)
use_repo(bun_install_ext, "script_test_vite_node_modules")
# Register the published Bun toolchains for this repository.
register_toolchains( register_toolchains(
"//bun:darwin_aarch64_toolchain", "//bun:darwin_aarch64_toolchain",
"//bun:darwin_x64_toolchain", "//bun:darwin_x64_toolchain",

22
MODULE.bazel.lock generated
View File

@@ -189,8 +189,8 @@
"moduleExtensions": { "moduleExtensions": {
"//bun:extensions.bzl%bun": { "//bun:extensions.bzl%bun": {
"general": { "general": {
"bzlTransitiveDigest": "oLR98WtKDCc+zh7Tvu9jtakNg8q/T1IPE38QR1FEQtI=", "bzlTransitiveDigest": "83P5DLnVhSu3AwYrHPGqYVY/L6twnM4Jnlhc8uAOOls=",
"usagesDigest": "NfJgMuTjZXXRLr1/kxxFkS1IKV2UyehFyr3fMvAke/k=", "usagesDigest": "SXT282ETYzRFxBNaQrX/Ym1rZzueKzjlll/D0arFoYs=",
"recordedInputs": [ "recordedInputs": [
"REPO_MAPPING:,bazel_tools bazel_tools" "REPO_MAPPING:,bazel_tools bazel_tools"
], ],
@@ -248,6 +248,24 @@
} }
} }
}, },
"//bun:extensions.bzl%bun_install": {
"general": {
"bzlTransitiveDigest": "83P5DLnVhSu3AwYrHPGqYVY/L6twnM4Jnlhc8uAOOls=",
"usagesDigest": "BSZJHRsUZpMHTxqlUZZaq4MH8kfqrzFfF+50EqSPx/Q=",
"recordedInputs": [
"REPO_MAPPING:,bazel_tools bazel_tools"
],
"generatedRepoSpecs": {
"script_test_vite_node_modules": {
"repoRuleId": "@@//internal:bun_install.bzl%bun_install_repository",
"attributes": {
"package_json": "@@//tests/script_test:vite_app/package.json",
"bun_lockfile": "@@//tests/script_test:vite_app/bun.lock"
}
}
}
}
},
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
"general": { "general": {
"bzlTransitiveDigest": "ABI1D/sbS1ovwaW/kHDoj8nnXjQ0oKU9fzmzEG4iT8o=", "bzlTransitiveDigest": "ABI1D/sbS1ovwaW/kHDoj8nnXjQ0oKU9fzmzEG4iT8o=",

254
README.md
View File

@@ -1,191 +1,197 @@
# rules_bun # Bun rules for [Bazel](https://bazel.build)
Bazel rules for bun. `rules_bun` provides Bazel rules for running, testing, bundling, and developing
JavaScript and TypeScript code with Bun.
## Rule reference ## Repository layout
This repository follows the standard Bazel ruleset layout:
```text
/
MODULE.bazel
README.md
bun/
BUILD.bazel
defs.bzl
extensions.bzl
repositories.bzl
toolchain.bzl
docs/
examples/
tests/
```
The public entrypoint for rule authors and users is `@rules_bun//bun:defs.bzl`.
## Public API
`rules_bun` exports these primary rules:
- `bun_binary`
- `bun_bundle`
- `bun_dev`
- `bun_script`
- `bun_test`
- `js_library`
- `ts_library`
Reference documentation:
- Published docs site: https://eriyc.github.io/rules_bun/ - Published docs site: https://eriyc.github.io/rules_bun/
- Generated API docs: [docs/rules.md](docs/rules.md) - Generated rule reference: [docs/rules.md](docs/rules.md)
- Regenerate: `bazel build //docs:rules_md && cp bazel-bin/docs/rules.md docs/rules.md` - Docs index: [docs/index.md](docs/index.md)
## Use To refresh generated rule docs:
These steps show how to consume a tagged release of `rules_bun` in a separate Bazel workspace. ```bash
bazel build //docs:rules_md && cp bazel-bin/docs/rules.md docs/rules.md
### 1) Add the module dependency
In your project's `MODULE.bazel`, add:
```starlark
bazel_dep(name = "rules_bun", version = "0.1.0")
archive_override(
module_name = "rules_bun",
urls = ["https://github.com/Eriyc/rules_bun/archiv0.0.5.tar.gz"],
strip_prefix = "rules_bun-v0.1.0",
)
``` ```
For channel/pre-release tags (for example `v0.1.0-rc.1`), use the matching folder prefix: ## Bzlmod usage
Release announcements should provide a copy-pasteable module snippet in the
standard ruleset form:
```starlark ```starlark
bazel_dep(name = "rules_bun", version = "0.1.0-rc.1") bazel_dep(name = "rules_bun", version = "0.2.1")
archive_override(
module_name = "rules_bun",
urls = ["https://github.com/Eriyc/rules_bun/archiv0.0.5-rc.1.tar.gz"],
strip_prefix = "rules_bun-v0.1.0-rc.1",
)
``` ```
Note: keep the `v` prefix in the Git tag URL and `strip_prefix`; for `bazel_dep(..., version = ...)`, use the module version string without the leading `v`. Then add the Bun repositories and register the toolchains in `MODULE.bazel`:
### 2) Create Bun repositories with the extension
Still in `MODULE.bazel`, add:
```starlark ```starlark
bun_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun") bun_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun")
use_repo( use_repo(
bun_ext, bun_ext,
"bun_linux_x64", "bun_linux_x64",
"bun_linux_aarch64", "bun_linux_aarch64",
"bun_darwin_x64", "bun_darwin_x64",
"bun_darwin_aarch64", "bun_darwin_aarch64",
"bun_windows_x64", "bun_windows_x64",
) )
```
### 3) Register toolchains
Also in `MODULE.bazel`, register:
```starlark
register_toolchains( register_toolchains(
"@rules_bun//bun:darwin_aarch64_toolchain", "@rules_bun//bun:darwin_aarch64_toolchain",
"@rules_bun//bun:darwin_x64_toolchain", "@rules_bun//bun:darwin_x64_toolchain",
"@rules_bun//bun:linux_aarch64_toolchain", "@rules_bun//bun:linux_aarch64_toolchain",
"@rules_bun//bun:linux_x64_toolchain", "@rules_bun//bun:linux_x64_toolchain",
"@rules_bun//bun:windows_x64_toolchain", "@rules_bun//bun:windows_x64_toolchain",
) )
``` ```
### 4) Load rules in `BUILD.bazel` If you want Bazel-managed dependency installation, also add the module
extension for `bun_install`:
```starlark
load(
"@rules_bun//bun:defs.bzl",
"bun_binary",
"bun_bundle",
"bun_dev",
"bun_script",
"bun_test",
"js_library",
"ts_library",
)
```
### 5) (Optional) Use `bun_install` module extension
If you want Bazel-managed install repositories, add:
```starlark ```starlark
bun_install_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun_install") bun_install_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun_install")
bun_install_ext.install( bun_install_ext.install(
name = "npm", name = "npm",
package_json = "//:package.json", package_json = "//:package.json",
bun_lockfile = "//:bun.lock", bun_lockfile = "//:bun.lock",
) )
use_repo(bun_install_ext, "npm") use_repo(bun_install_ext, "npm")
``` ```
### 6) Verify setup ## Legacy WORKSPACE usage
Run one of your bun-backed targets, for example: For non-Bzlmod consumers, the repository exposes a legacy setup macro in
`@rules_bun//bun:repositories.bzl`:
```bash ```starlark
bazel test //path/to:your_bun_test load("@rules_bun//bun:repositories.bzl", "bun_register_toolchains")
bun_register_toolchains()
``` ```
All `rules_bun` rule-driven Bun invocations pass `--bun`. ## Loading rules in BUILD files
## Package scripts (`bun_script`) ```starlark
load(
"@rules_bun//bun:defs.bzl",
"bun_binary",
"bun_bundle",
"bun_dev",
"bun_script",
"bun_test",
"js_library",
"ts_library",
)
```
Use `bun_script` to expose a `package.json` script as a Bazel executable target. ## Common workflows
### `bun_script` for package scripts
Use `bun_script` to expose a `package.json` script as a Bazel executable.
This is the recommended way to run Vite-style `dev`, `build`, and `preview`
scripts.
```starlark ```starlark
load("@rules_bun//bun:defs.bzl", "bun_script") load("@rules_bun//bun:defs.bzl", "bun_script")
bun_script( bun_script(
name = "web_dev", name = "web_dev",
script = "dev", script = "dev",
package_json = "package.json", package_json = "package.json",
node_modules = "@npm//:node_modules", node_modules = "@npm//:node_modules",
data = glob([ data = glob([
"src/**", "src/**",
"static/**", "static/**",
"vite.config.*", "vite.config.*",
"svelte.config.*", "svelte.config.*",
"tsconfig*.json", "tsconfig*.json",
]), ]),
) )
``` ```
Run it with: When `node_modules` is provided, executables from `node_modules/.bin` are added
to `PATH`.
```bash ### `bun_dev` for local development
bazel run //path/to:web_dev -- --host
```
`bun_script` defaults to running from the directory containing `package.json`, which matches the usual expectations for `vite`, `svelte-kit`, and similar package scripts. Use `bun_dev` for long-running watch or hot-reload development targets.
## Development mode (`bun_dev`)
Use `bun_dev` for long-running local development with Bun watch mode.
```starlark ```starlark
load("@rules_bun//bun:defs.bzl", "bun_dev") load("@rules_bun//bun:defs.bzl", "bun_dev")
bun_dev( bun_dev(
name = "web_dev", name = "web_dev",
entry_point = "src/main.ts", entry_point = "src/main.ts",
# Optional: run from the entry point directory so Bun auto-loads colocated .env files. # Optional: run from the entry point directory so Bun auto-loads colocated .env files.
# working_dir = "entry_point", # working_dir = "entry_point",
) )
``` ```
Run it with: Supported development options include:
```bash - `watch_mode = "watch"`
bazel run //path/to:web_dev - `watch_mode = "hot"`
``` - `restart_on = [...]`
- `working_dir = "workspace" | "entry_point"`
`bun_dev` supports: ### Working directory behavior
- `watch_mode = "watch"` (default) for `bun --watch`
- `watch_mode = "hot"` for `bun --hot`
- `restart_on = [...]` to force full process restarts when specific files change
- `working_dir = "workspace" | "entry_point"` (default: `workspace`)
## Runtime working directory (`bun_binary`, `bun_dev`)
`bun_binary` and `bun_dev` support `working_dir`: `bun_binary` and `bun_dev` support `working_dir`:
- `"workspace"` (default): runs from the Bazel runfiles workspace root. - `"workspace"`: run from the Bazel runfiles workspace root.
- `"entry_point"`: runs from the nearest ancestor of the entry point that contains `.env` or `package.json` (falls back to the entry point directory). - `"entry_point"`: run from the nearest ancestor of the entry point that
contains `.env` or `package.json`.
Use `"entry_point"` when Bun should resolve local files such as colocated `.env` files relative to the program directory. ## Tests and examples
### Hybrid Go + Bun + protobuf workflow The repository keeps conformance and integration coverage in [tests/](tests/) and
usage samples in [examples/](examples/).
For monorepos that mix Go and Bun (including FFI): Representative example docs:
1. Run Bun app with native watch/HMR via `bun_dev`. - [examples/basic/README.md](examples/basic/README.md)
2. Put generated artifacts or bridge files in `restart_on` (for example generated JS/TS files from proto/go steps). - [examples/workspace/README.md](examples/workspace/README.md)
3. Rebuild Go/proto artifacts separately (for example with `ibazel build`) so their output files change.
4. `bun_dev` detects those `restart_on` changes and restarts Bun, while ordinary JS edits continue to use Bun watch/HMR without full Bazel restarts.
This keeps the fast Bun JS loop while still supporting full restarts when non-JS dependencies change. To validate the ruleset locally:
```bash
bazel test //tests/...
```

View File

@@ -1,3 +1,3 @@
0.1.0 0.2.1
stable stable
0 0

View File

@@ -1,5 +1,12 @@
workspace(name = "rules_bun") workspace(name = "rules_bun")
load("//internal:bun_install.bzl", "bun_install")
load("//bun:repositories.bzl", "bun_register_toolchains") load("//bun:repositories.bzl", "bun_register_toolchains")
bun_register_toolchains() bun_register_toolchains()
bun_install(
name = "script_test_vite_node_modules",
package_json = "//tests/script_test:vite_app/package.json",
bun_lockfile = "//tests/script_test:vite_app/bun.lock",
)

View File

@@ -5,6 +5,9 @@ load(":version.bzl", "BUN_VERSION")
exports_files([ exports_files([
"defs.bzl", "defs.bzl",
"extensions.bzl", "extensions.bzl",
"repositories.bzl",
"toolchain.bzl",
"version.bzl",
]) ])
bzl_library( bzl_library(
@@ -13,6 +16,19 @@ bzl_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
bzl_library(
name = "extensions_bzl",
srcs = ["extensions.bzl"],
visibility = ["//visibility:public"],
deps = ["//internal:bun_install_bzl"],
)
bzl_library(
name = "repositories_bzl",
srcs = ["repositories.bzl"],
visibility = ["//visibility:public"],
)
bzl_library( bzl_library(
name = "defs_bzl", name = "defs_bzl",
srcs = ["defs.bzl"], srcs = ["defs.bzl"],

View File

@@ -1,14 +1,80 @@
# rules_bun docs # rules_bun docs
Documentation site for `rules_bun`. Documentation for `rules_bun`, a Bazel ruleset for Bun.
## Ruleset layout
The repository exposes its public Bazel API from the [bun/](../bun/) package:
- `@rules_bun//bun:defs.bzl` for build rules
- `@rules_bun//bun:extensions.bzl` for Bzlmod extensions
- `@rules_bun//bun:repositories.bzl` for legacy WORKSPACE setup
Supporting material lives in:
- [examples/](../examples/) for usage samples
- [tests/](../tests/) for repository conformance and integration tests
- [docs/rules.md](rules.md) for generated rule reference
## Rule reference ## Rule reference
- [rules.md](rules.md) - [rules.md](rules.md)
## Typical Bzlmod setup
```starlark
bazel_dep(name = "rules_bun", version = "0.2.0")
bun_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun")
use_repo(
bun_ext,
"bun_linux_x64",
"bun_linux_aarch64",
"bun_darwin_x64",
"bun_darwin_aarch64",
"bun_windows_x64",
)
register_toolchains(
"@rules_bun//bun:darwin_aarch64_toolchain",
"@rules_bun//bun:darwin_x64_toolchain",
"@rules_bun//bun:linux_aarch64_toolchain",
"@rules_bun//bun:linux_x64_toolchain",
"@rules_bun//bun:windows_x64_toolchain",
)
```
## Vite package scripts
Use `bun_script` for package-script driven workflows such as `dev`, `build`,
and `preview`.
```starlark
load("@rules_bun//bun:defs.bzl", "bun_script")
bun_script(
name = "web_dev",
script = "dev",
package_json = "package.json",
node_modules = "@npm//:node_modules",
data = glob([
"src/**",
"public/**",
"index.html",
"vite.config.*",
"tsconfig*.json",
]),
)
```
`bun_script` runs from the package directory by default and adds
`node_modules/.bin` to `PATH`.
## Regeneration ## Regeneration
The rule reference is generated from Starlark rule docstrings: The rule reference is generated from the public Starlark symbols in
`@rules_bun//bun:defs.bzl`:
```bash ```bash
bazel build //docs:rules_md bazel build //docs:rules_md

View File

@@ -30,13 +30,17 @@ Attributes:
Runs a named `package.json` script with Bun as an executable target (`bazel run`). Runs a named `package.json` script with Bun as an executable target (`bazel run`).
Recommended for package-script based tools such as Vite (`dev`, `build`, `preview`).
When `node_modules` is provided, executables from `node_modules/.bin` are added
to `PATH`, so scripts like `vite` work without wrapper scripts.
Attributes: Attributes:
- `script` (string, required): package script name passed to `bun run <script>`. - `script` (string, required): package script name passed to `bun run <script>`.
- `package_json` (label, required): `package.json` file containing the named script. - `package_json` (label, required): `package.json` file containing the named script.
- `node_modules` (label, optional): Bun/npm package files in runfiles. - `node_modules` (label, optional): Bun/npm package files in runfiles.
- `data` (label_list, optional): additional runtime files for the script. - `data` (label_list, optional): additional runtime files for the script.
- `working_dir` (string, default: `"package"`, values: `"workspace" | "package"`): runtime working directory. - `working_dir` (string, default: `"package"`, values: `"workspace" | "package"`): runtime working directory. The default is a good fit for Vite and similar package-script based tools.
## bun_bundle ## bun_bundle

View File

@@ -46,7 +46,7 @@
]; ];
features = { features = {
oxfmt = true; oxfmt = false;
}; };
formatters = { formatters = {

View File

@@ -30,9 +30,13 @@ def _bun_install_repository_impl(repository_ctx):
fail("bun_install: bun_lockfile not found: {}".format(repository_ctx.attr.bun_lockfile)) fail("bun_install: bun_lockfile not found: {}".format(repository_ctx.attr.bun_lockfile))
bun_bin = _select_bun_binary(repository_ctx) bun_bin = _select_bun_binary(repository_ctx)
lockfile_name = bun_lockfile.basename
if lockfile_name not in ["bun.lock", "bun.lockb"]:
lockfile_name = "bun.lock"
repository_ctx.symlink(package_json, "package.json") repository_ctx.symlink(package_json, "package.json")
repository_ctx.symlink(bun_lockfile, "bun.lockb") repository_ctx.symlink(bun_lockfile, lockfile_name)
result = repository_ctx.execute( result = repository_ctx.execute(
[str(bun_bin), "--bun", "install", "--frozen-lockfile", "--no-progress"], [str(bun_bin), "--bun", "install", "--frozen-lockfile", "--no-progress"],
@@ -64,11 +68,11 @@ bun_install_repository = repository_rule(
attrs = { attrs = {
"package_json": attr.label(mandatory = True, allow_single_file = True), "package_json": attr.label(mandatory = True, allow_single_file = True),
"bun_lockfile": attr.label(mandatory = True, allow_single_file = True), "bun_lockfile": attr.label(mandatory = True, allow_single_file = True),
"bun_linux_x64": attr.label(default = "@bun_linux_x64//:bun", allow_single_file = True), "bun_linux_x64": attr.label(default = "@bun_linux_x64//:bun-linux-x64/bun", allow_single_file = True),
"bun_linux_aarch64": attr.label(default = "@bun_linux_aarch64//:bun", allow_single_file = True), "bun_linux_aarch64": attr.label(default = "@bun_linux_aarch64//:bun-linux-aarch64/bun", allow_single_file = True),
"bun_darwin_x64": attr.label(default = "@bun_darwin_x64//:bun", allow_single_file = True), "bun_darwin_x64": attr.label(default = "@bun_darwin_x64//:bun-darwin-x64/bun", allow_single_file = True),
"bun_darwin_aarch64": attr.label(default = "@bun_darwin_aarch64//:bun", allow_single_file = True), "bun_darwin_aarch64": attr.label(default = "@bun_darwin_aarch64//:bun-darwin-aarch64/bun", allow_single_file = True),
"bun_windows_x64": attr.label(default = "@bun_windows_x64//:bun", allow_single_file = True), "bun_windows_x64": attr.label(default = "@bun_windows_x64//:bun-windows-x64/bun.exe", allow_single_file = True),
}, },
) )

View File

@@ -23,6 +23,15 @@ bun_bin="${{runfiles_dir}}/_main/{bun_short_path}"
package_json="${{runfiles_dir}}/_main/{package_json_short_path}" package_json="${{runfiles_dir}}/_main/{package_json_short_path}"
package_dir="$(dirname "${{package_json}}")" package_dir="$(dirname "${{package_json}}")"
node_modules_bin_dirs=()
while IFS= read -r node_modules_bin; do
node_modules_bin_dirs+=("${{node_modules_bin}}")
done < <(find "${{runfiles_dir}}" -type d -path '*/node_modules/.bin' 2>/dev/null | sort)
if [[ ${{#node_modules_bin_dirs[@]}} -gt 0 ]]; then
export PATH="$(IFS=:; echo "${{node_modules_bin_dirs[*]}}"):${{PATH}}"
fi
working_dir="{working_dir}" working_dir="{working_dir}"
if [[ "${{working_dir}}" == "package" ]]; then if [[ "${{working_dir}}" == "package" ]]; then
cd "${{package_dir}}" cd "${{package_dir}}"
@@ -61,7 +70,10 @@ bun_script = rule(
doc = """Runs a named `package.json` script with Bun as an executable target. doc = """Runs a named `package.json` script with Bun as an executable target.
Use this rule to expose existing package scripts such as `dev`, `build`, or Use this rule to expose existing package scripts such as `dev`, `build`, or
`check` via `bazel run` without adding wrapper shell scripts. `check` via `bazel run` without adding wrapper shell scripts. This is a good fit
for Vite-style workflows, where scripts like `vite dev` or `vite build` are
declared in `package.json` and expect to run from the package directory with
`node_modules/.bin` available on `PATH`.
""", """,
attrs = { attrs = {
"script": attr.string( "script": attr.string(
@@ -74,7 +86,7 @@ Use this rule to expose existing package scripts such as `dev`, `build`, or
doc = "Label of the `package.json` file containing the named script.", doc = "Label of the `package.json` file containing the named script.",
), ),
"node_modules": attr.label( "node_modules": attr.label(
doc = "Optional label providing Bun/npm package files in runfiles.", doc = "Optional label providing Bun/npm package files in runfiles. Executables from `node_modules/.bin` are added to `PATH`, which is useful for scripts such as `vite`.",
), ),
"data": attr.label_list( "data": attr.label_list(
allow_files = True, allow_files = True,
@@ -83,7 +95,7 @@ Use this rule to expose existing package scripts such as `dev`, `build`, or
"working_dir": attr.string( "working_dir": attr.string(
default = "package", default = "package",
values = ["workspace", "package"], values = ["workspace", "package"],
doc = "Working directory at runtime: Bazel runfiles `workspace` root or the directory containing `package.json`.", doc = "Working directory at runtime: Bazel runfiles `workspace` root or the directory containing `package.json`. The default `package` mode matches tools such as Vite that resolve config and assets relative to the package directory.",
), ),
}, },
executable = True, executable = True,

View File

@@ -5,4 +5,4 @@ rule_file="$1"
grep -Fq 'set -euo pipefail' "${rule_file}" grep -Fq 'set -euo pipefail' "${rule_file}"
grep -Fq 'src_args = " ".join([_shell_quote(src.short_path) for src in ctx.files.srcs])' "${rule_file}" grep -Fq 'src_args = " ".join([_shell_quote(src.short_path) for src in ctx.files.srcs])' "${rule_file}"
grep -Fq 'exec "${{bun_bin}}" test {src_args} "$@"' "${rule_file}" grep -Fq 'exec "${{bun_bin}}" --bun test {src_args} "$@"' "${rule_file}"

View File

@@ -3,5 +3,5 @@ set -euo pipefail
rule_file="$1" rule_file="$1"
grep -Fq 'exec "${{bun_bin}}" test {src_args} --test-name-pattern "${{TESTBRIDGE_TEST_ONLY}}" "$@"' "${rule_file}" grep -Fq 'exec "${{bun_bin}}" --bun test {src_args} --test-name-pattern "${{TESTBRIDGE_TEST_ONLY}}" "$@"' "${rule_file}"
grep -Fq 'if [[ -n "${{TESTBRIDGE_TEST_ONLY:-}}" ]]' "${rule_file}" grep -Fq 'if [[ -n "${{TESTBRIDGE_TEST_ONLY:-}}" ]]' "${rule_file}"

View File

@@ -5,5 +5,7 @@ rule_file="$1"
grep -Eq 'install", "--frozen-lockfile", "--no-progress"' "${rule_file}" grep -Eq 'install", "--frozen-lockfile", "--no-progress"' "${rule_file}"
grep -Eq 'repository_ctx\.symlink\(package_json, "package\.json"\)' "${rule_file}" grep -Eq 'repository_ctx\.symlink\(package_json, "package\.json"\)' "${rule_file}"
grep -Eq 'repository_ctx\.symlink\(bun_lockfile, "bun\.lockb"\)' "${rule_file}" grep -Eq 'lockfile_name = bun_lockfile\.basename' "${rule_file}"
grep -Eq 'if lockfile_name not in \["bun\.lock", "bun\.lockb"\]:' "${rule_file}"
grep -Eq 'repository_ctx\.symlink\(bun_lockfile, lockfile_name\)' "${rule_file}"
grep -Eq 'glob\(\["node_modules/\*\*"\]' "${rule_file}" grep -Eq 'glob\(\["node_modules/\*\*"\]' "${rule_file}"

View File

@@ -31,3 +31,21 @@ sh_test(
args = ["$(location :env_script)"], args = ["$(location :env_script)"],
data = [":env_script"], data = [":env_script"],
) )
bun_script(
name = "vite_dev_server",
script = "dev",
package_json = "vite_app/package.json",
node_modules = "@script_test_vite_node_modules//:node_modules",
data = [
"vite_app/index.html",
"vite_app/main.js",
],
)
sh_test(
name = "bun_script_vite_app_test",
srcs = ["run_vite_app.sh"],
args = ["$(location :vite_dev_server)"],
data = [":vite_dev_server"],
)

View File

@@ -1,2 +1,2 @@
const value = process.env.BUN_SCRIPT_ENV_TEST ?? "missing"; const value = import.meta.env.BUN_SCRIPT_ENV_TEST ?? "missing";
console.log(value); console.log(value);

View File

@@ -5,5 +5,8 @@
"scripts": { "scripts": {
"hello": "bun ./hello.ts", "hello": "bun ./hello.ts",
"print-env": "bun ./env.ts" "print-env": "bun ./env.ts"
},
"devDependencies": {
"@types/bun": "^1.3.10"
} }
} }

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail
binary="$1"
workdir="$(mktemp -d)"
log_file="${workdir}/vite.log"
cleanup() {
if [[ -n ${server_pid:-} ]] && kill -0 "${server_pid}" 2>/dev/null; then
kill "${server_pid}" 2>/dev/null || true
wait "${server_pid}" 2>/dev/null || true
fi
rm -rf "${workdir}"
}
trap cleanup EXIT
port="$(
python3 - <<'PY'
import socket
sock = socket.socket()
sock.bind(("127.0.0.1", 0))
print(sock.getsockname()[1])
sock.close()
PY
)"
"${binary}" --host 127.0.0.1 --port "${port}" --strictPort >"${log_file}" 2>&1 &
server_pid=$!
for _ in {1..60}; do
if ! kill -0 "${server_pid}" 2>/dev/null; then
cat "${log_file}" >&2
echo "Vite server exited unexpectedly" >&2
exit 1
fi
if curl --fail --silent "http://127.0.0.1:${port}/" | grep -Fq "Vite via bun_script"; then
break
fi
sleep 0.5
done
if ! curl --fail --silent "http://127.0.0.1:${port}/" | grep -Fq "Vite via bun_script"; then
cat "${log_file}" >&2
echo "Timed out waiting for Vite index page" >&2
exit 1
fi
if ! curl --fail --silent "http://127.0.0.1:${port}/main.js" | grep -Fq "Hello from Vite"; then
cat "${log_file}" >&2
echo "Expected Vite module output was not served" >&2
exit 1
fi

View File

@@ -0,0 +1,127 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "vite-app-test",
"devDependencies": {
"vite": "5.4.14",
},
},
},
"packages": {
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="],
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="],
"@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="],
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="],
"@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="],
"@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="],
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="],
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
"rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"vite": ["vite@5.4.14", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA=="],
}
}

View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite via bun_script</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,7 @@
const app = document.querySelector("#app");
if (app) {
app.textContent = "Hello from Vite";
}
console.log("Hello from Vite");

View File

@@ -0,0 +1,11 @@
{
"name": "vite-app-test",
"private": true,
"type": "module",
"scripts": {
"dev": "vite"
},
"devDependencies": {
"vite": "5.4.14"
}
}