Codync
免费开源的 1:1 Grok Bot 与 Muse 替代方案。可在 iPhone、Mac 或 Linux 桌面上将 Claude 代码、Codex、Cursor 以及 40 多个编码代理作为持久机器人使用。支持群组聊天、线程、应用。
AI 翻译
尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
TypeScript rules for Bazel using Oxc and tsgo. TypeScript on Bazel should feel like Go on Bazel.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗TypeScript programs are source-native by default: ts_compile and ts_test keep tsgo validation and emit no application JavaScript or declarations. Opt in with emit = True where a JavaScript-only runtime or declaration consumer requires built files; Gazelle follows those consumer requirements.
An opinionated Bazel ruleset for TypeScript, built around Oxc and tsgo. It builds TypeScript packages and provides a source-built dev server. For a different build model, see aspect-build/rules_ts.
Rust and Go do the work: Oxc compiles an ES-module program and tsgo a CommonJS-shaped one; tsgo type-checks. The default dev server is oj 0.3.1. Vite remains an explicit option. Gazelle writes the BUILD files. Write .ts, run Gazelle, bazel build //.... The build reads no node_modules/. No system Node. Just Bazelisk.
Coming from an existing TypeScript repository: Install is the short path, and the Quick Start covers the migration questions.
Full documentation: mikn.github.io/rules_typescript
emit = True, Rust-based TypeScript/JSX transformer: .js + .js.map per file, and .d.ts too under --//ts:declarations=oxc. A program whose module is CommonJS-shaped is tsgo's emit — see The Module Format.emit = True, emits declarations too: no export annotations required, and the .d.ts are what tsc would produce. The check is a validation on every target and fails bazel build on a type error; the declarations are emitted where a dependent reads them.emit = False on compile and test targets retains tsgo validation while removing JavaScript and declaration emission from their runtime path. See source-only programs for supported consumers and package manifests.ts_dev_server(server = ...) takes any target providing DevServerInfo. oj 0.3.1 is the default; select @rules_typescript//vite:dev_server for Vite. What a server does not read is declared in its provider, so a target depending on a field its server ignores fails at analysis time naming both.--//ts:declarations=oxc, and Oxc emits the .d.ts syntactically, so a dependent waits for a per-file transform rather than for tsgo's declaration emit, which shortens a deep dependency chain substantially. Opt-in, per build — see Cost of each mode.tsconfig.json or existing manifest entry points, with sources and deps read off tsgo's own listing, without program-membership directives. It regenerates the attributes it owns on every run and names every value it drops, so a value it cannot derive needs # keep — see Attributes Gazelle owns.The only prerequisite is Bazelisk (or Bazel 9+). Bazel fetches the Rust and Go toolchains, Node.js, and the npm packages your targets reach. It compiles oxc-bazel and the four Go tools from source. Later builds can reuse their cached outputs. Prebuilt Go tools are an explicit option.
Supported platforms: Linux x86_64, Linux ARM64, macOS x86_64, macOS ARM64. Windows is not supported right now. It may be considered in the future. See COMPATIBILITY.md.
No module release has shipped. There is no v* tag, no Bazel Central
Registry entry and no production users. No tools release has been published. Pre-1.0, any commit may break the API
with no deprecation window. Every released break is listed in
CHANGELOG.md with the edit it requires, and every unreleased one
in changelog.d/; read both before moving a pin. Full policy:
COMPATIBILITY.md.
Vite and vitest are your dependencies, not the ruleset's: they come from your own lockfile, and the rules generate configuration for whichever version it resolves to. The versions the tests exercise, and the places a generated config is version-sensitive, are in COMPATIBILITY.md.
LLVM BCR 0.8.21 can omit Clang builtin headers when a sandbox presents the resource directory as a symlink. Until an LLVM release includes the fix, consumers must copy the resource-directory patch into their workspace root and copy the explicit root archive_override from the React example MODULE, which applies that patch to the checksum-pinned 0.8.21 archive. Bazel does not inherit dependency overrides from this ruleset. Remove the override when upgrading to the fixed upstream release; no release containing the repair is claimed yet.
The patch preserves the compiler's headers and shared resources while excluding its host runtime libraries. The measured RE builds pass without the patch because their inputs are materialised directories; that alone does not verify sandbox builds. The upstream submission is prepared for the maintainer; see the affected LLVM rule.
Step 1. Create .bazelversion:
9.2.0
Step 2. Add to MODULE.bazel. The ruleset is not on the Bazel Central
Registry yet, so bazel_dep alone has nothing to resolve against; pin it from
git:
module(name = "my_project", version = "0.0.0")
bazel_dep(name = "rules_typescript", version = "0.2.0")
git_override(
module_name = "rules_typescript",
remote = "https://github.com/mikn/rules_typescript.git",
commit = "REPLACE_WITH_A_COMMIT_SHA_FROM_MAIN",
)
register_toolchains("@rules_typescript//ts/toolchain:all")
bazel_dep(name = "gazelle", version = "0.51.3")
Pin a full commit SHA, not a branch. bzlmod still requires version on
bazel_dep and ignores its value while the override is active. The
archive_override (smaller fetch) and local_path_override forms are in
Depending on rules_typescript.
Step 3. Add to .bazelrc:
build --incompatible_strict_action_env
build --nolegacy_external_runfiles
build --output_groups=+_validation
Those three lines are the whole file. Do not add an @rules_rust flag:
rules_rust is not exposed by rules_typescript to your
module, so Bazel cannot resolve the label and rejects the invocation with
No repository visible as '@rules_rust' from main repository.
Step 4. Add to BUILD.bazel at the repository root:
load("@gazelle//:def.bzl", "gazelle")
gazelle(
name = "gazelle",
gazelle = "@rules_typescript//gazelle:gazelle_typescript",
tags = ["manual"],
)
Point at gazelle_typescript, not gazelle_ts. gazelle_ts also carries the Go
and proto languages, for this repository's own .go sources, and in a polyglot
repo it rewrites Go BUILD files too.
Step 5. Write TypeScript, with a tsconfig.json in the directory that is
to be a package: Gazelle writes one ts_compile per tsconfig.json, over what
the program lists. Export annotations are optional: tsgo emits the declarations
from the full type program, so an inferred return type is fine:
// src/lib/math.ts, beside src/lib/tsconfig.json
export function add(a: number, b: number) {
return a + b;
}
Step 6. Generate BUILD files, build, and test:
bazel run //:gazelle
bazel build //...
bazel test //...
The npm extension is reproducible: consumers’ MODULE.bazel.lock contains no npm extension metadata. Bazel derives repository definitions from the watched pnpm lockfile, workspace/npmrc files, member manifests and patch bytes; changing those inputs refreshes the graph. Package downloads still use the lockfile’s integrity checks.
One-time setup in MODULE.bazel:
npm = use_extension("@rules_typescript//npm:extensions.bzl", "npm")
npm.translate_lock(pnpm_lock = "//:pnpm-lock.yaml")
use_repo(npm, "npm", "pnpm")
"pnpm" is the hermetic pnpm behind the ts_pnpm and ts_add_package targets
you write into your root BUILD.bazel
(Hermetic pnpm).
Then, per package:
bazel run //:pnpm -- add zod # updates pnpm-lock.yaml and installs it
bazel run //:gazelle # lists each tsconfig.json with tsgo, writes deps
bazel build //... # fetches just that package's closure, builds
Bazel fetches a package the first time a target needs it. Build actions use Bazel’s npm store. Gazelle and editor tools can read the checkout’s installed node_modules/; keep those directories out of Git.
bazel run //:pnpm -- add zod --lockfile-only uses a hermetic pnpm
(two lines of setup).
ts_refresh_tsconfig writes the workspace-root tsconfig.json from Bazel's
build graph: one compilerOptions.paths entry per first-party package your
targets reach, source directory and bazel-bin twin. The file is checked in,
and test = True adds a test that fails once it goes stale. An editor, a plain
tsc run and a coding agent's language server resolve Bazel's declarations
through it with no setup; npm packages resolve through the checkout's
node_modules, so pnpm install is the editor's npm setup. A tsserver plugin
installed alongside it resolves live, without a re-run; the plugin needs editor
configuration.
# BUILD.bazel
load("@rules_typescript//ts:defs.bzl", "ts_refresh_tsconfig")
ts_refresh_tsconfig(
name = "refresh_tsconfig",
test = True,
deps = [
"//apps/web",
"//packages/design-system",
],
)
deps is the whole input. An aspect walks it, so listing a target covers
everything it depends on; the default, deps = [], writes an empty paths. It
obeys visibility, so a package-private target cannot be listed.
bazel run //:refresh_tsconfig # writes tsconfig.json and the plugin
bazel test //:refresh_tsconfig_test # fails when the checked-in tsconfig is stale
The plugin is optional. To turn it on, point tsserver's plugin probe at .bazel
and name @rules_typescript/tsserver-plugin. The per-editor recipes, and the
coding-agent case, are in
IDE Setup.
nested_tsconfigs lists the packages that need their own editor program, as
workspace-relative paths to the tsconfig.json each one gets. A package belongs
there when its targets set compilerOptions the root block cannot also be set
to. The list is declared, not discovered. The rule fails at analysis time when
the list disagrees with the graph in either direction, so a repository with one
such package fails the snippet above until the list is filled in. That attribute,
extra_exclude and the other editors are in
IDE Setup.
tsconfig.json plus live tsserver resolution from Bazel's build graph (TypeScript's GOPACKAGESDRIVER)ts_test, snapshots, sharding, watch mode with ibazel; runner = "@rules_typescript//ts/runners:node_test" for tests written against node's own runnerts_binary with any BundlerInfo-compatible bundlerDevServerInfo rule through servertsconfig.json, cross-package .d.ts caching# keepMIT
bazel run //:gazelle writes it.@npm alias hub, so a target fetches only its own dependency closure. pnpm's virtual store is built as Bazel artifacts — one cached tree per resolution (name, version and peer set) — and each importer's node_modules links into it, so a target resolves what its importer declared.ts_proto_libraryproto_library