Skip to content

Commit 8daac72

Browse files
committed
Merge branch 'dev' into release-next
2 parents 18dc8b8 + cae658e commit 8daac72

File tree

88 files changed

+2238
-3110
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2238
-3110
lines changed

.changeset/eighty-dolls-juggle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
Enable prerendering for resource routes

.changeset/serious-beds-approve.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
resolve config directory relative to flat output file structure

.github/workflows/shared-build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ jobs:
2222
node-version-file: ".nvmrc"
2323
cache: "pnpm"
2424

25+
- uses: google/wireit@setup-github-actions-caching/v2
26+
2527
- name: Disable GitHub Actions Annotations
2628
run: |
2729
echo "::remove-matcher owner=tsc::"

.github/workflows/shared-integration.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ jobs:
4545
node-version: ${{ matrix.node }}
4646
cache: "pnpm"
4747

48+
- uses: google/wireit@setup-github-actions-caching/v2
49+
4850
- name: Disable GitHub Actions Annotations
4951
run: |
5052
echo "::remove-matcher owner=tsc::"

.github/workflows/test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ jobs:
4545
cache: pnpm
4646
check-latest: true
4747

48+
- uses: google/wireit@setup-github-actions-caching/v2
49+
4850
- name: Disable GitHub Actions Annotations
4951
run: |
5052
echo "::remove-matcher owner=tsc::"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ node_modules/
2222
/packages/*/dist/
2323
/packages/*/LICENSE.md
2424

25+
.wireit
2526
.eslintcache
2627
.tmp
2728
/.env

DEVELOPMENT.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ Changesets will do most of the heavy lifting for our releases. When changes are
2222
- `git commit -a -m "Enter prerelease mode"`
2323
- `git push --set-upstream origin release-next`
2424
- Wait for the release workflow to finish - the Changesets action will open a PR that will increment all versions and generate the changelogs
25-
- Check out the PR branch created by changesets locally
26-
- _Optional:_ Review the updated `CHANGELOG.md` files in the PR locally and make any adjustments necessary, then merge the PR into the `release-next` branch.
27-
- `find packages -name 'CHANGELOG.md' -mindepth 2 -maxdepth 2 -exec code {} \;`
28-
- Usually for prereleases there's not much to change here because the prerelease sections will be deleted prior to the final stable release anyway
25+
- If you need/want to make any changes to the `CHANGELOG.md` files, you can do so and commit directly to the PR branch
26+
- This is usually not required for prereleases
2927
- Once the changesets files are in good shape, merge the PR to `release-next`
3028
- Once the PR is merged, the release workflow will publish the updated `X.Y.Z-pre.*` packages to npm
29+
30+
### Prepare the draft release notes
31+
3132
- At this point, you can begin crafting the release notes for the eventual stable release in the root `CHANGELOG.md` file in the repo
3233
- Copy the template for a new release and update the version numbers and links accordingly
3334
- Copy the relevant changelog entries from all packages into the release notes and adjust accordingly
35+
- `find packages -name 'CHANGELOG.md' -mindepth 2 -maxdepth 2 -exec code {} \;`
3436
- Commit these changes directly to the `release-next` branch - they will not trigger a new prerelease since they do not include a changeset
3537

3638
### Iterating a pre-release
@@ -96,15 +98,24 @@ After the `6.25.0` release, we branched off a `v6` branch for continued `6.x` wo
9698
- Once the stable release is out:
9799
- Merge `release-v6` back to `v6` with a **Normal Merge**
98100
- **Do not** merge `release-v6` to `main`
99-
- Copy the updated changelog entry for the `6.X.Y` version to `main`
101+
- Copy the updated root `CHANGELOG.md` entry for the `6.X.Y` release to `main` and `dev`
102+
- `git checkout main`
103+
- `git diff [email protected]@6.X.Y -- "***CHANGELOG.md" > ./docs.patch`
104+
- `git apply ./docs.patch`
105+
- `git checkout dev`
106+
- `git apply ./docs.patch`
107+
- `rm ./docs.patch`
100108
- Copy the docs changes to `main` so they show up on the live docs site for v6
101109
- `git checkout main`
102110
- `git diff [email protected]@6.X.Y docs/ > ./docs.patch`
103111
- `git apply ./docs.patch`
104-
- The _code_ changes should already be in the `dev` branch but confirm that the commits in this release are all included in `dev` already:
105-
- I.e., https://github.com/remix-run/react-router/compare/[email protected]@6.26.2
106-
- If one or more are not, then you can manually bring them over by cherry-picking the commit (or re-doing the work)
107-
- You should not include a changelog in your commit to `dev`
112+
- `rm ./docs.patch`
113+
- The _code_ changes should already be in the `dev` branch
114+
- This should have happened at the time the v6 change was made (except for changes such as deprecation warnings)
115+
- Confirm that the commits in this release are all included in `dev` already:
116+
- I.e., https://github.com/remix-run/react-router/compare/[email protected]@6.26.2
117+
- If one or more are not, then you can manually bring them over by cherry-picking the commit (or re-doing the work)
118+
- You should not include a changelog in your commit to `dev`
108119
- Copy the updated changelogs from `release-next` over to `dev` so the changelogs continue to reflect this new 6x release into the v7 releases
109120

110121
### Notes on 7.0.0-pre.N released during the v7 prerelease

build.utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function createBanner(packageName: string, version: string) {
2+
return `/**
3+
* ${packageName} v${version}
4+
*
5+
* Copyright (c) Remix Software Inc.
6+
*
7+
* This source code is licensed under the MIT license found in the
8+
* LICENSE.md file in the root directory of this source tree.
9+
*
10+
* @license MIT
11+
*/`;
12+
}

decisions/0011-routes-ts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,4 @@ As of the creation of this decision document, the only available build context i
9292

9393
### Remix's `routes` option has an adapter for easy migration
9494

95-
Some Remix consumers used the `routes` option to define config-based routes or use community file system routing conventions. To ease the migration, the `@react-router/remix-config-routes-adapter` package provides a `remixConfigRoutes` function that accepts Remix's `routes` config value as an argument.
95+
Some Remix consumers used the `routes` option to define config-based routes or use community file system routing conventions. To ease the migration, the `@react-router/remix-routes-option-adapter` package provides a `remixRoutesOptionAdapter` function that accepts Remix's `routes` config value as an argument.

docs/start/testing.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ order: 9
55

66
# Testing
77

8-
When components use things like `useLoaderData`, `<Link>`, etc, they are required to be rendered in context of a React Router app. The `createStub` function creates that context to test components in isolation.
8+
When components use things like `useLoaderData`, `<Link>`, etc, they are required to be rendered in context of a React Router app. The `createRoutesStub` function creates that context to test components in isolation.
99

1010
Consider a login form component that relies on `useActionData`
1111

@@ -32,19 +32,20 @@ export function LoginForm() {
3232
}
3333
```
3434

35-
We can test this component with `createStub`. It takes an array of objects that resemble route modules with loaders, actions, and components.
35+
We can test this component with `createRoutesStub`. It takes an array of objects that resemble route modules with loaders, actions, and components.
3636

3737
```tsx
38-
import { createStub, route } from "react-router/testing";
38+
import { createRoutesStub } from "react-router";
3939
import * as Test from "@testing-library/react";
4040
import { LoginForm } from "./LoginForm";
4141

4242
test("LoginForm renders error messages", async () => {
4343
const USER_MESSAGE = "Username is required";
4444
const PASSWORD_MESSAGE = "Password is required";
4545

46-
const Stub = createStub([
47-
route("/login", {
46+
const Stub = createRoutesStub([
47+
{
48+
path: "/login",
4849
Component: LoginForm,
4950
action() {
5051
return {

integration/fs-routes-test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ test.describe("fs-routes", () => {
2828
"app/routes.ts": js`
2929
import { type RouteConfig } from "@react-router/dev/routes";
3030
import { flatRoutes } from "@react-router/fs-routes";
31-
import { remixConfigRoutes } from "@react-router/remix-config-routes-adapter";
31+
import { remixRoutesOptionAdapter } from "@react-router/remix-routes-option-adapter";
3232
3333
export const routes: RouteConfig = [
3434
...await flatRoutes({
3535
ignoredRouteFiles: ["**/ignored-route.*"],
3636
}),
3737
3838
// Ensure Remix back compat layer works
39-
...await remixConfigRoutes(async (defineRoutes) => {
39+
...await remixRoutesOptionAdapter(async (defineRoutes) => {
4040
// Ensure async routes work
4141
return defineRoutes((route) => {
4242
route("/remix/config/route", "remix-config-route.tsx")

integration/helpers/create-fixture.ts

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Writable } from "node:stream";
2+
import { Readable } from "node:stream";
23
import path from "node:path";
34
import url from "node:url";
45
import fse from "fs-extra";
@@ -15,6 +16,7 @@ import {
1516
UNSAFE_decodeViaTurboStream as decodeViaTurboStream,
1617
} from "react-router";
1718
import { createRequestHandler as createExpressHandler } from "@react-router/express";
19+
import { createReadableStreamFromReadable } from "@react-router/node";
1820

1921
import { viteConfig } from "./vite.js";
2022

@@ -54,40 +56,23 @@ export async function createFixture(init: FixtureInit, mode?: ServerMode) {
5456
);
5557
};
5658

57-
if (init.spaMode || init.prerender) {
58-
let requestDocument = init.spaMode
59-
? () => {
60-
let html = fse.readFileSync(
61-
path.join(projectDir, "build/client/index.html")
62-
);
63-
return new Response(html, {
64-
headers: {
65-
"Content-Type": "text/html",
66-
},
67-
});
68-
}
69-
: (href: string) => {
70-
let pathname = new URL(href, "test://test").pathname;
71-
let file = pathname.endsWith(".data")
72-
? pathname
73-
: pathname + "/index.html";
74-
let html = fse.readFileSync(
75-
path.join(projectDir, "build/client" + file)
76-
);
77-
return new Response(html, {
78-
headers: {
79-
"Content-Type": "text/html",
80-
},
81-
});
82-
};
83-
59+
if (init.spaMode) {
8460
return {
8561
projectDir,
8662
build: null,
8763
isSpaMode: init.spaMode,
8864
prerender: init.prerender,
89-
requestDocument,
90-
requestResource: () => {
65+
requestDocument() {
66+
let html = fse.readFileSync(
67+
path.join(projectDir, "build/client/index.html")
68+
);
69+
return new Response(html, {
70+
headers: {
71+
"Content-Type": "text/html",
72+
},
73+
});
74+
},
75+
requestResource() {
9176
throw new Error("Cannot requestResource in SPA Mode tests");
9277
},
9378
requestSingleFetchData: () => {
@@ -101,6 +86,49 @@ export async function createFixture(init: FixtureInit, mode?: ServerMode) {
10186
};
10287
}
10388

89+
if (init.prerender) {
90+
return {
91+
projectDir,
92+
build: null,
93+
isSpaMode: init.spaMode,
94+
prerender: init.prerender,
95+
requestDocument(href: string) {
96+
let file = new URL(href, "test://test").pathname + "/index.html";
97+
let html = fse.readFileSync(
98+
path.join(projectDir, "build/client" + file)
99+
);
100+
return new Response(html, {
101+
headers: {
102+
"Content-Type": "text/html",
103+
},
104+
});
105+
},
106+
requestResource(href: string) {
107+
let data = fse.readFileSync(
108+
path.join(projectDir, "build/client", href)
109+
);
110+
return new Response(data);
111+
},
112+
async requestSingleFetchData(href: string) {
113+
let data = fse.readFileSync(
114+
path.join(projectDir, "build/client", href)
115+
);
116+
let stream = createReadableStreamFromReadable(Readable.from(data));
117+
return {
118+
status: 200,
119+
statusText: "OK",
120+
headers: new Headers(),
121+
data: (await decodeViaTurboStream(stream, global)).value,
122+
};
123+
},
124+
postDocument: () => {
125+
throw new Error("Cannot postDocument in Prerender tests");
126+
},
127+
getBrowserAsset,
128+
useReactRouterServe: init.useReactRouterServe,
129+
};
130+
}
131+
104132
let app: ServerBuild = await import(buildPath);
105133
let handler = createRequestHandler(app, mode || ServerMode.Production);
106134

@@ -316,33 +344,14 @@ export async function createFixtureProject(
316344
init: FixtureInit = {},
317345
mode?: ServerMode
318346
): Promise<string> {
319-
let template = "node-template";
347+
let template = "vite-template";
320348
let integrationTemplateDir = path.resolve(__dirname, template);
321349
let projectName = `rr-${template}-${Math.random().toString(32).slice(2)}`;
322350
let projectDir = path.join(TMP_DIR, projectName);
323351
let port = init.port ?? (await getPort());
324352

325353
await fse.ensureDir(projectDir);
326354
await fse.copy(integrationTemplateDir, projectDir);
327-
// let reactRouterDev = path.join(
328-
// projectDir,
329-
// "node_modules/@react-router/dev/dist/cli/index.js"
330-
// );
331-
// await fse.chmod(reactRouterDev, 0o755);
332-
// await fse.ensureSymlink(
333-
// reactRouterDev,
334-
// path.join(projectDir, "node_modules/.bin/rr")
335-
// );
336-
//
337-
// let reactRouterServe = path.join(
338-
// projectDir,
339-
// "node_modules/@react-router/serve/dist/cli.js"
340-
// );
341-
// await fse.chmod(reactRouterServe, 0o755);
342-
// await fse.ensureSymlink(
343-
// reactRouterServe,
344-
// path.join(projectDir, "node_modules/.bin/react-router-serve")
345-
// );
346355

347356
let hasViteConfig = Object.keys(init.files ?? {}).some((filename) =>
348357
filename.startsWith("vite.config.")

integration/helpers/node-template/.gitignore

Lines changed: 0 additions & 6 deletions
This file was deleted.

integration/helpers/node-template/app/root.tsx

Lines changed: 0 additions & 19 deletions
This file was deleted.

integration/helpers/node-template/app/routes.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

integration/helpers/node-template/app/routes/_index.tsx

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)