Skip to content

Commit

Permalink
chore: workaround the generated types going into the program
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeagle committed Jan 31, 2025
1 parent fdada2d commit 29fb9e2
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 16 deletions.
4 changes: 3 additions & 1 deletion frontend/WORKSPACE.bazel
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Marker that this folder is the root of a Bazel workspace
# This file should be removed once issues are fixed:
# https://github.com/bazel-contrib/bazel-gazelle/issues/2012
# https://github.com/bazelbuild/bazel-watcher/issues/646
24 changes: 13 additions & 11 deletions frontend/react-router/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
load("@aspect_rules_js//js:defs.bzl", "js_library", "js_run_binary", "js_run_devserver", "js_test")
load("@aspect_rules_ts//ts:defs.bzl", "ts_config")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//react-router:tsconfig-to-swcconfig/package_json.bzl", tsconfig_to_swcconfig = "bin")
load("@npm//react-router:@react-router/dev/package_json.bzl", react_router_bin = "bin")
load("@npm//react-router:@react-router/serve/package_json.bzl", react_router_serve_bin = "bin")
load("@npm//react-router:tsconfig-to-swcconfig/package_json.bzl", tsconfig_to_swcconfig = "bin")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -77,32 +77,32 @@ react_router_bin.react_router_binary(
# Runs a development server. Run this target under ibazel to use hot reloading.
js_run_devserver(
name = "dev",
tool = ":react_router",
chdir = package_name(),
args = ["dev"],
chdir = package_name(),
data = RUNTIME_DEPS + NPM_DEPS,
tool = ":react_router",
)

js_run_binary(
name = "build",
tool = ":react_router",
chdir = package_name(),
args = ["build"],
srcs = RUNTIME_DEPS + NPM_DEPS,
args = ["build"],
chdir = package_name(),
out_dirs = [
"build",
"public/build",
],
tool = ":react_router",
)

# Runs the production server.
react_router_serve_bin.react_router_serve_binary(
name = "start",
chdir = package_name(),
args = ["build/server/index.js"],
chdir = package_name(),
data = NPM_DEPS + [
":build",
"package.json",
":build",
],
)

Expand All @@ -115,13 +115,15 @@ js_test(
entry_point = "build_smoke_test.js",
)

# Produce `+types/<route file>.d.ts` files, see
# https://reactrouter.com/explanation/type-safety#typegen-command
js_run_binary(
name = "typegen",
tool = ":react_router",
chdir = package_name(),
args = ["typegen"],
srcs = RUNTIME_DEPS + NPM_DEPS,
args = ["typegen"],
chdir = package_name(),
out_dirs = [
".react-router",
],
tool = ":react_router",
)
48 changes: 44 additions & 4 deletions frontend/react-router/app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file")
load("@aspect_bazel_lib//lib:directory_path.bzl", "directory_path")
load("@aspect_rules_js//js:defs.bzl", "js_library")
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
load("//:vitest.bzl", "vitest")
Expand All @@ -15,16 +17,55 @@ js_library(
visibility = ["//react-router:__subpackages__"],
)

#############
# WORKAROUND for this react-router codegen pattern.
# https://reactrouter.com/how-to/route-module-type-safety relies on TypeScript "rootDirs" feature to make
# two different physical folders be "merged" into a logical folder within the TypeScript Program.
# This allows a cycle: the generated files in the +types folder to reference our sources, and our sources reference those files.
# Alex: I studied this a bit, though my knowledge is rusty.
# Under Bazel, we expect the `ts_project` rule can control the rootDir, and that the graph is acyclic, so this shape doesn't work.
# The simple answer is to use Bazel actions to actually merge the two folders together, so by the time the Type-Checker produces a Program,
# there's no longer a need for rootDirs.
# The downside is that we have to enumerate all the generated files here, and the boilerplate of copying them.

# Reference files within the genereted typegen folder
directory_path(
name = "root_type",
directory = "//react-router:typegen",
path = "types/app/+types/root.ts",
)

directory_path(
name = "home_type",
directory = "//react-router:typegen",
path = "types/app/routes/+types/home.ts",
)

# Copy those files as if they were part of the source tree.
copy_file(
name = "copy_type1",
src = "root_type",
out = "+types/root.ts",
)

copy_file(
name = "copy_type2",
src = "home_type",
out = "routes/+types/home.ts",
)

ts_project(
name = "app",
srcs = glob(
include = SRC_PATTERNS,
allow_empty = True,
exclude = TEST_PATTERNS,
),
) + [
":copy_type1",
":copy_type2",
],
data = [
":assets",
"//react-router:typegen",
],
declaration = True,
resolve_json_module = True,
Expand All @@ -34,7 +75,6 @@ ts_project(
deps = [
"//react-router:node_modules/@react-router/dev",
"//react-router:node_modules/@react-router/node",
"//react-router:node_modules/@react-router/serve",
"//react-router:node_modules/@types/node",
"//react-router:node_modules/@types/react",
"//react-router:node_modules/isbot",
Expand All @@ -54,7 +94,7 @@ ts_project(
declaration = True,
resolve_json_module = True,
transpiler = TRANSPILER,
tsconfig = "//react:tsconfig",
tsconfig = "//react-router:tsconfig",
deps = [
":app",
"//:node_modules/vitest",
Expand Down

0 comments on commit 29fb9e2

Please sign in to comment.