Skip to content

Commit

Permalink
Merge branch 'release-next' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 committed Dec 13, 2023
2 parents f2b4d53 + 03c5cb5 commit 37ee74e
Show file tree
Hide file tree
Showing 17 changed files with 770 additions and 37 deletions.
419 changes: 416 additions & 3 deletions integration/client-data-test.ts

Large diffs are not rendered by default.

153 changes: 153 additions & 0 deletions packages/remix-dev/CHANGELOG.md
@@ -1,5 +1,158 @@
# `@remix-run/dev`

## 2.4.0

### Minor Changes

- Vite: exclude modules within `.server` directories from client build ([#8154](https://github.com/remix-run/remix/pull/8154))

- Add support for `clientLoader`/`clientAction`/`HydrateFallback` route exports ([RFC](https://github.com/remix-run/remix/discussions/7634)) ([#8173](https://github.com/remix-run/remix/pull/8173))

Remix now supports loaders/actions that run on the client (in addition to, or instead of the loader/action that runs on the server). While we still recommend server loaders/actions for the majority of your data needs in a Remix app - these provide some levers you can pull for more advanced use-cases such as:

- Leveraging a data source local to the browser (i.e., `localStorage`)
- Managing a client-side cache of server data (like `IndexedDB`)
- Bypassing the Remix server in a BFF setup and hitting your API directly from the browser
- Migrating a React Router SPA to a Remix application

By default, `clientLoader` will not run on hydration, and will only run on subsequent client side navigations.

If you wish to run your client loader on hydration, you can set `clientLoader.hydrate=true` to force Remix to execute it on initial page load. Keep in mind that Remix will still SSR your route component so you should ensure that there is no new _required_ data being added by your `clientLoader`.

If your `clientLoader` needs to run on hydration and adds data you require to render the route component, you can export a `HydrateFallback` component that will render during SSR, and then your route component will not render until the `clientLoader` has executed on hydration.

`clientAction` is simpler than `clientLoader` because it has no hydration use-cases. `clientAction` will only run on client-side navigations.

For more information, please refer to the [`clientLoader`](https://remix.run/route/client-loader) and [`clientAction`](https://remix.run/route/client-action) documentation.

- Vite: Strict route exports ([#8171](https://github.com/remix-run/remix/pull/8171))

With Vite, Remix gets stricter about which exports are allowed from your route modules.
Previously, the Remix compiler would allow any export from routes.
While this was convenient, it was also a common source of bugs that were hard to track down because they only surfaced at runtime.

For more, see <https://remix.run/docs/en/main/future/vite#strict-route-exports>

- Add a new `future.v3_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. For more information, please see the React Router [`6.21.0` Release Notes](https://github.com/remix-run/react-router/blob/release-next/CHANGELOG.md#futurev7_relativesplatpath) and the [`useResolvedPath` docs](https://remix.run/hooks/use-resolved-path#splat-paths). ([#8216](https://github.com/remix-run/remix/pull/8216))

### Patch Changes

- Upgrade Vite peer dependency range to v5 ([#8172](https://github.com/remix-run/remix/pull/8172))

- Support HMR for routes with `handle` export in Vite dev ([#8022](https://github.com/remix-run/remix/pull/8022))

- Fix flash of unstyled content for non-Express custom servers in Vite dev ([#8076](https://github.com/remix-run/remix/pull/8076))

- Bundle CSS imported in client entry file in Vite plugin ([#8143](https://github.com/remix-run/remix/pull/8143))

- Change Vite build output paths to fix a conflict between how Vite and the Remix compiler each manage the `public` directory. ([#8077](https://github.com/remix-run/remix/pull/8077))

**This is a breaking change for projects using the unstable Vite plugin.**

The server is now compiled into `build/server` rather than `build`, and the client is now compiled into `build/client` rather than `public`.

For more information on the changes and guidance on how to migrate your project, refer to the updated [Remix Vite documentation](https://remix.run/docs/en/main/future/vite).

- Remove undocumented `legacyCssImports` option from Vite plugin due to issues with `?url` imports of CSS files not being processed correctly in Vite ([#8096](https://github.com/remix-run/remix/pull/8096))

- Vite: fix access to default `entry.{client,server}.tsx` within pnpm workspace on Windows ([#8057](https://github.com/remix-run/remix/pull/8057))

- Remove `unstable_createViteServer` and `unstable_loadViteServerBuild` which were only minimal wrappers around Vite's `createServer` and `ssrLoadModule` functions when using a custom server. ([#8120](https://github.com/remix-run/remix/pull/8120))

**This is a breaking change for projects using the unstable Vite plugin with a custom server.**

Instead, we now provide `unstable_viteServerBuildModuleId` so that custom servers interact with Vite directly rather than via Remix APIs, for example:

```diff
-import {
- unstable_createViteServer,
- unstable_loadViteServerBuild,
-} from "@remix-run/dev";
+import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
```

Creating the Vite server in middleware mode:

```diff
const vite =
process.env.NODE_ENV === "production"
? undefined
- : await unstable_createViteServer();
+ : await import("vite").then(({ createServer }) =>
+ createServer({
+ server: {
+ middlewareMode: true,
+ },
+ })
+ );
```

Loading the Vite server build in the request handler:

```diff
app.all(
"*",
createRequestHandler({
build: vite
- ? () => unstable_loadViteServerBuild(vite)
+ ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
: await import("./build/server/index.js"),
})
);
```

- Pass request handler errors to `vite.ssrFixStacktrace` in Vite dev to ensure stack traces correctly map to the original source code ([#8066](https://github.com/remix-run/remix/pull/8066))

- Vite: Preserve names for exports from .client imports ([#8200](https://github.com/remix-run/remix/pull/8200))

Unlike `.server` modules, the main idea is not to prevent code from leaking into the server build
since the client build is already public. Rather, the goal is to isolate the SSR render from client-only code.
Routes need to import code from `.client` modules without compilation failing and then rely on runtime checks
to determine if the code is running on the server or client.

Replacing `.client` modules with empty modules would cause the build to fail as ESM named imports are statically analyzed.
So instead, we preserve the named export but replace each exported value with an empty object.
That way, the import is valid at build time and the standard runtime checks can be used to determine if then
code is running on the server or client.

- Add `@remix-run/node` to Vite's `optimizeDeps.include` array ([#8177](https://github.com/remix-run/remix/pull/8177))

- Improve Vite plugin performance ([#8121](https://github.com/remix-run/remix/pull/8121))

- Parallelize detection of route module exports
- Disable `server.preTransformRequests` in Vite child compiler since it's only used to process route modules

- Remove automatic global Node polyfill installation from the built-in Vite dev server and instead allow explicit opt-in. ([#8119](https://github.com/remix-run/remix/pull/8119))

**This is a breaking change for projects using the unstable Vite plugin without a custom server.**

If you're not using a custom server, you should call `installGlobals` in your Vite config instead.

```diff
import { unstable_vitePlugin as remix } from "@remix-run/dev";
+import { installGlobals } from "@remix-run/node";
import { defineConfig } from "vite";

+installGlobals();

export default defineConfig({
plugins: [remix()],
});
```

- Vite: Errors at build-time when client imports .server default export ([#8184](https://github.com/remix-run/remix/pull/8184))

Remix already stripped .server file code before ensuring that server code never makes it into the client.
That results in errors when client code tries to import server code, which is exactly what we want!
But those errors were happening at runtime for default imports.
A better experience is to have those errors happen at build-time so that you guarantee that your users won't hit them.

- Fix `request instanceof Request` checks when using Vite dev server ([#8062](https://github.com/remix-run/remix/pull/8062))

- Updated dependencies:
- `@remix-run/server-runtime@2.4.0`
- `@remix-run/node@2.4.0`

## 2.3.1

### Patch Changes
Expand Down
12 changes: 6 additions & 6 deletions packages/remix-dev/package.json
@@ -1,6 +1,6 @@
{
"name": "@remix-run/dev",
"version": "2.3.1",
"version": "2.4.0",
"description": "Dev tools and CLI for Remix",
"homepage": "https://remix.run",
"bugs": {
Expand Down Expand Up @@ -28,9 +28,9 @@
"@babel/types": "^7.22.5",
"@mdx-js/mdx": "^2.3.0",
"@npmcli/package-json": "^4.0.1",
"@remix-run/node": "2.3.1",
"@remix-run/router": "1.14.0-pre.0",
"@remix-run/server-runtime": "2.3.1",
"@remix-run/node": "2.4.0",
"@remix-run/router": "1.14.0",
"@remix-run/server-runtime": "2.4.0",
"@types/mdx": "^2.0.5",
"@vanilla-extract/integration": "^6.2.0",
"arg": "^5.0.1",
Expand Down Expand Up @@ -73,7 +73,7 @@
"ws": "^7.4.5"
},
"devDependencies": {
"@remix-run/serve": "2.3.1",
"@remix-run/serve": "2.4.0",
"@types/cacache": "^17.0.0",
"@types/cross-spawn": "^6.0.2",
"@types/gunzip-maybe": "^1.4.0",
Expand All @@ -94,7 +94,7 @@
"vite": "^5.0.0"
},
"peerDependencies": {
"@remix-run/serve": "^2.3.1",
"@remix-run/serve": "^2.4.0",
"typescript": "^5.1.0",
"vite": "^5.0.0"
},
Expand Down
7 changes: 7 additions & 0 deletions packages/remix-express/CHANGELOG.md
@@ -1,5 +1,12 @@
# `@remix-run/express`

## 2.4.0

### Patch Changes

- Updated dependencies:
- `@remix-run/node@2.4.0`

## 2.3.1

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/remix-express/package.json
@@ -1,6 +1,6 @@
{
"name": "@remix-run/express",
"version": "2.3.1",
"version": "2.4.0",
"description": "Express server request handler for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand All @@ -14,7 +14,7 @@
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"dependencies": {
"@remix-run/node": "2.3.1"
"@remix-run/node": "2.4.0"
},
"devDependencies": {
"@types/express": "^4.17.9",
Expand Down
12 changes: 12 additions & 0 deletions packages/remix-node/CHANGELOG.md
@@ -1,5 +1,17 @@
# `@remix-run/node`

## 2.4.0

### Minor Changes

- Deprecate `DataFunctionArgs` in favor of `LoaderFunctionArgs`/`ActionFunctionArgs`. This is aimed at keeping the types aligned across server/client loaders/actions now that `clientLoader`/`clientActon` functions have `serverLoader`/`serverAction` parameters which differentiate `ClientLoaderFunctionArgs`/`ClientActionFunctionArgs`. ([#8173](https://github.com/remix-run/remix/pull/8173))

### Patch Changes

- Update to `@remix-run/web-fetch@4.4.2` ([#8231](https://github.com/remix-run/remix/pull/8231))
- Updated dependencies:
- `@remix-run/server-runtime@2.4.0`

## 2.3.1

### Patch Changes
Expand Down
6 changes: 3 additions & 3 deletions packages/remix-node/package.json
@@ -1,6 +1,6 @@
{
"name": "@remix-run/node",
"version": "2.3.1",
"version": "2.4.0",
"description": "Node.js platform abstractions for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand All @@ -17,8 +17,8 @@
"./install.js"
],
"dependencies": {
"@remix-run/server-runtime": "2.3.1",
"@remix-run/web-fetch": "^4.4.1",
"@remix-run/server-runtime": "2.4.0",
"@remix-run/web-fetch": "^4.4.2",
"@remix-run/web-file": "^3.1.0",
"@remix-run/web-stream": "^1.1.0",
"@web3-storage/multipart-parser": "^1.0.0",
Expand Down
9 changes: 9 additions & 0 deletions packages/remix-serve/CHANGELOG.md
@@ -1,5 +1,14 @@
# `@remix-run/serve`

## 2.4.0

### Patch Changes

- Fix source map loading when file has `?t=timestamp` suffix (rebuilds) ([#8174](https://github.com/remix-run/remix/pull/8174))
- Updated dependencies:
- `@remix-run/node@2.4.0`
- `@remix-run/express@2.4.0`

## 2.3.1

### Patch Changes
Expand Down
6 changes: 3 additions & 3 deletions packages/remix-serve/package.json
@@ -1,6 +1,6 @@
{
"name": "@remix-run/serve",
"version": "2.3.1",
"version": "2.4.0",
"description": "Production application server for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand All @@ -15,8 +15,8 @@
"remix-serve": "dist/cli.js"
},
"dependencies": {
"@remix-run/express": "2.3.1",
"@remix-run/node": "2.3.1",
"@remix-run/express": "2.4.0",
"@remix-run/node": "2.4.0",
"chokidar": "^3.5.3",
"compression": "^1.7.4",
"express": "^4.17.1",
Expand Down
32 changes: 32 additions & 0 deletions packages/remix-server-runtime/CHANGELOG.md
@@ -1,5 +1,37 @@
# `@remix-run/server-runtime`

## 2.4.0

### Minor Changes

- Add support for `clientLoader`/`clientAction`/`HydrateFallback` route exports ([RFC](https://github.com/remix-run/remix/discussions/7634)). ([#8173](https://github.com/remix-run/remix/pull/8173))

Remix now supports loaders/actions that run on the client (in addition to, or instead of the loader/action that runs on the server). While we still recommend server loaders/actions for the majority of your data needs in a Remix app - these provide some levers you can pull for more advanced use-cases such as:

- Leveraging a data source local to the browser (i.e., `localStorage`)
- Managing a client-side cache of server data (like `IndexedDB`)
- Bypassing the Remix server in a BFF setup and hitting your API directly from the browser
- Migrating a React Router SPA to a Remix application

By default, `clientLoader` will not run on hydration, and will only run on subsequent client side navigations.

If you wish to run your client loader on hydration, you can set `clientLoader.hydrate=true` to force Remix to execute it on initial page load. Keep in mind that Remix will still SSR your route component so you should ensure that there is no new _required_ data being added by your `clientLoader`.

If your `clientLoader` needs to run on hydration and adds data you require to render the route component, you can export a `HydrateFallback` component that will render during SSR, and then your route component will not render until the `clientLoader` has executed on hydration.

`clientAction` is simpler than `clientLoader` because it has no hydration use-cases. `clientAction` will only run on client-side navigations.

For more information, please refer to the [`clientLoader`](https://remix.run/route/client-loader) and [`clientAction`](https://remix.run/route/client-action) documentation.

- Deprecate `DataFunctionArgs` in favor of `LoaderFunctionArgs`/`ActionFunctionArgs`. This is aimed at keeping the types aligned across server/client loaders/actions now that `clientLoader`/`clientActon` functions have `serverLoader`/`serverAction` parameters which differentiate `ClientLoaderFunctionArgs`/`ClientActionFunctionArgs`. ([#8173](https://github.com/remix-run/remix/pull/8173))

- Add a new `future.v3_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. For more information, please see the React Router [`6.21.0` Release Notes](https://github.com/remix-run/react-router/blob/release-next/CHANGELOG.md#futurev7_relativesplatpath) and the [`useResolvedPath` docs](https://remix.run/hooks/use-resolved-path#splat-paths). ([#8216](https://github.com/remix-run/remix/pull/8216))

### Patch Changes

- Fix flash of unstyled content for non-Express custom servers in Vite dev ([#8076](https://github.com/remix-run/remix/pull/8076))
- Pass request handler errors to `vite.ssrFixStacktrace` in Vite dev to ensure stack traces correctly map to the original source code ([#8066](https://github.com/remix-run/remix/pull/8066))

## 2.3.1

No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.3.1.
Expand Down
6 changes: 5 additions & 1 deletion packages/remix-server-runtime/jsonify.ts
Expand Up @@ -21,6 +21,9 @@ export type Jsonify<T> =
T extends Number ? number :
T extends Boolean ? boolean :

// Promises JSON.stringify to an empty object
T extends Promise<unknown> ? EmptyObject :

// Map & Set
T extends Map<unknown, unknown> ? EmptyObject :
T extends Set<unknown> ? EmptyObject :
Expand Down Expand Up @@ -119,6 +122,7 @@ type _tests = [
Expect<Equal<Jsonify<String>, string>>,
Expect<Equal<Jsonify<Number>, number>>,
Expect<Equal<Jsonify<Boolean>, boolean>>,
Expect<Equal<Jsonify<Promise<string>>, EmptyObject>>,

// Map & Set
Expect<Equal<Jsonify<Map<unknown, unknown>>, EmptyObject>>,
Expand Down Expand Up @@ -251,7 +255,7 @@ type NeverToNull<T> = [T] extends [never] ? null : T;

// adapted from https://github.com/sindresorhus/type-fest/blob/main/source/empty-object.d.ts
declare const emptyObjectSymbol: unique symbol;
type EmptyObject = { [emptyObjectSymbol]?: never };
export type EmptyObject = { [emptyObjectSymbol]?: never };

// adapted from https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts
type IsAny<T> = 0 extends 1 & T ? true : false;
4 changes: 2 additions & 2 deletions packages/remix-server-runtime/package.json
@@ -1,6 +1,6 @@
{
"name": "@remix-run/server-runtime",
"version": "2.3.1",
"version": "2.4.0",
"description": "Server runtime for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand All @@ -16,7 +16,7 @@
"typings": "dist/index.d.ts",
"module": "dist/esm/index.js",
"dependencies": {
"@remix-run/router": "1.14.0-pre.0",
"@remix-run/router": "1.14.0",
"@types/cookie": "^0.5.3",
"@web3-storage/multipart-parser": "^1.0.0",
"cookie": "^0.5.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/remix-server-runtime/routeModules.ts
Expand Up @@ -54,7 +54,7 @@ type ClientActionFunction = (
* Arguments passed to a route `clientAction` function
* @private Public API is exported from @remix-run/react
*/
type ClientActionFunctionArgs = RRActionFunctionArgs<undefined> & {
export type ClientActionFunctionArgs = RRActionFunctionArgs<undefined> & {
serverAction: <T = AppData>() => Promise<SerializeFrom<T>>;
};

Expand Down Expand Up @@ -87,7 +87,7 @@ type ClientLoaderFunction = ((
* Arguments passed to a route `clientLoader` function
* @private Public API is exported from @remix-run/react
*/
type ClientLoaderFunctionArgs = RRLoaderFunctionArgs<undefined> & {
export type ClientLoaderFunctionArgs = RRLoaderFunctionArgs<undefined> & {
serverLoader: <T = AppData>() => Promise<SerializeFrom<T>>;
};

Expand Down

0 comments on commit 37ee74e

Please sign in to comment.