@barefootjs/vite 0.30.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/child-marker.d.ts +62 -0
- package/dist/child-marker.d.ts.map +1 -0
- package/dist/compile-cache.d.ts +19 -0
- package/dist/compile-cache.d.ts.map +1 -0
- package/dist/component-manifest.d.ts +69 -0
- package/dist/component-manifest.d.ts.map +1 -0
- package/dist/corpus-program.d.ts +41 -0
- package/dist/corpus-program.d.ts.map +1 -0
- package/dist/debounced-serial-runner.d.ts +27 -0
- package/dist/debounced-serial-runner.d.ts.map +1 -0
- package/dist/dev-server.d.ts +99 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/discover.d.ts +117 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/emit.d.ts +9 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24626 -0
- package/dist/manifest.d.ts +39 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/paths.d.ts +57 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/resolve-client-js.d.ts +6 -0
- package/dist/resolve-client-js.d.ts.map +1 -0
- package/dist/types.d.ts +141 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +55 -0
- package/src/__tests__/child-marker.test.ts +24 -0
- package/src/__tests__/compile-cache.test.ts +73 -0
- package/src/__tests__/component-dir-entry.test.ts +239 -0
- package/src/__tests__/component-manifest.test.ts +124 -0
- package/src/__tests__/corpus-program.test.ts +244 -0
- package/src/__tests__/debounced-serial-runner.test.ts +131 -0
- package/src/__tests__/dev-server.test.ts +138 -0
- package/src/__tests__/discover.test.ts +148 -0
- package/src/__tests__/e2e-vite-build.test.ts +191 -0
- package/src/__tests__/e2e-vite-dev.test.ts +478 -0
- package/src/__tests__/emit.test.ts +73 -0
- package/src/__tests__/manifest.test.ts +146 -0
- package/src/__tests__/paths.test.ts +93 -0
- package/src/__tests__/plugin.test.ts +417 -0
- package/src/__tests__/relative-import-rewrite.test.ts +79 -0
- package/src/__tests__/resolve-client-js.test.ts +55 -0
- package/src/__tests__/templates-optional.test.ts +139 -0
- package/src/child-marker.ts +67 -0
- package/src/compile-cache.ts +63 -0
- package/src/component-manifest.ts +139 -0
- package/src/corpus-program.ts +125 -0
- package/src/debounced-serial-runner.ts +67 -0
- package/src/dev-server.ts +184 -0
- package/src/discover.ts +230 -0
- package/src/emit.ts +66 -0
- package/src/index.ts +25 -0
- package/src/manifest.ts +89 -0
- package/src/paths.ts +114 -0
- package/src/plugin.ts +792 -0
- package/src/resolve-client-js.ts +34 -0
- package/src/types.ts +144 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `resolveId` shim: maps the compiler's synthesized `./foo.client.js`
|
|
3
|
+
* sibling-import specifier back to the real `./foo.tsx` source file on
|
|
4
|
+
* disk. There is no `.client.js` file for Vite to find — the compiler only
|
|
5
|
+
* ever read `foo.tsx`.
|
|
6
|
+
*
|
|
7
|
+
* Scope, per the spike (spike-findings.md, R2): the `.client.js` rewrite
|
|
8
|
+
* (`packages/jsx/src/ir-to-client-js/imports.ts:177`, gated by
|
|
9
|
+
* `analyzer.ts`'s `scanImportedClientSignals`) only ever fires for
|
|
10
|
+
* **relative** specifiers (`./`, `../`) that import a module exporting
|
|
11
|
+
* client signals — alias imports (`@/components/foo`) are never rewritten
|
|
12
|
+
* by the compiler, so they reach Vite as plain bare specifiers that
|
|
13
|
+
* `resolve.alias` already resolves natively (proven in the spike: both
|
|
14
|
+
* resolution paths converge on the same module id and Rollup dedupes them
|
|
15
|
+
* into one shared chunk). Do NOT add alias handling here.
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync } from 'node:fs'
|
|
18
|
+
import { dirname, resolve } from 'node:path'
|
|
19
|
+
|
|
20
|
+
const CLIENT_JS_SUFFIX = '.client.js'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Resolve `source` (an import specifier seen by Vite's `resolveId`) to the
|
|
24
|
+
* real `.tsx` file it stands in for, or `null` if this shim doesn't apply.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveClientJsSpecifier(source: string, importer: string | undefined): string | null {
|
|
27
|
+
if (!source.endsWith(CLIENT_JS_SUFFIX)) return null
|
|
28
|
+
if (!source.startsWith('./') && !source.startsWith('../')) return null
|
|
29
|
+
if (!importer) return null
|
|
30
|
+
|
|
31
|
+
const candidateBase = resolve(dirname(importer), source.slice(0, -CLIENT_JS_SUFFIX.length))
|
|
32
|
+
const tsxPath = `${candidateBase}.tsx`
|
|
33
|
+
return existsSync(tsxPath) ? tsxPath : null
|
|
34
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { TemplateAdapter } from '@barefootjs/jsx'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Narrow context handed to `afterEmit` once per eager pass (`writeBundle`
|
|
5
|
+
* for `vite build`, the dev pass for `vite dev`) — AFTER every discovered
|
|
6
|
+
* component's template has already been written to `templatesDir`. This is
|
|
7
|
+
* the one escape hatch this plugin exposes, and its shape is deliberately
|
|
8
|
+
* minimal:
|
|
9
|
+
*
|
|
10
|
+
* - `types`: adapter-generated `types` fragments (e.g. Go Props structs)
|
|
11
|
+
* this pass produced, keyed by the source file's absolute path. Raw,
|
|
12
|
+
* per-file, uncombined — combining them into a single backend-native
|
|
13
|
+
* file (stripping headers, deduping, injecting shared helpers) is a
|
|
14
|
+
* real per-language operation an adapter's own `/vite` subpath performs
|
|
15
|
+
* (see `@barefootjs/go-template/vite`'s use of `combineGoTypes`), not
|
|
16
|
+
* something core knows how to do generically.
|
|
17
|
+
* - `projectDir` / `templatesDir` / `outDir`: the same absolute paths the
|
|
18
|
+
* plugin itself just used to write templates and (for `outDir`) that
|
|
19
|
+
* Vite wrote client assets to.
|
|
20
|
+
* - `mode`: which eager pass just ran. Go's `components.go` (and any other
|
|
21
|
+
* adapter-side derived file) has to exist for `go run .` to even compile
|
|
22
|
+
* in dev, which is why this fires from BOTH passes, not just the build
|
|
23
|
+
* one — a hook named `postBuild` would misleadingly suggest otherwise.
|
|
24
|
+
*
|
|
25
|
+
* What this deliberately does NOT carry: emitted client JS. That's the
|
|
26
|
+
* one thing a caller must never be handed to rewrite post-compile (see
|
|
27
|
+
* CLAUDE.md's "never add compiler options/hooks for tool-specific output
|
|
28
|
+
* rewriting") — closing that door by TYPE, not by convention, is the
|
|
29
|
+
* point of keeping this context this narrow.
|
|
30
|
+
*/
|
|
31
|
+
export interface AfterEmitContext {
|
|
32
|
+
/** Per-source-file `types` output, keyed by that file's absolute path.
|
|
33
|
+
* Empty when no discovered file in this pass produced a `types` output. */
|
|
34
|
+
types: Map<string, string>
|
|
35
|
+
/** Absolute path to the Vite project root. */
|
|
36
|
+
projectDir: string
|
|
37
|
+
/** Absolute path to the configured `templates` output dir. */
|
|
38
|
+
templatesDir: string
|
|
39
|
+
/** Absolute path to Vite's configured `build.outDir`. */
|
|
40
|
+
outDir: string
|
|
41
|
+
/** Which eager pass just ran. */
|
|
42
|
+
mode: 'build' | 'dev'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* One `components` entry with per-directory compile behavior. A plain
|
|
47
|
+
* string is exactly equivalent to `{ dir: string }` — see
|
|
48
|
+
* `BarefootViteOptions.components`.
|
|
49
|
+
*/
|
|
50
|
+
export interface ComponentDirEntry {
|
|
51
|
+
/** Source directory to scan, relative to the Vite root (or absolute). */
|
|
52
|
+
dir: string
|
|
53
|
+
/** `CompileOptions.cssLayerPrefix` for every component under `dir`:
|
|
54
|
+
* static class strings get `layer-{value}:` prefixes so a library's
|
|
55
|
+
* base classes land in a lower cascade layer than app overrides. Set
|
|
56
|
+
* it on library entries, leave it off app entries. */
|
|
57
|
+
cssLayerPrefix?: string
|
|
58
|
+
/** Directory NAMES to skip anywhere under `dir` (e.g. `['shared']`). */
|
|
59
|
+
skipDirs?: string[]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Public options for the `barefoot()` Vite plugin. Exactly three
|
|
64
|
+
* BarefootJS-specific FIELDS — everything else (bundling, hashing,
|
|
65
|
+
* chunking, tree-shaking, minification, dev server, `base`, `outDir`) is
|
|
66
|
+
* stock Vite config. Do not add more fields here; see the design doc for
|
|
67
|
+
* the full list of options this deliberately drops in favor of Vite's own
|
|
68
|
+
* equivalents (`minify` → `build.minify`, `externals` → Rollup's automatic
|
|
69
|
+
* chunk splitting, `clientJsBasePath`/`barefootJsPath` → `base` + manifest
|
|
70
|
+
* resolution, etc).
|
|
71
|
+
*
|
|
72
|
+
* The cap is on FIELDS, not on per-directory expressiveness: whether a
|
|
73
|
+
* directory's classes need a CSS cascade layer, or which subdirectories to
|
|
74
|
+
* skip, is a function of WHICH `components` entry a file came from — so
|
|
75
|
+
* that behavior rides on the `components` entries themselves
|
|
76
|
+
* (`ComponentDirEntry`) rather than becoming a 4th/5th top-level option.
|
|
77
|
+
*/
|
|
78
|
+
export interface BarefootViteOptions {
|
|
79
|
+
/** A constructed `TemplateAdapter` instance (e.g. `new
|
|
80
|
+
* GoTemplateAdapter({ packageName: 'main' })`). Not a factory function —
|
|
81
|
+
* the plugin never constructs adapters itself. */
|
|
82
|
+
adapter: TemplateAdapter
|
|
83
|
+
/** Source directories to scan for `.tsx` components, relative to the
|
|
84
|
+
* Vite project root (or absolute). A plain string is exactly equivalent
|
|
85
|
+
* to `{ dir: string }` (a `ComponentDirEntry` with no `cssLayerPrefix`/
|
|
86
|
+
* `skipDirs`) — use the object form only when a directory needs one of
|
|
87
|
+
* those. Entries are processed in array order, and that order is also
|
|
88
|
+
* the precedence when the same file is reachable under more than one
|
|
89
|
+
* entry: the first entry wins. */
|
|
90
|
+
components: (string | ComponentDirEntry)[]
|
|
91
|
+
/**
|
|
92
|
+
* Where compiled templates, `ssrDefaults`, and adapter-generated types
|
|
93
|
+
* land — relative to the Vite project root (or absolute). This is a
|
|
94
|
+
* backend source directory the server-side app reads, NOT
|
|
95
|
+
* `build.outDir` (which is Vite's client-asset output).
|
|
96
|
+
*
|
|
97
|
+
* Optional for an adapter whose `generate()` output is ALWAYS empty
|
|
98
|
+
* (e.g. `CSRAdapter` — CSR has no template-language backend to point a
|
|
99
|
+
* `templates` dir at). When omitted, the eager pass still compiles every
|
|
100
|
+
* discovered component (client JS generation is unaffected) but writes
|
|
101
|
+
* nothing to disk on its behalf — no per-component template/ssrDefaults/
|
|
102
|
+
* types files, no `manifest.json`. If some discovered component turns
|
|
103
|
+
* out to produce a REAL (non-empty) template anyway, the eager pass
|
|
104
|
+
* refuses loudly instead of silently dropping it: omitting `templates`
|
|
105
|
+
* is a claim about the adapter's output that this plugin verifies rather
|
|
106
|
+
* than trusts. See `plugin.ts`'s `assertNoRealTemplateOutput`.
|
|
107
|
+
*/
|
|
108
|
+
templates?: string
|
|
109
|
+
/**
|
|
110
|
+
* Optional escape hatch called once per eager pass (build AND dev), after
|
|
111
|
+
* templates are written, with a narrow `AfterEmitContext`. NOT a
|
|
112
|
+
* user-facing 4th option in the design-doc sense — it exists so an
|
|
113
|
+
* adapter's own `/vite` subpath (e.g. `@barefootjs/go-template/vite`) can
|
|
114
|
+
* wire up its own per-language post-processing (e.g. combining `types`
|
|
115
|
+
* into a single `components.go`) while calling this core plugin
|
|
116
|
+
* underneath. See `AfterEmitContext`'s docstring for what it can and
|
|
117
|
+
* cannot see.
|
|
118
|
+
*/
|
|
119
|
+
afterEmit?: (ctx: AfterEmitContext) => Promise<void> | void
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Shape exposed on the returned plugin's `.api` — Vite's own convention
|
|
124
|
+
* (a plugin may attach an `api` property "designed for other plugins or
|
|
125
|
+
* Vite-based tools to access") for exactly this: tooling that wants this
|
|
126
|
+
* plugin's resolved options without re-deriving them from `vite.config.ts`
|
|
127
|
+
* text. The `bf` CLI (`packages/cli/src/context.ts`) is the one consumer
|
|
128
|
+
* today — it uses Vite's own `loadConfigFromFile` to get the resolved
|
|
129
|
+
* config, finds the plugin by name (`PLUGIN_NAME`, exported from
|
|
130
|
+
* `plugin.ts`) in its `plugins` array, and reads `api.options.components`
|
|
131
|
+
* as `sourceDirs`.
|
|
132
|
+
*
|
|
133
|
+
* Populated synchronously the moment `barefoot(options)` is called —
|
|
134
|
+
* `options` needs no Vite lifecycle hook to have already run, deliberately:
|
|
135
|
+
* `loadConfigFromFile` never calls a plugin's hooks (`config`,
|
|
136
|
+
* `configResolved`, ...) at all, it just evaluates `vite.config.ts` and
|
|
137
|
+
* returns the resulting plugin instances, so anything gated behind
|
|
138
|
+
* `configResolved` (e.g. the plugin's own resolved absolute `componentDirs`)
|
|
139
|
+
* would never be visible to a caller going through that path.
|
|
140
|
+
*/
|
|
141
|
+
export interface BarefootPluginApi {
|
|
142
|
+
/** The exact options object `barefoot()` was constructed with. */
|
|
143
|
+
options: BarefootViteOptions
|
|
144
|
+
}
|