unplugin-docubook 1.1.1 → 1.1.3
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/README.md +384 -96
- package/dist/astro.cjs +1 -1
- package/dist/astro.cjs.map +1 -1
- package/dist/astro.js +1 -1
- package/dist/astro.js.map +1 -1
- package/dist/bun.cjs +1 -1
- package/dist/bun.cjs.map +1 -1
- package/dist/bun.js +1 -1
- package/dist/bun.js.map +1 -1
- package/dist/components/index.cjs +56 -53
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +56 -53
- package/dist/components/index.js.map +1 -1
- package/dist/components/theme.css +121 -0
- package/dist/components/theme.css.map +1 -0
- package/dist/esbuild.cjs +1 -1
- package/dist/esbuild.cjs.map +1 -1
- package/dist/esbuild.js +1 -1
- package/dist/esbuild.js.map +1 -1
- package/dist/farm.cjs +1 -1
- package/dist/farm.cjs.map +1 -1
- package/dist/farm.js +1 -1
- package/dist/farm.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +1 -1
- package/dist/next.cjs.map +1 -1
- package/dist/next.js +1 -1
- package/dist/next.js.map +1 -1
- package/dist/nuxt.cjs +1 -1
- package/dist/nuxt.cjs.map +1 -1
- package/dist/nuxt.js +1 -1
- package/dist/nuxt.js.map +1 -1
- package/dist/rolldown.cjs +1 -1
- package/dist/rolldown.cjs.map +1 -1
- package/dist/rolldown.js +1 -1
- package/dist/rolldown.js.map +1 -1
- package/dist/rollup.cjs +1 -1
- package/dist/rollup.cjs.map +1 -1
- package/dist/rollup.js +1 -1
- package/dist/rollup.js.map +1 -1
- package/dist/rspack.cjs +1 -1
- package/dist/rspack.cjs.map +1 -1
- package/dist/rspack.js +1 -1
- package/dist/rspack.js.map +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.js +1 -1
- package/dist/vite.js.map +1 -1
- package/dist/webpack.cjs +1 -1
- package/dist/webpack.cjs.map +1 -1
- package/dist/webpack.js +1 -1
- package/dist/webpack.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,156 +1,444 @@
|
|
|
1
|
-
#
|
|
1
|
+
# <img src="./docu.svg" width="32" height="32" valign="middle" /> @DocuBook/content
|
|
2
|
+
|
|
2
3
|
The Universal Documentation Engine for any JavaScript Framework.
|
|
3
4
|
|
|
4
5
|
> Write with MDX — works with pretty much any JS framework: Vite, React, Vue, Svelte, you name it!
|
|
5
6
|
|
|
6
7
|
## Features
|
|
7
|
-
- 🚀 **Framework Agnostic**:
|
|
8
|
-
- 🛠️ **Unified Pipeline**: Built on top of
|
|
9
|
-
- 📦 **
|
|
10
|
-
-
|
|
8
|
+
- 🚀 **Framework Agnostic**: Native support for React, Vue, and Svelte.
|
|
9
|
+
- 🛠️ **Unified Pipeline**: Built on top of Unplugin for cross-bundler compatibility.
|
|
10
|
+
- 📦 **Zero-Import Components**: Use `<Accordion />`, `<Tabs />`, `<Note />` etc., directly in MDX without manual imports.
|
|
11
|
+
- 🎨 **Themeable**: Built-in beautiful design tokens, easily customizable via CSS variables.
|
|
12
|
+
- ⚡ **Performance First**: Regex-based detection with memoization and safe-stripping logic.
|
|
13
|
+
|
|
14
|
+
---
|
|
11
15
|
|
|
12
|
-
##
|
|
16
|
+
## 🛠️ Installation
|
|
13
17
|
|
|
18
|
+
### 1. Install Package
|
|
14
19
|
```bash
|
|
15
20
|
npm install unplugin-docubook
|
|
16
21
|
```
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
### 2. Install Icon Dependencies
|
|
24
|
+
DocuBook uses Lucide for its UI icons. Install the version corresponding to your framework:
|
|
25
|
+
```bash
|
|
26
|
+
# For React / Next.js
|
|
27
|
+
npm install lucide-react
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import DocuBook from 'unplugin-docubook/vite'
|
|
25
|
-
import { defineConfig } from 'vite'
|
|
29
|
+
# For Vue / Nuxt
|
|
30
|
+
npm install lucide-vue-next
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
DocuBook({ /* options */ }),
|
|
30
|
-
],
|
|
31
|
-
})
|
|
32
|
+
# For Svelte / Astro
|
|
33
|
+
npm install lucide-svelte
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
## 🎨 Theming & Customization
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
// rollup.config.ts
|
|
38
|
-
import DocuBook from 'unplugin-docubook/rollup'
|
|
38
|
+
DocuBook uses CSS variables for theming. You can override these variables to customize the appearance of components.
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
plugins: [
|
|
42
|
-
DocuBook({ /* options */ }),
|
|
43
|
-
],
|
|
44
|
-
}
|
|
45
|
-
```
|
|
40
|
+
### Quick Start
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
> Import the DocuBook theme in your entry file (`main.ts`, `App.tsx`, etc.)
|
|
48
43
|
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
module.exports = {
|
|
52
|
-
/* ... */
|
|
53
|
-
plugins: [
|
|
54
|
-
require('unplugin-docubook/webpack')({ /* options */ }),
|
|
55
|
-
],
|
|
56
|
-
}
|
|
44
|
+
```typescript
|
|
45
|
+
import 'unplugin-docubook/theme.css';
|
|
57
46
|
```
|
|
58
47
|
|
|
59
|
-
###
|
|
48
|
+
### Override CSS Variables
|
|
49
|
+
|
|
50
|
+
<details>
|
|
51
|
+
<summary><b>Base Colors</b></summary>
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
:root {
|
|
55
|
+
/* Background & Foreground */
|
|
56
|
+
--background: 210 40% 98%;
|
|
57
|
+
--foreground: 220 30% 15%;
|
|
58
|
+
|
|
59
|
+
/* Card */
|
|
60
|
+
--card: 0 0% 100%;
|
|
61
|
+
--card-foreground: 220 30% 15%;
|
|
62
|
+
|
|
63
|
+
/* Popover */
|
|
64
|
+
--popover: 0 0% 100%;
|
|
65
|
+
--popover-foreground: 220 30% 15%;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
</details>
|
|
69
|
+
|
|
70
|
+
<details>
|
|
71
|
+
<summary><b>Primary & Accent Colors</b></summary>
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
:root {
|
|
75
|
+
/* Primary - main brand color */
|
|
76
|
+
--primary: 210 81% 56%;
|
|
77
|
+
--primary-foreground: 0 0% 100%;
|
|
78
|
+
|
|
79
|
+
/* Secondary */
|
|
80
|
+
--secondary: 210 30% 90%;
|
|
81
|
+
--secondary-foreground: 220 30% 15%;
|
|
82
|
+
|
|
83
|
+
/* Accent */
|
|
84
|
+
--accent: 200 100% 40%;
|
|
85
|
+
--accent-foreground: 0 0% 100%;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
</details>
|
|
89
|
+
|
|
90
|
+
<details>
|
|
91
|
+
<summary><b>Muted & UI Colors</b></summary>
|
|
92
|
+
|
|
93
|
+
```css
|
|
94
|
+
:root {
|
|
95
|
+
/* Muted */
|
|
96
|
+
--muted: 210 20% 92%;
|
|
97
|
+
--muted-foreground: 220 15% 50%;
|
|
98
|
+
|
|
99
|
+
/* Status */
|
|
100
|
+
--destructive: 0 85% 60%;
|
|
101
|
+
--destructive-foreground: 0 0% 100%;
|
|
102
|
+
--success: 142 70% 50%;
|
|
103
|
+
--success-foreground: 0 0% 100%;
|
|
104
|
+
|
|
105
|
+
/* Border & Input */
|
|
106
|
+
--border: 210 20% 85%;
|
|
107
|
+
--input: 210 20% 85%;
|
|
108
|
+
--ring: 210 81% 56%;
|
|
109
|
+
|
|
110
|
+
/* Radius */
|
|
111
|
+
--radius: 0.5rem;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary><b>Note / Alert Variants</b></summary>
|
|
118
|
+
|
|
119
|
+
```css
|
|
120
|
+
:root {
|
|
121
|
+
/* Note (info) */
|
|
122
|
+
--note-bg: 214 100% 97%;
|
|
123
|
+
--note-border: 214 100% 90%;
|
|
124
|
+
--note-accent: 210 81% 56%;
|
|
125
|
+
--note-text: 220 50% 30%;
|
|
126
|
+
|
|
127
|
+
/* Danger */
|
|
128
|
+
--danger-bg: 0 100% 97%;
|
|
129
|
+
--danger-border: 0 100% 90%;
|
|
130
|
+
--danger-accent: 0 85% 60%;
|
|
131
|
+
--danger-text: 0 50% 30%;
|
|
132
|
+
|
|
133
|
+
/* Warning */
|
|
134
|
+
--warning-bg: 38 100% 97%;
|
|
135
|
+
--warning-border: 38 100% 90%;
|
|
136
|
+
--warning-accent: 38 100% 50%;
|
|
137
|
+
--warning-text: 38 50% 30%;
|
|
138
|
+
|
|
139
|
+
/* Success */
|
|
140
|
+
--success-bg: 142 100% 97%;
|
|
141
|
+
--success-border: 142 100% 90%;
|
|
142
|
+
--success-accent: 142 70% 50%;
|
|
143
|
+
--success-text: 142 50% 25%;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
</details>
|
|
147
|
+
|
|
148
|
+
<details>
|
|
149
|
+
<summary><b>Dark Mode</b></summary>
|
|
150
|
+
|
|
151
|
+
Override colors for dark mode by adding `.dark` class:
|
|
152
|
+
|
|
153
|
+
```css
|
|
154
|
+
.dark {
|
|
155
|
+
--background: 220 25% 10%;
|
|
156
|
+
--foreground: 210 30% 96%;
|
|
157
|
+
--card: 220 25% 15%;
|
|
158
|
+
--card-foreground: 210 30% 96%;
|
|
159
|
+
--primary: 210 100% 65%;
|
|
160
|
+
--primary-foreground: 220 25% 10%;
|
|
161
|
+
--accent: 200 100% 60%;
|
|
162
|
+
--muted: 215 20% 25%;
|
|
163
|
+
--muted-foreground: 215 20% 65%;
|
|
164
|
+
--border: 215 20% 25%;
|
|
165
|
+
--destructive: 0 85% 70%;
|
|
166
|
+
--success: 142 70% 55%;
|
|
167
|
+
|
|
168
|
+
/* Note variants - dark */
|
|
169
|
+
--note-bg: 217 50% 20%;
|
|
170
|
+
--note-border: 217 50% 30%;
|
|
171
|
+
--note-text: 210 30% 90%;
|
|
172
|
+
/* ... etc */
|
|
173
|
+
}
|
|
174
|
+
```
|
|
60
175
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
176
|
+
> [!TIP]
|
|
177
|
+
> DocuBook automatically detects dark mode via the `.dark` class on parent element (compatible with Tailwind CSS).
|
|
178
|
+
</details>
|
|
179
|
+
|
|
180
|
+
<details>
|
|
181
|
+
<summary><b>Shadows & Animations</b></summary>
|
|
182
|
+
|
|
183
|
+
```css
|
|
184
|
+
:root {
|
|
185
|
+
/* Shadows */
|
|
186
|
+
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
187
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
|
188
|
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
|
189
|
+
|
|
190
|
+
/* Animations */
|
|
191
|
+
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
192
|
+
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
68
193
|
}
|
|
69
194
|
```
|
|
195
|
+
</details>
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 🚀 Usage
|
|
70
200
|
|
|
71
|
-
###
|
|
201
|
+
### MDX Content
|
|
202
|
+
No imports needed for core components!
|
|
72
203
|
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
204
|
+
```mdx
|
|
205
|
+
<Accordion title="Getting Started">
|
|
206
|
+
<Note type="success">
|
|
207
|
+
Docubook is now managing your imports.
|
|
208
|
+
</Note>
|
|
209
|
+
|
|
210
|
+
<Card title="Quick Link" icon="zap">
|
|
211
|
+
Check our docs.
|
|
212
|
+
</Card>
|
|
213
|
+
</Accordion>
|
|
214
|
+
```
|
|
77
215
|
|
|
78
|
-
|
|
79
|
-
|
|
216
|
+
### Custom Components
|
|
217
|
+
You can register your own components (project-specific or external) for auto-import:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
DocuBook({
|
|
221
|
+
customComponents: {
|
|
222
|
+
// Relative path (to unplugin-docubook/components)
|
|
223
|
+
MyWidget: { exports: ['MyWidget'], path: '/custom' },
|
|
224
|
+
|
|
225
|
+
// Absolute/Alias path (to your project)
|
|
226
|
+
SpecialButton: { exports: ['Button'], path: '@/components/ui/Button' }
|
|
227
|
+
}
|
|
80
228
|
})
|
|
81
229
|
```
|
|
82
230
|
|
|
83
|
-
|
|
231
|
+
## 🔌 Integration
|
|
232
|
+
|
|
233
|
+
DocuBook is not a replacement for your MDX compiler; it is a **transformer** that works alongside your favorite compiler. DocuBook handles automatic component imports (auto-import) before the MDX is compiled.
|
|
234
|
+
|
|
235
|
+
### Requirement
|
|
236
|
+
You still need an MDX compiler/bundler based on your framework:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# For Vite (React)
|
|
240
|
+
npm install @mdx-js/rollup @mdx-js/react
|
|
241
|
+
|
|
242
|
+
# For Vite (Vue)
|
|
243
|
+
npm install @mdx-js/rollup @mdx-js/vue
|
|
244
|
+
|
|
245
|
+
# For Next.js
|
|
246
|
+
npm install @next/mdx @mdx-js/loader @mdx-js/react
|
|
247
|
+
|
|
248
|
+
# For Svelte
|
|
249
|
+
npm install mdsvex
|
|
250
|
+
|
|
251
|
+
# For Astro
|
|
252
|
+
npm install @astrojs/mdx
|
|
253
|
+
|
|
254
|
+
# For Nuxt
|
|
255
|
+
npm install @nuxtjs/mdc
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
> [!NOTE]
|
|
259
|
+
> **What's the difference with `next-mdx-remote`?**
|
|
260
|
+
> `next-mdx-remote` compiles MDX at runtime. DocuBook (via Webpack/Vite) processes your MDX files at build-time. If you are using local MDX files, DocuBook eliminates the need to write manual imports in every file or repeatedly register components in a provider.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## ⚙️ Configuration
|
|
265
|
+
|
|
266
|
+
> [!TIP]
|
|
267
|
+
> DocuBook supports all major bundlers via `unplugin`. Select your bundler below to see the configuration.
|
|
84
268
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
269
|
+
<details>
|
|
270
|
+
<summary><b>Vite (React)</b></summary>
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// vite.config.ts
|
|
274
|
+
import { defineConfig } from 'vite';
|
|
275
|
+
import react from '@vitejs/plugin-react';
|
|
276
|
+
import mdx from '@mdx-js/rollup';
|
|
277
|
+
import DocuBook from 'unplugin-docubook/vite';
|
|
89
278
|
|
|
90
279
|
export default defineConfig({
|
|
91
280
|
plugins: [
|
|
92
|
-
|
|
281
|
+
react(),
|
|
282
|
+
mdx(),
|
|
283
|
+
DocuBook({
|
|
284
|
+
framework: 'react',
|
|
285
|
+
}),
|
|
93
286
|
],
|
|
94
|
-
})
|
|
287
|
+
});
|
|
95
288
|
```
|
|
289
|
+
</details>
|
|
96
290
|
|
|
97
|
-
|
|
291
|
+
<details>
|
|
292
|
+
<summary><b>Vite (Vue)</b></summary>
|
|
98
293
|
|
|
99
|
-
```
|
|
100
|
-
//
|
|
101
|
-
import
|
|
294
|
+
```typescript
|
|
295
|
+
// vite.config.ts
|
|
296
|
+
import { defineConfig } from 'vite';
|
|
297
|
+
import vue from '@vitejs/plugin-vue';
|
|
298
|
+
import mdx from '@mdx-js/rollup';
|
|
299
|
+
import DocuBook from 'unplugin-docubook/vite';
|
|
102
300
|
|
|
103
|
-
|
|
104
|
-
entrypoints: ['./src/index.ts'],
|
|
105
|
-
outdir: './dist',
|
|
301
|
+
export default defineConfig({
|
|
106
302
|
plugins: [
|
|
107
|
-
|
|
303
|
+
vue(),
|
|
304
|
+
mdx({ providerImportSource: '@mdx-js/vue' }),
|
|
305
|
+
DocuBook({
|
|
306
|
+
framework: 'vue',
|
|
307
|
+
}),
|
|
108
308
|
],
|
|
109
|
-
})
|
|
309
|
+
});
|
|
110
310
|
```
|
|
311
|
+
</details>
|
|
111
312
|
|
|
112
|
-
|
|
313
|
+
<details>
|
|
314
|
+
<summary><b>Next.js (App Router / Pages Router)</b></summary>
|
|
113
315
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
316
|
+
First, install the `@next/mdx` compiler:
|
|
317
|
+
```bash
|
|
318
|
+
npm install @next/mdx @mdx-js/loader @mdx-js/react
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Then configure `next.config.mjs`:
|
|
322
|
+
```javascript
|
|
323
|
+
// next.config.mjs
|
|
324
|
+
import DocuBook from 'unplugin-docubook/webpack';
|
|
325
|
+
import createMDX from '@next/mdx';
|
|
326
|
+
|
|
327
|
+
const withMDX = createMDX({});
|
|
328
|
+
|
|
329
|
+
/** @type {import('next').NextConfig} */
|
|
330
|
+
const nextConfig = {
|
|
331
|
+
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
|
|
332
|
+
webpack(config) {
|
|
333
|
+
config.plugins.push(DocuBook({ framework: 'react' }));
|
|
334
|
+
return config;
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
export default withMDX(nextConfig);
|
|
339
|
+
```
|
|
340
|
+
</details>
|
|
341
|
+
|
|
342
|
+
<details>
|
|
343
|
+
<summary><b>Svelte (Vite)</b></summary>
|
|
344
|
+
|
|
345
|
+
First, install `mdsvex`:
|
|
346
|
+
```bash
|
|
347
|
+
npm install mdsvex
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Then configure `vite.config.ts`:
|
|
351
|
+
```typescript
|
|
352
|
+
// vite.config.ts
|
|
353
|
+
import { defineConfig } from 'vite';
|
|
354
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
355
|
+
import mdsvex from 'mdsvex';
|
|
356
|
+
import DocuBook from 'unplugin-docubook/vite';
|
|
357
|
+
|
|
358
|
+
export default defineConfig({
|
|
359
|
+
plugins: [
|
|
360
|
+
svelte({
|
|
361
|
+
extensions: ['.md', '.mdx'],
|
|
362
|
+
}),
|
|
363
|
+
mdsvex({
|
|
364
|
+
extensions: ['.md', '.mdx'],
|
|
365
|
+
}),
|
|
366
|
+
DocuBook({
|
|
367
|
+
framework: 'svelte',
|
|
368
|
+
}),
|
|
119
369
|
],
|
|
120
|
-
})
|
|
370
|
+
});
|
|
121
371
|
```
|
|
372
|
+
</details>
|
|
373
|
+
|
|
374
|
+
<details>
|
|
375
|
+
<summary><b>Astro</b></summary>
|
|
122
376
|
|
|
123
|
-
|
|
377
|
+
First, install `@astrojs/mdx`:
|
|
378
|
+
```bash
|
|
379
|
+
npm install @astrojs/mdx
|
|
380
|
+
```
|
|
124
381
|
|
|
125
|
-
|
|
382
|
+
Then configure `astro.config.mjs`:
|
|
383
|
+
```javascript
|
|
126
384
|
// astro.config.mjs
|
|
127
|
-
import { defineConfig } from 'astro/config'
|
|
128
|
-
import
|
|
385
|
+
import { defineConfig } from 'astro/config';
|
|
386
|
+
import mdx from '@astrojs/mdx';
|
|
387
|
+
import DocuBook from 'unplugin-docubook/vite';
|
|
129
388
|
|
|
130
389
|
export default defineConfig({
|
|
131
|
-
integrations: [
|
|
132
|
-
|
|
390
|
+
integrations: [mdx()],
|
|
391
|
+
vite: {
|
|
392
|
+
plugins: [
|
|
393
|
+
DocuBook({
|
|
394
|
+
framework: 'svelte', // or 'react' if using React in Astro
|
|
395
|
+
}),
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
});
|
|
133
399
|
```
|
|
400
|
+
</details>
|
|
134
401
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
| Option | Type | Default | Description |
|
|
138
|
-
|--------|------|---------|-------------|
|
|
139
|
-
| `framework` | `'react' \| 'vue' \| 'svelte'` | `'react'` | Target framework |
|
|
140
|
-
| `include` | `string[]` | `['**/*.mdx', '**/*.md']` | Files to include |
|
|
141
|
-
| `exclude` | `string[]` | - | Files to exclude |
|
|
142
|
-
| `importSource` | `string` | `'unplugin-docubook/components'` | Import source for components |
|
|
402
|
+
<details>
|
|
403
|
+
<summary><b>Nuxt (Vue)</b></summary>
|
|
143
404
|
|
|
144
|
-
|
|
405
|
+
First, install `@nuxtjs/mdc`:
|
|
406
|
+
```bash
|
|
407
|
+
npm install @nuxtjs/mdc
|
|
408
|
+
```
|
|
145
409
|
|
|
146
|
-
|
|
147
|
-
|
|
410
|
+
Then configure `nuxt.config.ts`:
|
|
411
|
+
```typescript
|
|
412
|
+
// nuxt.config.ts
|
|
413
|
+
export default defineNuxtConfig({
|
|
414
|
+
modules: ['@nuxtjs/mdc'],
|
|
415
|
+
docubook: {
|
|
416
|
+
framework: 'vue'
|
|
417
|
+
}
|
|
418
|
+
})
|
|
419
|
+
```
|
|
148
420
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
421
|
+
Or use the DocuBook Nuxt module directly:
|
|
422
|
+
```typescript
|
|
423
|
+
// nuxt.config.ts
|
|
424
|
+
export default defineNuxtConfig({
|
|
425
|
+
modules: ['unplugin-docubook/nuxt'],
|
|
426
|
+
docubook: {
|
|
427
|
+
framework: 'vue'
|
|
428
|
+
}
|
|
429
|
+
})
|
|
152
430
|
```
|
|
431
|
+
</details>
|
|
153
432
|
|
|
154
|
-
|
|
433
|
+
<details>
|
|
434
|
+
<summary><b>Webpack / Rollup / Others</b></summary>
|
|
155
435
|
|
|
436
|
+
Import from `unplugin-docubook/webpack` or `unplugin-docubook/rollup` and add to your plugins array.
|
|
437
|
+
</details>
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## License
|
|
156
442
|
MIT
|
|
443
|
+
|
|
444
|
+
|
package/dist/astro.cjs
CHANGED
|
@@ -128,7 +128,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
|
|
|
128
128
|
for (const name of componentNames) {
|
|
129
129
|
const meta = registry[name];
|
|
130
130
|
if (!meta) continue;
|
|
131
|
-
const fullPath = `${importSource}${meta.path}
|
|
131
|
+
const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
|
|
132
132
|
if (!pathToExports.has(fullPath)) {
|
|
133
133
|
pathToExports.set(fullPath, /* @__PURE__ */ new Set());
|
|
134
134
|
}
|
package/dist/astro.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/astro.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import type { Options } from './types'\nimport unplugin from '.'\n\ninterface AstroConfig {\n config: {\n vite: {\n plugins: unknown[]\n }\n }\n}\n\nexport default function (options: Options) {\n return {\n name: 'unplugin-docubook',\n hooks: {\n 'astro:config:setup': async (astro: AstroConfig) => {\n astro.config.vite.plugins ||= []\n astro.config.vite.plugins.push(unplugin.vite(options))\n },\n },\n }\n}\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n const fullPath = `${importSource}${meta.path}`\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["registry","names","exports"]}
|
|
1
|
+
{"version":3,"sources":["../src/astro.ts","../src/index.ts","../src/core/registry.ts","../src/core/transform.ts"],"sourcesContent":["import type { Options } from './types'\nimport unplugin from '.'\n\ninterface AstroConfig {\n config: {\n vite: {\n plugins: unknown[]\n }\n }\n}\n\nexport default function (options: Options) {\n return {\n name: 'unplugin-docubook',\n hooks: {\n 'astro:config:setup': async (astro: AstroConfig) => {\n astro.config.vite.plugins ||= []\n astro.config.vite.plugins.push(unplugin.vite(options))\n },\n },\n }\n}\n","import type { UnpluginFactory } from 'unplugin'\nimport type { Options } from './types'\nimport { createUnplugin } from 'unplugin'\nimport { transformMdx } from './core/transform'\n\nexport const unpluginFactory: UnpluginFactory<Options | undefined> = (\n options,\n) => ({\n name: 'unplugin-docubook',\n\n transformInclude(id) {\n // Only process .mdx and .md files\n return /\\.mdx?$/.test(id)\n },\n\n transform(code, _id) {\n const result = transformMdx(code, options)\n if (!result.hasTransformed) return\n return result.code\n },\n})\n\nexport const unplugin = /* #__PURE__ */ createUnplugin(unpluginFactory)\n\nexport default unplugin\n","import type { Framework } from '../types'\n\nexport interface ComponentMeta {\n exports: string[]\n path: string\n}\n\nconst FRAMEWORK_PATHS: Record<Framework, string> = {\n react: '/react',\n vue: '/vue',\n svelte: '/svelte',\n}\n\nfunction createRegistry(framework: Framework): Record<string, ComponentMeta> {\n const basePath = FRAMEWORK_PATHS[framework]\n\n return {\n Note: { exports: ['Note'], path: basePath },\n Card: { exports: ['Card'], path: basePath },\n CardGroup: { exports: ['CardGroup'], path: basePath },\n Accordion: { exports: ['Accordion'], path: basePath },\n AccordionGroup: { exports: ['AccordionGroup'], path: basePath },\n Stepper: { exports: ['Stepper', 'StepperItem'], path: basePath },\n Kbd: { exports: ['Kbd'], path: basePath },\n Tooltip: { exports: ['Tooltip'], path: basePath },\n Youtube: { exports: ['Youtube'], path: basePath },\n Button: { exports: ['Button'], path: basePath },\n DocuLink: { exports: ['DocuLink'], path: basePath },\n DocuImage: { exports: ['DocuImage'], path: basePath },\n Files: { exports: ['Files'], path: basePath },\n Folder: { exports: ['Folder'], path: basePath },\n File: { exports: ['File'], path: basePath },\n Release: { exports: ['Release'], path: basePath },\n Changes: { exports: ['Changes'], path: basePath },\n Pre: { exports: ['Pre'], path: basePath },\n Copy: { exports: ['Copy'], path: basePath },\n DocuBookProvider: { exports: ['DocuBookProvider'], path: basePath },\n }\n}\n\nconst registryCache = new Map<Framework, Record<string, ComponentMeta>>()\nconst regexCache = new Map<Framework, RegExp>()\n\nexport function getComponentRegistry(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): Record<string, ComponentMeta> {\n if (!customComponents || Object.keys(customComponents).length === 0) {\n const cached = registryCache.get(framework)\n if (cached) return cached\n const registry = createRegistry(framework)\n registryCache.set(framework, registry)\n return registry\n }\n // Merge custom components with built-in (custom overrides built-in)\n return { ...createRegistry(framework), ...customComponents }\n}\n\nexport function buildComponentDetectionRegex(\n framework: Framework = 'react',\n customComponents?: Record<string, ComponentMeta>,\n): RegExp {\n // Custom components: always build fresh regex (not cached)\n if (customComponents && Object.keys(customComponents).length > 0) {\n const registry = getComponentRegistry(framework, customComponents)\n const names = Object.keys(registry)\n return new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n }\n\n const cached = regexCache.get(framework)\n if (cached) {\n cached.lastIndex = 0 // Reset regex state because of /g flag\n return cached\n }\n const registry = getComponentRegistry(framework)\n const names = Object.keys(registry)\n const regex = new RegExp(`<(${names.join('|')})(?=[\\\\s/>])`, 'g')\n regexCache.set(framework, regex)\n return regex\n}\n","import type { Options, Framework } from '../types'\nimport type { ComponentMeta } from './registry'\nimport { getComponentRegistry, buildComponentDetectionRegex } from './registry'\n\nconst DEFAULT_IMPORT_SOURCE = 'unplugin-docubook/components'\nconst DEFAULT_FRAMEWORK: Framework = 'react'\n\n/**\n * Strip content zones where component tags should NOT be detected:\n * - Fenced code blocks (triple backticks)\n * - Inline code (single backticks)\n * - MDX comments\n * - HTML comments\n * - Existing import/export statements\n */\nfunction stripIgnoredZones(code: string): string {\n return code\n .replace(/```[\\s\\S]*?```/g, '') // fenced code blocks\n .replace(/`[^`]+`/g, '') // inline code\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, '') // MDX comments {/* */}\n .replace(/<!--[\\s\\S]*?-->/g, '') // HTML comments\n .replace(/^import\\s.+$/gm, '') // existing imports\n .replace(/^export\\s.+$/gm, '') // exports\n}\n\nexport function detectComponents(\n code: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string[] {\n const strippedCode = stripIgnoredZones(code)\n const regex = buildComponentDetectionRegex(framework, customComponents)\n const registry = getComponentRegistry(framework, customComponents)\n const found = new Set<string>()\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(strippedCode)) !== null) {\n const name = match[1]\n if (name && registry[name]) {\n found.add(name)\n }\n }\n\n return Array.from(found)\n}\n\nexport function generateImports(\n componentNames: string[],\n importSource: string,\n framework: Framework = DEFAULT_FRAMEWORK,\n customComponents?: Record<string, ComponentMeta>,\n): string {\n const registry = getComponentRegistry(framework, customComponents)\n const pathToExports = new Map<string, Set<string>>()\n\n for (const name of componentNames) {\n const meta = registry[name]\n if (!meta) continue\n\n // If path starts with '/', it's relative to importSource.\n // Otherwise, it's a full import path (e.g. '@/components/MyComp' or 'my-lib')\n const fullPath = meta.path.startsWith('/')\n ? `${importSource}${meta.path}`\n : meta.path\n\n if (!pathToExports.has(fullPath)) {\n pathToExports.set(fullPath, new Set())\n }\n for (const exp of meta.exports) {\n pathToExports.get(fullPath)!.add(exp)\n }\n }\n\n const lines: string[] = []\n for (const [path, exports] of pathToExports) {\n const names = Array.from(exports).sort().join(', ')\n lines.push(`import { ${names} } from '${path}'`)\n }\n\n return lines.join('\\n')\n}\n\nexport function transformMdx(\n code: string,\n options: Options = {},\n): { code: string; hasTransformed: boolean } {\n const framework = options.framework ?? DEFAULT_FRAMEWORK\n const usedComponents = detectComponents(code, framework, options.customComponents)\n\n if (usedComponents.length === 0) {\n return { code, hasTransformed: false }\n }\n\n const importSource = options.importSource ?? DEFAULT_IMPORT_SOURCE\n const importStatements = generateImports(usedComponents, importSource, framework, options.customComponents)\n\n return {\n code: `${importStatements}\\n\\n${code}`,\n hasTransformed: true,\n }\n}\n\n"],"mappings":"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","names":["registry","names","exports"]}
|
package/dist/astro.js
CHANGED
|
@@ -105,7 +105,7 @@ function generateImports(componentNames, importSource, framework = DEFAULT_FRAME
|
|
|
105
105
|
for (const name of componentNames) {
|
|
106
106
|
const meta = registry[name];
|
|
107
107
|
if (!meta) continue;
|
|
108
|
-
const fullPath = `${importSource}${meta.path}
|
|
108
|
+
const fullPath = meta.path.startsWith("/") ? `${importSource}${meta.path}` : meta.path;
|
|
109
109
|
if (!pathToExports.has(fullPath)) {
|
|
110
110
|
pathToExports.set(fullPath, /* @__PURE__ */ new Set());
|
|
111
111
|
}
|