forked from remix-run/remix
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Vite-based
cloudflare-workers
template (remix-run#9345)
- Loading branch information
1 parent
da96d35
commit b3f75da
Showing
19 changed files
with
441 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/** | ||
* This is intended to be a basic starting point for linting in your app. | ||
* It relies on recommended configs out of the box for simplicity, but you can | ||
* and should modify this configuration to best suit your team's needs. | ||
*/ | ||
|
||
/** @type {import('eslint').Linter.Config} */ | ||
module.exports = { | ||
root: true, | ||
parserOptions: { | ||
ecmaVersion: "latest", | ||
sourceType: "module", | ||
ecmaFeatures: { | ||
jsx: true, | ||
}, | ||
}, | ||
env: { | ||
browser: true, | ||
commonjs: true, | ||
es6: true, | ||
}, | ||
|
||
// Base config | ||
extends: ["eslint:recommended"], | ||
|
||
overrides: [ | ||
// React | ||
{ | ||
files: ["**/*.{js,jsx,ts,tsx}"], | ||
plugins: ["react", "jsx-a11y"], | ||
extends: [ | ||
"plugin:react/recommended", | ||
"plugin:react/jsx-runtime", | ||
"plugin:react-hooks/recommended", | ||
"plugin:jsx-a11y/recommended", | ||
], | ||
settings: { | ||
react: { | ||
version: "detect", | ||
}, | ||
formComponents: ["Form"], | ||
linkComponents: [ | ||
{ name: "Link", linkAttribute: "to" }, | ||
{ name: "NavLink", linkAttribute: "to" }, | ||
], | ||
"import/resolver": { | ||
typescript: {}, | ||
}, | ||
}, | ||
}, | ||
|
||
// Typescript | ||
{ | ||
files: ["**/*.{ts,tsx}"], | ||
plugins: ["@typescript-eslint", "import"], | ||
parser: "@typescript-eslint/parser", | ||
settings: { | ||
"import/internal-regex": "^~/", | ||
"import/resolver": { | ||
node: { | ||
extensions: [".ts", ".tsx"], | ||
}, | ||
typescript: { | ||
alwaysTryTypes: true, | ||
}, | ||
}, | ||
}, | ||
extends: [ | ||
"plugin:@typescript-eslint/recommended", | ||
"plugin:import/recommended", | ||
"plugin:import/typescript", | ||
], | ||
}, | ||
|
||
// Node | ||
{ | ||
files: [".eslintrc.cjs"], | ||
env: { | ||
node: true, | ||
}, | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
node_modules | ||
|
||
/.wrangler | ||
/build | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Welcome to Remix + Vite! | ||
|
||
📖 See the [Remix docs](https://remix.run/docs) and the [Remix Vite docs](https://remix.run/docs/en/main/guides/vite) for details on supported features. | ||
|
||
## Typegen | ||
|
||
Generate types for your Cloudflare bindings in `wrangler.toml`: | ||
|
||
```sh | ||
pnpm typegen | ||
``` | ||
|
||
You will need to rerun typegen whenever you make changes to `wrangler.toml`. | ||
|
||
## Development | ||
|
||
Run the Vite dev server: | ||
|
||
```sh | ||
npm run dev | ||
``` | ||
|
||
To run Wrangler: | ||
|
||
```sh | ||
npm run build | ||
npm start | ||
``` | ||
|
||
## Deployment | ||
|
||
If you don't already have an account, then [create a cloudflare account here](https://dash.cloudflare.com/sign-up) and after verifying your email address with Cloudflare, go to your dashboard and set up your free custom Cloudflare Workers subdomain. | ||
|
||
Once that's done, you should be able to deploy your app: | ||
|
||
```sh | ||
pnpm run deploy | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* By default, Remix will handle hydrating your app on the client for you. | ||
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ | ||
* For more information, see https://remix.run/file-conventions/entry.client | ||
*/ | ||
|
||
import { RemixBrowser } from "@remix-run/react"; | ||
import { startTransition, StrictMode } from "react"; | ||
import { hydrateRoot } from "react-dom/client"; | ||
|
||
startTransition(() => { | ||
hydrateRoot( | ||
document, | ||
<StrictMode> | ||
<RemixBrowser /> | ||
</StrictMode> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* By default, Remix will handle generating the HTTP Response for you. | ||
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ | ||
* For more information, see https://remix.run/file-conventions/entry.server | ||
*/ | ||
|
||
import type { AppLoadContext, EntryContext } from "@remix-run/cloudflare"; | ||
import { RemixServer } from "@remix-run/react"; | ||
import { isbot } from "isbot"; | ||
import { renderToReadableStream } from "react-dom/server"; | ||
|
||
export default async function handleRequest( | ||
request: Request, | ||
responseStatusCode: number, | ||
responseHeaders: Headers, | ||
remixContext: EntryContext, | ||
// This is ignored so we can keep it in the template for visibility. Feel | ||
// free to delete this parameter in your app if you're not using it! | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
loadContext: AppLoadContext | ||
) { | ||
const body = await renderToReadableStream( | ||
<RemixServer context={remixContext} url={request.url} />, | ||
{ | ||
signal: request.signal, | ||
onError(error: unknown) { | ||
// Log streaming rendering errors from inside the shell | ||
console.error(error); | ||
responseStatusCode = 500; | ||
}, | ||
} | ||
); | ||
|
||
if (isbot(request.headers.get("user-agent") || "")) { | ||
await body.allReady; | ||
} | ||
|
||
responseHeaders.set("Content-Type", "text/html"); | ||
return new Response(body, { | ||
headers: responseHeaders, | ||
status: responseStatusCode, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { | ||
Links, | ||
Meta, | ||
Outlet, | ||
Scripts, | ||
ScrollRestoration, | ||
} from "@remix-run/react"; | ||
|
||
export function Layout({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<html lang="en"> | ||
<head> | ||
<meta charSet="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<Meta /> | ||
<Links /> | ||
</head> | ||
<body> | ||
{children} | ||
<ScrollRestoration /> | ||
<Scripts /> | ||
</body> | ||
</html> | ||
); | ||
} | ||
|
||
export default function App() { | ||
return <Outlet />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { MetaFunction } from "@remix-run/cloudflare"; | ||
|
||
export const meta: MetaFunction = () => { | ||
return [ | ||
{ title: "New Remix App" }, | ||
{ | ||
name: "description", | ||
content: "Welcome to Remix! Using Vite and Cloudflare Workers!", | ||
}, | ||
]; | ||
}; | ||
|
||
export default function Index() { | ||
return ( | ||
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}> | ||
<h1>Welcome to Remix (with Vite and Cloudflare Workers)</h1> | ||
<ul> | ||
<li> | ||
<a | ||
target="_blank" | ||
href="https://developers.cloudflare.com/workers/" | ||
rel="noreferrer" | ||
> | ||
Cloudflare Workers Docs | ||
</a> | ||
</li> | ||
<li> | ||
<a target="_blank" href="https://remix.run/docs" rel="noreferrer"> | ||
Remix Docs | ||
</a> | ||
</li> | ||
</ul> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare module "__STATIC_CONTENT_MANIFEST" { | ||
const manifest: string; | ||
export default manifest; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { type PlatformProxy } from "wrangler"; | ||
|
||
declare module "@remix-run/cloudflare" { | ||
interface AppLoadContext { | ||
cloudflare: Omit<PlatformProxy<Env>, "dispose">; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"private": true, | ||
"sideEffects": false, | ||
"type": "module", | ||
"scripts": { | ||
"build": "remix vite:build", | ||
"deploy": "wrangler deploy", | ||
"dev": "remix vite:dev", | ||
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .", | ||
"start": "wrangler dev ./server.js", | ||
"typegen": "wrangler types", | ||
"typecheck": "tsc" | ||
}, | ||
"dependencies": { | ||
"@cloudflare/kv-asset-handler": "^0.1.3", | ||
"@remix-run/cloudflare": "*", | ||
"@remix-run/react": "*", | ||
"@remix-run/server-runtime": "*", | ||
"isbot": "^4.1.0", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0" | ||
}, | ||
"devDependencies": { | ||
"@cloudflare/workers-types": "^4.20230518.0", | ||
"@remix-run/dev": "*", | ||
"@types/react": "^18.2.20", | ||
"@types/react-dom": "^18.2.7", | ||
"@typescript-eslint/eslint-plugin": "^6.7.4", | ||
"@typescript-eslint/parser": "^6.7.4", | ||
"eslint": "^8.38.0", | ||
"eslint-import-resolver-typescript": "^3.6.1", | ||
"eslint-plugin-import": "^2.28.1", | ||
"eslint-plugin-jsx-a11y": "^6.7.1", | ||
"eslint-plugin-react": "^7.33.2", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"typescript": "^5.1.6", | ||
"vite": "^5.1.0", | ||
"vite-tsconfig-paths": "^4.2.1", | ||
"wrangler": "^3.24.0" | ||
}, | ||
"engines": { | ||
"node": ">=18.0.0" | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { getAssetFromKV } from "@cloudflare/kv-asset-handler"; | ||
import { createRequestHandler } from "@remix-run/cloudflare"; | ||
import * as remixBuild from "./build/server"; | ||
// eslint-disable-next-line import/no-unresolved | ||
import __STATIC_CONTENT_MANIFEST from "__STATIC_CONTENT_MANIFEST"; | ||
|
||
const MANIFEST = JSON.parse(__STATIC_CONTENT_MANIFEST); | ||
const handleRemixRequest = createRequestHandler(remixBuild); | ||
|
||
export default { | ||
async fetch(request, env, ctx) { | ||
try { | ||
const url = new URL(request.url); | ||
const ttl = url.pathname.startsWith("/assets/") | ||
? 60 * 60 * 24 * 365 // 1 year | ||
: 60 * 5; // 5 minutes | ||
return await getAssetFromKV( | ||
{ | ||
request, | ||
waitUntil: ctx.waitUntil.bind(ctx), | ||
}, | ||
{ | ||
ASSET_NAMESPACE: env.__STATIC_CONTENT, | ||
ASSET_MANIFEST: MANIFEST, | ||
cacheControl: { | ||
browserTTL: ttl, | ||
edgeTTL: ttl, | ||
}, | ||
} | ||
); | ||
} catch (error) { | ||
// No-op | ||
} | ||
|
||
try { | ||
const loadContext = { | ||
cloudflare: { | ||
// This object matches the return value from Wrangler's | ||
// `getPlatformProxy` used during development via Remix's | ||
// `cloudflareDevProxyVitePlugin`: | ||
// https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy | ||
cf: request.cf, | ||
ctx: { | ||
waitUntil: ctx.waitUntil, | ||
passThroughOnException: ctx.passThroughOnException, | ||
}, | ||
caches, | ||
env, | ||
}, | ||
}; | ||
return await handleRemixRequest(request, loadContext); | ||
} catch (error) { | ||
console.log(error); | ||
return new Response("An unexpected error occurred", { status: 500 }); | ||
} | ||
}, | ||
}; |
Oops, something went wrong.