create-rsc-kit 0.7.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/templates.js +87 -15
- package/package.json +1 -1
package/dist/templates.js
CHANGED
|
@@ -63,16 +63,34 @@ export function scripts(o) {
|
|
|
63
63
|
return {
|
|
64
64
|
dev: 'vite',
|
|
65
65
|
build: 'vite build',
|
|
66
|
+
// The two that produce something you ship build first, rather than reading
|
|
67
|
+
// whatever .output happens to hold. Run on a project that has never been
|
|
68
|
+
// built, they failed with `ENOENT opening root directory ".output/server"`
|
|
69
|
+
// — a path the app did not write and has no reason to recognise. Run on one
|
|
70
|
+
// built a while ago, which is worse, they silently packaged the old code.
|
|
71
|
+
//
|
|
72
|
+
// start and preview are left alone: they are the inner loop, they follow a
|
|
73
|
+
// build in every set of instructions, and re-running one on each restart
|
|
74
|
+
// costs more than it saves.
|
|
66
75
|
...(o.host === 'worker'
|
|
67
|
-
? {
|
|
76
|
+
? {
|
|
77
|
+
preview: 'wrangler dev .output/server/index.mjs',
|
|
78
|
+
deploy: 'vite build && nitro deploy --prebuilt',
|
|
79
|
+
}
|
|
68
80
|
: {
|
|
69
81
|
start: `${o.host === 'node' ? 'node' : 'bun'} .output/server/index.mjs`,
|
|
70
82
|
// Bun only, and only because serveStatic: 'inline' is set in the vite
|
|
71
83
|
// config. Without that the binary compiles, serves pages, and 404s
|
|
72
84
|
// every asset — the static path resolves into Bun's virtual
|
|
73
85
|
// filesystem, where the files on disk are not.
|
|
86
|
+
//
|
|
87
|
+
// Into dist/, which is already ignored. Named after the project it
|
|
88
|
+
// landed a 63MB binary in the root of, next to the source, with
|
|
89
|
+
// nothing in .gitignore covering it.
|
|
74
90
|
...(o.host === 'bun'
|
|
75
|
-
? {
|
|
91
|
+
? {
|
|
92
|
+
compile: 'vite build && bun build --compile .output/server/index.mjs --outfile dist/app',
|
|
93
|
+
}
|
|
76
94
|
: {}),
|
|
77
95
|
}),
|
|
78
96
|
typecheck: 'tsc --noEmit',
|
|
@@ -178,7 +196,11 @@ export function viteConfig(o) {
|
|
|
178
196
|
//
|
|
179
197
|
// Not optional, and not a flag on rscKit() either — the plugin builds for
|
|
180
198
|
// Nitro and nothing else, so a config without this line has no server.
|
|
181
|
-
|
|
199
|
+
// serverDir is what makes server/api and server/routes exist at all: Nitro's
|
|
200
|
+
// scanDirs is empty without it, so a handler written there is never scanned,
|
|
201
|
+
// the request falls through to the rsc entry, and the 404 it answers with
|
|
202
|
+
// reads as a routing bug in this package rather than a missing option.
|
|
203
|
+
plugins.push(`nitro({ preset: ${JSON.stringify(preset(o.host))}, serveStatic: 'inline', serverDir: 'server' })`);
|
|
182
204
|
plugins.push(`rscKit({
|
|
183
205
|
${options.join(',\n ')},
|
|
184
206
|
})`);
|
|
@@ -187,12 +209,22 @@ export function viteConfig(o) {
|
|
|
187
209
|
plugins.push('babel({ presets: [reactCompilerPreset()] })');
|
|
188
210
|
if (o.tailwind)
|
|
189
211
|
plugins.push('tailwindcss()');
|
|
212
|
+
// `@/` for the source directory. Vite does not read tsconfig `paths`, so the
|
|
213
|
+
// alias has to exist here as well or the import type-checks and then fails to
|
|
214
|
+
// resolve — and the tsconfig half is what tools like shadcn look for when
|
|
215
|
+
// they ask whether this project has an import alias at all.
|
|
190
216
|
return `${imports.join('\n')}
|
|
217
|
+
import { fileURLToPath } from 'node:url'
|
|
191
218
|
|
|
192
219
|
export default defineConfig({
|
|
193
220
|
plugins: [
|
|
194
221
|
${plugins.join(',\n ')},
|
|
195
222
|
],
|
|
223
|
+
resolve: {
|
|
224
|
+
alias: {
|
|
225
|
+
'@': fileURLToPath(new URL('./${o.sourceDir}', import.meta.url)),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
196
228
|
})
|
|
197
229
|
`;
|
|
198
230
|
}
|
|
@@ -202,6 +234,16 @@ export const tsconfig = (o) => JSON.stringify({
|
|
|
202
234
|
target: 'ESNext',
|
|
203
235
|
module: 'ESNext',
|
|
204
236
|
moduleResolution: 'bundler',
|
|
237
|
+
// `@/thing` for `<sourceDir>/thing`. Matched by resolve.alias in the
|
|
238
|
+
// vite config, which is what actually resolves it — this half is for
|
|
239
|
+
// the type system, and for the tools that read a tsconfig to find out
|
|
240
|
+
// whether the project has an import alias. shadcn refuses to init
|
|
241
|
+
// without one.
|
|
242
|
+
//
|
|
243
|
+
// No `baseUrl`: TypeScript removed it, and emitting it now is an
|
|
244
|
+
// outright TS5102 on a freshly scaffolded app. Paths resolve relative
|
|
245
|
+
// to this file without it.
|
|
246
|
+
paths: { '@/*': [`./${o.sourceDir}/*`] },
|
|
205
247
|
jsx: 'react-jsx',
|
|
206
248
|
strict: true,
|
|
207
249
|
noEmit: true,
|
|
@@ -231,12 +273,17 @@ export const tsconfig = (o) => JSON.stringify({
|
|
|
231
273
|
// .rsc-kit holds the generated ambient declarations. Ambient means
|
|
232
274
|
// inside the project, and `include` is what decides that — leave it out
|
|
233
275
|
// and typed routes silently fall back to string.
|
|
234
|
-
|
|
276
|
+
//
|
|
277
|
+
// server/ is the same mistake one directory over: an api handler outside
|
|
278
|
+
// the program is not type-checked at all, so one returning the wrong
|
|
279
|
+
// shape builds, deploys and fails at runtime with nothing having said so.
|
|
280
|
+
include: [`${o.sourceDir}/**/*`, 'server/**/*', '.rsc-kit/**/*'],
|
|
235
281
|
}, null, 2) + '\n';
|
|
236
282
|
export function layout(o) {
|
|
237
283
|
return `${o.tailwind ? "import './styles.css'\n" : ''}import type { ReactNode } from 'react'
|
|
284
|
+
import type { Metadata } from '@rsc-kit/core/metadata'
|
|
238
285
|
|
|
239
|
-
export const metadata = {
|
|
286
|
+
export const metadata: Metadata = {
|
|
240
287
|
title: { template: '%s · ${o.name}', default: '${o.name}' },
|
|
241
288
|
}
|
|
242
289
|
|
|
@@ -260,23 +307,40 @@ export default function RootLayout({ children }: { children: ReactNode }) {
|
|
|
260
307
|
export function page(o) {
|
|
261
308
|
const h1 = o.tailwind ? ' className="text-3xl font-bold"' : '';
|
|
262
309
|
const p = o.tailwind ? ' className="mt-4 text-slate-600"' : '';
|
|
310
|
+
const code = o.tailwind ? ' className="rounded bg-slate-100 px-1"' : '';
|
|
311
|
+
// Deliberately nothing that changes between renders.
|
|
312
|
+
//
|
|
313
|
+
// This page said "Rendered on the server at {new Date()}" — and every route
|
|
314
|
+
// it can is frozen at build time, so that timestamp was the build's and
|
|
315
|
+
// never moved again. Reload and the same instant is still there, under a
|
|
316
|
+
// sentence claiming it was rendered just now. The first thing the starter
|
|
317
|
+
// did was look broken, and the fix someone reaches for is to stop
|
|
318
|
+
// prerendering the page that is teaching them about prerendering.
|
|
263
319
|
return `import { Counter } from '../components/Counter'
|
|
320
|
+
import type { Metadata } from '@rsc-kit/core/metadata'
|
|
264
321
|
|
|
265
|
-
export const metadata = { title: 'Home' }
|
|
266
|
-
|
|
267
|
-
// A server component: async, runs only on the server, ships no JavaScript.
|
|
268
|
-
export default async function HomePage() {
|
|
269
|
-
const now = new Date().toISOString()
|
|
322
|
+
export const metadata: Metadata = { title: 'Home' }
|
|
270
323
|
|
|
324
|
+
// A server component. It runs on the server and ships no JavaScript of its
|
|
325
|
+
// own — this file is not in the browser bundle. It can be \`async\` and await
|
|
326
|
+
// whatever it needs; nothing here does yet.
|
|
327
|
+
export default function HomePage() {
|
|
271
328
|
return (
|
|
272
329
|
<>
|
|
273
330
|
<h1${h1}>${o.name}</h1>
|
|
274
331
|
<p${p}>
|
|
275
|
-
|
|
276
|
-
|
|
332
|
+
The only JavaScript on this page is the counter below, because
|
|
333
|
+
<code${code}>Counter.tsx</code> is the only file that opts into the
|
|
334
|
+
client. Everything else rendered on the server and stayed there.
|
|
277
335
|
</p>
|
|
278
336
|
|
|
279
337
|
<Counter />
|
|
338
|
+
|
|
339
|
+
<p${p}>
|
|
340
|
+
Edit <code${code}>src/app/page.tsx</code> and the change arrives without
|
|
341
|
+
a reload. Add <code${code}>src/app/about/page.tsx</code> and{' '}
|
|
342
|
+
<code${code}>/about</code> exists — there is no route table to update.
|
|
343
|
+
</p>
|
|
280
344
|
</>
|
|
281
345
|
)
|
|
282
346
|
}
|
|
@@ -384,9 +448,17 @@ export function readme(o) {
|
|
|
384
448
|
? `${pm} preview # wrangler dev, on workerd\n${pm} deploy # nitro deploy --prebuilt`
|
|
385
449
|
: `${pm} start # serve on http://localhost:${PORT}`;
|
|
386
450
|
const compile = o.host === 'bun'
|
|
387
|
-
? `\n\n\`${pm} compile\` puts the whole application
|
|
388
|
-
|
|
389
|
-
|
|
451
|
+
? `\n\n\`${pm} compile\` builds and then puts the whole application into
|
|
452
|
+
\`dist/app\` — engine, pages and assets, with Bun's runtime inside it. Run it
|
|
453
|
+
directly:
|
|
454
|
+
|
|
455
|
+
\`\`\`sh
|
|
456
|
+
./dist/app
|
|
457
|
+
\`\`\`
|
|
458
|
+
|
|
459
|
+
It builds first, so the binary is never a version behind your source. Frozen
|
|
460
|
+
pages stay outside it: a binary has no filesystem to read them from, so it
|
|
461
|
+
renders those live.`
|
|
390
462
|
: '';
|
|
391
463
|
return `# ${o.name}
|
|
392
464
|
|