Skip to content

Commit 91e0c91

Browse files
docs: plugin. (#73)
1 parent 1e9fc0d commit 91e0c91

3 files changed

Lines changed: 182 additions & 0 deletions

File tree

docs/loader.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ augmented exports to be present on the original JS/TS module. Use the resolver p
5353
to automatically append `?knighted-css` for any module import that has a generated
5454
sidecar `.d.ts` file.
5555

56+
See [docs/plugin.md](./plugin.md) for full resolver plugin documentation.
57+
5658
```js
5759
// rspack.config.js
5860
import { knightedCssResolverPlugin } from '@knighted/css/plugin'

docs/plugin.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Resolver plugin (`KnightedCssResolverPlugin`)
2+
3+
`KnightedCssResolverPlugin` is the resolver companion for declaration mode. It teaches your
4+
bundler to rewrite module imports to `?knighted-css` (and `&combined` when applicable) when a
5+
matching declaration sidecar exists, so runtime exports stay aligned with the generated types.
6+
7+
Without the plugin, TypeScript may compile, but the bundler will load the original module
8+
without the loader query. That means `knightedCss`, `stableSelectors`, or other injected exports
9+
will be missing at runtime.
10+
11+
## What it does
12+
13+
- Scans resolved JS/TS module requests.
14+
- Looks for a declaration sidecar (`.d.ts`) generated by `knighted-css-generate-types --mode declaration`.
15+
- If a sidecar is found, rewrites the request to append `?knighted-css`.
16+
- Optionally enforces strict sidecar matches using a manifest to avoid accidental rewrites.
17+
- Optionally marks “combined” entries (via `combinedPaths`) so the query includes `&combined`.
18+
19+
## API
20+
21+
The idiomatic usage is to instantiate the class:
22+
23+
```ts
24+
import { KnightedCssResolverPlugin } from '@knighted/css/plugin'
25+
26+
new KnightedCssResolverPlugin(options)
27+
```
28+
29+
If you prefer a factory function, the package also exports `knightedCssResolverPlugin` which
30+
returns the same plugin instance:
31+
32+
```ts
33+
import { knightedCssResolverPlugin } from '@knighted/css/plugin'
34+
35+
knightedCssResolverPlugin(options)
36+
```
37+
38+
### Options
39+
40+
```ts
41+
type KnightedCssResolverPluginOptions = {
42+
rootDir?: string
43+
tsconfig?: string | Record<string, unknown>
44+
conditions?: string[]
45+
extensions?: string[]
46+
debug?: boolean
47+
combinedPaths?: Array<string | RegExp>
48+
strictSidecar?: boolean
49+
manifestPath?: string
50+
}
51+
```
52+
53+
- `rootDir` (optional): Base directory used for resolver scoping. Defaults to `process.cwd()`.
54+
- `tsconfig` (optional): Path to a tsconfig or an in-memory tsconfig object for path resolution.
55+
- `conditions` (optional): Custom `package.json` export conditions to honor during resolution.
56+
- `extensions` (optional): File extensions considered as script modules. Defaults to
57+
`.ts`, `.tsx`, `.js`, `.jsx`, `.mts`, `.cts`, `.mjs`, `.cjs`.
58+
- `debug` (optional): Logs rewrite decisions and a summary of cache hits/misses.
59+
- `combinedPaths` (optional): List of strings or regexes. Any resolved path that matches will
60+
receive `&combined` alongside `?knighted-css`.
61+
- `strictSidecar` (optional): When true, only modules present in the manifest are rewritten.
62+
Defaults to true when `manifestPath` is provided.
63+
- `manifestPath` (optional): Path to the sidecar manifest generated by
64+
`knighted-css-generate-types --manifest`. Used for strict matching.
65+
66+
## Basic usage (declaration mode)
67+
68+
```js
69+
// rspack.config.js
70+
import { KnightedCssResolverPlugin } from '@knighted/css/plugin'
71+
72+
export default {
73+
resolve: {
74+
plugins: [new KnightedCssResolverPlugin()],
75+
},
76+
}
77+
```
78+
79+
```ts
80+
// Type generation
81+
knighted-css-generate-types --root . --include src --mode declaration
82+
```
83+
84+
This lets you write clean imports while still receiving `knightedCss` at runtime:
85+
86+
```ts
87+
import { Button, knightedCss } from './button.js'
88+
```
89+
90+
## Strict sidecar + manifest (recommended)
91+
92+
Use strict sidecars to avoid rewriting modules that merely happen to have a `.d.ts` next to
93+
them. This ensures only declaration mode sidecars generated by the CLI trigger rewrites.
94+
95+
```sh
96+
knighted-css-generate-types --root . --include src --mode declaration --manifest .knighted-css/knighted-manifest.json
97+
```
98+
99+
```js
100+
// rspack.config.js
101+
import path from 'node:path'
102+
import { KnightedCssResolverPlugin } from '@knighted/css/plugin'
103+
104+
export default {
105+
resolve: {
106+
plugins: [
107+
new KnightedCssResolverPlugin({
108+
strictSidecar: true,
109+
manifestPath: path.resolve('.knighted-css/knighted-manifest.json'),
110+
}),
111+
],
112+
},
113+
}
114+
```
115+
116+
## Combined imports
117+
118+
If you have modules that are consumed with combined exports (`?knighted-css&combined`),
119+
set `combinedPaths` to ensure the resolver appends `&combined` during rewrites.
120+
121+
Example of an import that relies on `&combined` at runtime:
122+
123+
```ts
124+
import { Card, knightedCss } from './combined-card.js'
125+
```
126+
127+
And how you would use `combinedPaths` to support that:
128+
129+
```js
130+
import path from 'node:path'
131+
import { KnightedCssResolverPlugin } from '@knighted/css/plugin'
132+
133+
export default {
134+
resolve: {
135+
plugins: [
136+
new KnightedCssResolverPlugin({
137+
combinedPaths: [
138+
path.resolve('src/components/combined-card.tsx'),
139+
/src\/views\/.*\.tsx$/,
140+
],
141+
}),
142+
],
143+
},
144+
}
145+
```
146+
147+
## Debugging
148+
149+
Enable `debug: true` to log each decision and a final summary that includes counts for
150+
rewrites, cache hits, marker misses, and manifest misses.
151+
152+
```js
153+
import { KnightedCssResolverPlugin } from '@knighted/css/plugin'
154+
155+
export default {
156+
resolve: {
157+
plugins: [new KnightedCssResolverPlugin({ debug: true })],
158+
},
159+
}
160+
```

docs/type-generation.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Wire it into `postinstall` or your build so new selectors land automatically.
4040
| `declaration` | Plain JS/TS imports | `.d.ts` augmentations next to modules | Required (append `?knighted-css`) | Cleaner imports when you accept resolver overhead |
4141

4242
If you use declaration mode, prefer enabling strict sidecars + a manifest so the resolver only rewrites imports that the CLI generated.
43+
See [docs/plugin.md](./plugin.md) for resolver plugin details and configuration options.
4344

4445
### Relationship to the loader
4546

@@ -80,6 +81,25 @@ import Button, { knightedCss, stableSelectors } from './button.js'
8081
> [!IMPORTANT]
8182
> Declaration mode requires a resolver plugin to append `?knighted-css` (and `&combined` when applicable)
8283
> at build time so runtime exports match the generated types.
84+
> See [docs/plugin.md](./plugin.md) for resolver plugin configuration.
85+
86+
### How declaration sidecars are chosen
87+
88+
The CLI only emits `.d.ts` sidecars for files that pass all of the following checks:
89+
90+
- **Inside your include set**: it walks each `--include` entry recursively, skipping common build
91+
folders (`node_modules`, `dist`, `build`, `.knighted-css`, etc.), and only considers script
92+
files (`.ts`, `.tsx`, `.js`, `.jsx`, `.mts`, `.cts`, `.mjs`, `.cjs`). Existing `.d.ts` files
93+
are ignored.
94+
- **Within the project root**: if a candidate file resolves outside `--root`, the CLI skips it
95+
and logs a warning.
96+
- **Imports styles**: the file must import/require a style resource directly (e.g. `.css`,
97+
`.scss`, `.sass`, `.less`) or resolve to one via tsconfig paths / resolver hooks.
98+
- **Produces selectors**: the extracted CSS must be non-empty and yield at least one selector
99+
token; otherwise the sidecar is skipped.
100+
101+
In other words, declaration mode is opt-in by usage: only JS/TS/JSX/TSX modules that actually pull in
102+
styles get a generated `.d.ts` augmentation.
83103

84104
### Sidecar manifests + strict resolver mode
85105

0 commit comments

Comments
 (0)