@barefootjs/cli 0.35.4 → 0.35.5

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.
@@ -126,7 +126,7 @@ export function Counter(__allProps: { initial?: number } & { __instanceId?: stri
126
126
  A build-time post-processing step injects `useRequestContext()` calls into generated templates. `BfScripts` renders the collected `<script>` tags:
127
127
 
128
128
  ```tsx
129
- import { BfScripts } from '@barefootjs/hono'
129
+ import { BfScripts } from '@barefootjs/hono/scripts'
130
130
 
131
131
  export function Layout({ children }) {
132
132
  return (
@@ -212,3 +212,158 @@ export default defineConfig({
212
212
  }),
213
213
  })
214
214
  ```
215
+
216
+ ## Adding to an Existing Project
217
+
218
+ `npm create barefootjs@latest` scaffolds the layout above from scratch; this section retrofits it onto an existing Hono + Cloudflare Workers app that already renders with `hono/jsx-renderer` and deploys with `wrangler deploy`. The end state is the same as the scaffold's, so a freshly scaffolded project is a valid reference to diff against when something doesn't line up.
219
+
220
+ ### What changes
221
+
222
+ `barefoot()` compiles **individual components** — each `.tsx` under `components` becomes an SSR template under `templates` plus hydration JS under `build.outDir`. It never bundles the server app into a single file. For a project that currently does that with a whole-app Vite bundler (e.g. `@hono/vite-build`), the consequence is:
223
+
224
+ | | Before | After |
225
+ |---|---|---|
226
+ | Server build | Bundler plugin emits a single-file SSR bundle | Step removed; nothing replaces it |
227
+ | `wrangler.jsonc` `main` | The pre-bundled output | The uncompiled entry file — wrangler's own esbuild bundles it at dev/deploy time |
228
+ | `vite build` | Produces the server bundle | Produces compiled templates + hydration JS only |
229
+
230
+ `barefoot()` takes the bundler plugin's place in `vite.config.ts`, and any `package.json` script or CI step that referenced the old bundle path goes with it.
231
+
232
+ **Paths in this section are the scaffold's** (`components/`, `dist/components`, `public/components`, `server.tsx`, `renderer.tsx`). Substitute your own. Two that are easy to copy literally by mistake:
233
+
234
+ - `wrangler.jsonc` `main` must be your app's actual Hono entry file (e.g. `src/index.tsx`). Copying `server.tsx` as-is fails immediately with `The entry-point file at "server.tsx" was not found`.
235
+ - `import { renderer } from './renderer'` assumes `jsxRenderer` lives in its own module, as in the scaffold. If yours is defined inline in the entry file, edit it there and skip the import — there's no need to split it out.
236
+
237
+ ### 1. Install
238
+
239
+ ```sh
240
+ npm install @barefootjs/client @barefootjs/hono @barefootjs/jsx @barefootjs/shared
241
+ npm install -D @barefootjs/vite
242
+ ```
243
+
244
+ > **Peer dependencies.** `@barefootjs/hono` peer-depends on `vite ^6.0.0` and `@barefootjs/jsx` on `typescript ^5.0.0`. A project already on a newer major of either (e.g. `vite@8`, `typescript@7`) fails `npm install` with an `ERESOLVE` error. Either install with `--legacy-peer-deps` or pin `typescript` to `^5`. The `typescript` range is the one that matters: a newer `vite` alone works in practice, but a newer `typescript` makes `vite build` crash at config-load time with `TypeError: ts.createPrinter is not a function` — an opaque runtime error, not a version check — because `@barefootjs/vite` calls the `typescript` package's compiler API directly.
245
+
246
+ ### 2. Config files
247
+
248
+ #### `tsconfig.json`
249
+
250
+ ```json
251
+ {
252
+ "compilerOptions": {
253
+ "jsx": "react-jsx",
254
+ "jsxImportSource": "@barefootjs/hono/jsx",
255
+ "baseUrl": ".",
256
+ "paths": {
257
+ "@/components/*": ["./dist/components/*", "./components/*"]
258
+ }
259
+ },
260
+ "exclude": ["node_modules", "dist/components"]
261
+ }
262
+ ```
263
+
264
+ `@/components/*` has two targets, tried in order by both TypeScript and wrangler: the compiled SSR template under `dist/components/` (carrying the hydration markers from Output Format above) whenever it exists, otherwise the raw source under `components/` so editor tooling and type-checking resolve before the first build. Excluding `dist/components` keeps the compiled copy out of type-checking. Everything else already in `compilerOptions` (`types`, `strict`, …) stays as it is.
265
+
266
+ #### `vite.config.ts`
267
+
268
+ ```ts
269
+ // vite.config.ts
270
+ import { dirname, resolve } from 'node:path'
271
+ import { fileURLToPath } from 'node:url'
272
+ import { defineConfig } from 'vite'
273
+ import { barefoot } from '@barefootjs/hono/vite'
274
+
275
+ const HERE = dirname(fileURLToPath(import.meta.url))
276
+
277
+ export default defineConfig({
278
+ // Public URL prefix of the client build. Must match the path Workers
279
+ // Assets serves `build.outDir` under (wrangler.jsonc below).
280
+ base: '/components/',
281
+ resolve: {
282
+ // Required, not optional: Vite's dev-server dependency pre-scan runs
283
+ // before this plugin's `transform` hook and ignores tsconfig `paths`.
284
+ // Points at the SOURCE tree, never at `dist/components`.
285
+ alias: {
286
+ '@/components': resolve(HERE, 'components'),
287
+ },
288
+ },
289
+ // `build.outDir` sits inside `public/`, which Workers Assets already
290
+ // serves as-is. Vite's default `publicDir` would copy the rest of
291
+ // `public/` into `public/components` on every build for nothing.
292
+ publicDir: false,
293
+ build: {
294
+ outDir: 'public/components', // hydration JS → served by Workers Assets
295
+ emptyOutDir: true,
296
+ },
297
+ plugins: barefoot({
298
+ components: ['components'], // .tsx source directories to compile
299
+ templates: 'dist/components', // compiled SSR templates → imported by the server, never served
300
+ }),
301
+ })
302
+ ```
303
+
304
+ Everything not shown (hashing, chunking, minification, dev server) is stock Vite. `adapterOptions`, `assets`, and `assetsOutputFile` (see Options above) are not needed for a retrofit.
305
+
306
+ #### `wrangler.jsonc`
307
+
308
+ ```jsonc
309
+ {
310
+ "$schema": "node_modules/wrangler/config-schema.json",
311
+ "name": "my-app",
312
+ // Your existing uncompiled Hono entry (see "Paths" above). Wrangler
313
+ // bundles it and follows the tsconfig `paths` mapping into dist/components/.
314
+ "main": "server.tsx",
315
+ "compatibility_date": "2025-01-01",
316
+ // Must cover `build.outDir` from vite.config.ts and must not include
317
+ // `templates` — see Deploying to Cloudflare Workers above.
318
+ "assets": {
319
+ "directory": "./public"
320
+ }
321
+ }
322
+ ```
323
+
324
+ ### 3. Wire the app
325
+
326
+ **Render `<BfScripts />` once** (from `@barefootjs/hono/scripts`) in the layout your `jsxRenderer` already defines — not inside individual components. It emits the `<script>` tags loading each compiled component's hydration JS exactly once per page, however many instances are rendered (see Script Collection above). Existing `ContextRenderer` augmentation and stylesheet links stay as they are.
327
+
328
+ ```tsx
329
+ import { jsxRenderer } from 'hono/jsx-renderer'
330
+ import { BfScripts } from '@barefootjs/hono/scripts'
331
+
332
+ export const renderer = jsxRenderer(({ children, title }) => (
333
+ <html lang="en">
334
+ <head>
335
+ <meta charset="UTF-8" />
336
+ <title>{title ?? 'My app'}</title>
337
+ </head>
338
+ <body>
339
+ {children}
340
+ <BfScripts />
341
+ </body>
342
+ </html>
343
+ ))
344
+ ```
345
+
346
+ **Import components through the alias**, not a relative path into the source tree, so the dist-first resolution from `tsconfig.json` applies:
347
+
348
+ ```tsx
349
+ // server.tsx
350
+ import { Hono } from 'hono'
351
+ import { renderer } from './renderer'
352
+ import { Counter } from '@/components/Counter'
353
+
354
+ const app = new Hono()
355
+ app.use('*', renderer)
356
+ app.get('/', (c) => c.render(<main><Counter /></main>, { title: 'My app' }))
357
+ export default app
358
+ ```
359
+
360
+ Existing plain Hono JSX components can stay put and move under `components/` one at a time — only files under a configured `components` directory are compiled.
361
+
362
+ ### 4. Build and verify
363
+
364
+ ```sh
365
+ npx vite build # writes dist/components/ (templates) and public/components/ (hydration JS)
366
+ npx wrangler dev # or: npx wrangler deploy
367
+ ```
368
+
369
+ Load a page that renders a converted `"use client"` component: its element carries a `bf` marker attribute (see Output Format above) and it responds to interaction. During development, run `vite dev` alongside `wrangler dev` so `dist/components/` keeps regenerating on change.
@@ -18,16 +18,20 @@ JSX Source
18
18
 
19
19
  ## Available Adapters
20
20
 
21
- | Adapter | Output | Backend | Package |
22
- |---------|--------|---------|---------|
23
- | [`HonoAdapter`](./adapters/hono-adapter.md) | `.tsx` | Hono / JSX-based servers | `@barefootjs/hono` |
24
- | [`GoTemplateAdapter`](./adapters/go-template-adapter.md) | `.tmpl` + `_types.go` | Go `html/template` | `@barefootjs/go-template` |
25
- | [Perl](./adapters/perl-adapter.md) | `.ep` / `.tx` | Mojolicious, Text::Xslate (PSGI/Plack) | `@barefootjs/mojolicious`, `@barefootjs/xslate` |
26
- | [Ruby](./adapters/ruby-adapter.md) | `.erb` | stdlib ERB (any Rack app — Sinatra, Rails) | `@barefootjs/erb` |
27
- | [Python](./adapters/python-adapter.md) | `.jinja` | Jinja2 (Flask, Django, bare WSGI) | `@barefootjs/jinja` |
28
- | [PHP](./adapters/php-adapter.md) | `.twig` / `.blade.php` | Twig (Slim, plain PHP), Laravel Blade (`illuminate/view` standalone) | `@barefootjs/twig`, `@barefootjs/blade` |
29
- | [Rust](./adapters/rust-adapter.md) | `.j2` | minijinja (axum, actix-web, warp) | `@barefootjs/rust` |
30
- | [CSR](./adapters/csr.md) | — (client-rendered) | None (browser-only) | `@barefootjs/client` |
21
+ <!-- ADAPTER-TABLE:START (auto-generated by scripts/generate-adapter-docs.ts do not edit by hand) -->
22
+ | Language | Backend | Package |
23
+ |----------|---------|---------|
24
+ | TypeScript | [Hono](./adapters/hono-adapter.md) | `@barefootjs/hono` |
25
+ | Go | [html/template](./adapters/go-template-adapter.md) | `@barefootjs/go-template` |
26
+ | Perl | [Mojolicious](./adapters/perl-adapter.md) | `@barefootjs/mojolicious` |
27
+ | Perl | [Text::Xslate](./adapters/perl-adapter.md) | `@barefootjs/xslate` |
28
+ | Ruby | [ERB](./adapters/ruby-adapter.md) | `@barefootjs/erb` |
29
+ | Python | [Jinja2](./adapters/python-adapter.md) | `@barefootjs/jinja` |
30
+ | PHP | [Twig](./adapters/php-adapter.md) | `@barefootjs/twig` |
31
+ | PHP | [Laravel Blade](./adapters/php-adapter.md) | `@barefootjs/blade` |
32
+ | Rust | [minijinja](./adapters/rust-adapter.md) | `@barefootjs/rust` |
33
+ | — | [CSR (browser only)](./adapters/csr.md) | `@barefootjs/client` |
34
+ <!-- ADAPTER-TABLE:END -->
31
35
 
32
36
  > CSR is not an IR→template adapter. It renders components directly in the browser using client-side template functions — use it when the server can't (or shouldn't) emit the initial HTML.
33
37
 
@@ -13,19 +13,21 @@ BarefootJS compiles JSX at build time into your backend's native template format
13
13
  JSX → IR (backend-agnostic) → Adapter → Template
14
14
  ```
15
15
 
16
- | Language | Adapter | Notes |
17
- |----------|---------|-------|
18
- | TypeScript | [HonoAdapter](../adapters/hono-adapter.md) | Hono / JSX-based TS servers |
19
- | TypeScript | [TestAdapter](https://github.com/piconic-ai/barefootjs/tree/main/packages/test) | IR-based component testing |
20
- | Go | [GoTemplateAdapter](../adapters/go-template-adapter.md) | `html/template` |
21
- | Perl | [MojoliciousAdapter](https://github.com/piconic-ai/barefootjs/tree/main/packages/adapter-mojolicious) | Mojolicious EP templates |
22
-
23
- ### Planned
24
-
25
- | Language | Adapter |
26
- |----------|---------|
27
- | Rust | (TBD) |
28
- | Python | Jinja2Adapter |
29
- | Ruby | ERBAdapter |
16
+ <!-- ADAPTER-TABLE:START (auto-generated by scripts/generate-adapter-docs.ts do not edit by hand) -->
17
+ | Language | Backend | Package |
18
+ |----------|---------|---------|
19
+ | TypeScript | [Hono](../adapters/hono-adapter.md) | `@barefootjs/hono` |
20
+ | Go | [html/template](../adapters/go-template-adapter.md) | `@barefootjs/go-template` |
21
+ | Perl | [Mojolicious](../adapters/perl-adapter.md) | `@barefootjs/mojolicious` |
22
+ | Perl | [Text::Xslate](../adapters/perl-adapter.md) | `@barefootjs/xslate` |
23
+ | Ruby | [ERB](../adapters/ruby-adapter.md) | `@barefootjs/erb` |
24
+ | Python | [Jinja2](../adapters/python-adapter.md) | `@barefootjs/jinja` |
25
+ | PHP | [Twig](../adapters/php-adapter.md) | `@barefootjs/twig` |
26
+ | PHP | [Laravel Blade](../adapters/php-adapter.md) | `@barefootjs/blade` |
27
+ | Rust | [minijinja](../adapters/rust-adapter.md) | `@barefootjs/rust` |
28
+ | | [CSR (browser only)](../adapters/csr.md) | `@barefootjs/client` |
29
+ <!-- ADAPTER-TABLE:END -->
30
+
31
+ TypeScript also has an [IR-based `TestAdapter`](https://github.com/piconic-ai/barefootjs/tree/main/packages/test) for browser-free component testing — it isn't a serving-time backend, so it's outside the table above. See [Adapters](../adapters.md) for the full picture, including which adapters share one engine-agnostic runtime.
30
32
 
31
33
  The IR contract is stable. You can [write a custom adapter](../adapters/custom-adapter.md) for any backend.