uniweb 0.2.29 → 0.2.31
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 +22 -13
- package/package.json +4 -4
- package/src/commands/build.js +21 -16
- package/src/index.js +6 -2
- package/templates/_shared/CLAUDE.md.hbs +10 -8
- package/templates/multi/CLAUDE.md.hbs +2 -2
- package/templates/multi/foundations/default/package.json.hbs +2 -2
- package/templates/multi/sites/main/package.json.hbs +1 -2
- package/templates/single/README.md.hbs +1 -1
- package/templates/single/foundation/package.json.hbs +2 -2
- package/templates/single/site/package.json.hbs +1 -2
- package/templates/template/template/foundation/package.json.hbs +2 -2
- package/templates/template/template/site/package.json.hbs +1 -2
- package/templates/multi/foundations/default/src/entry-runtime.js +0 -3
- package/templates/single/foundation/src/entry-runtime.js +0 -3
- package/templates/single/foundation/src/index.js +0 -35
- package/templates/template/template/foundation/src/entry-runtime.js +0 -3
- package/templates/template/template/foundation/src/index.js +0 -36
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ my-project/
|
|
|
32
32
|
│ ├── locales/ # i18n (hash-based translations)
|
|
33
33
|
│ │ ├── manifest.json # Auto-extracted strings
|
|
34
34
|
│ │ └── es.json # Spanish translations
|
|
35
|
-
│ ├── main.js #
|
|
35
|
+
│ ├── main.js # Entry point (~6 lines)
|
|
36
36
|
│ ├── vite.config.js # 3-line config
|
|
37
37
|
│ └── public/ # Static assets
|
|
38
38
|
│
|
|
@@ -226,7 +226,8 @@ uniweb build [options]
|
|
|
226
226
|
| Option | Description |
|
|
227
227
|
| ------------------- | --------------------------------------------------------------------- |
|
|
228
228
|
| `--target <type>` | Build target: `foundation` or `site` (auto-detected if not specified) |
|
|
229
|
-
| `--prerender` |
|
|
229
|
+
| `--prerender` | Force pre-rendering (overrides site.yml) |
|
|
230
|
+
| `--no-prerender` | Skip pre-rendering (overrides site.yml) |
|
|
230
231
|
| `--foundation-dir` | Path to foundation directory (for prerendering) |
|
|
231
232
|
| `--platform <name>` | Deployment platform (e.g., `vercel`) for platform-specific output |
|
|
232
233
|
|
|
@@ -242,16 +243,26 @@ uniweb build --target foundation
|
|
|
242
243
|
# Explicitly build as site
|
|
243
244
|
uniweb build --target site
|
|
244
245
|
|
|
245
|
-
# Build site with pre-rendering (SSG)
|
|
246
|
+
# Build site with pre-rendering (SSG) - force on
|
|
246
247
|
uniweb build --prerender
|
|
247
248
|
|
|
249
|
+
# Skip pre-rendering even if enabled in site.yml
|
|
250
|
+
uniweb build --no-prerender
|
|
251
|
+
|
|
248
252
|
# Build for Vercel deployment
|
|
249
253
|
uniweb build --platform vercel
|
|
250
254
|
```
|
|
251
255
|
|
|
252
256
|
### Pre-rendering (SSG)
|
|
253
257
|
|
|
254
|
-
|
|
258
|
+
Pre-rendering generates static HTML for each page at build time. Enable it in `site.yml`:
|
|
259
|
+
|
|
260
|
+
```yaml
|
|
261
|
+
build:
|
|
262
|
+
prerender: true
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Or use the `--prerender` flag to force it on (or `--no-prerender` to skip it). This is useful for:
|
|
255
266
|
|
|
256
267
|
- **SEO**: Search engines see fully rendered content immediately
|
|
257
268
|
- **Performance**: First contentful paint is instant (no JavaScript required)
|
|
@@ -275,11 +286,11 @@ The pre-rendered HTML includes a `<script id="__SITE_CONTENT__">` tag with the f
|
|
|
275
286
|
**Usage:**
|
|
276
287
|
|
|
277
288
|
```bash
|
|
278
|
-
# From site directory
|
|
289
|
+
# From site directory (with build.prerender: true in site.yml)
|
|
279
290
|
cd site
|
|
280
|
-
pnpm build
|
|
291
|
+
pnpm build
|
|
281
292
|
|
|
282
|
-
# Or
|
|
293
|
+
# Or force pre-rendering via CLI flag
|
|
283
294
|
cd site && uniweb build --prerender
|
|
284
295
|
```
|
|
285
296
|
|
|
@@ -300,7 +311,7 @@ my-project/
|
|
|
300
311
|
│ ├── vite.config.js # 3-line config
|
|
301
312
|
│ ├── index.html
|
|
302
313
|
│ ├── site.yml # Site configuration (foundation, title, i18n)
|
|
303
|
-
│ ├── main.js #
|
|
314
|
+
│ ├── main.js # Entry point (~6 lines)
|
|
304
315
|
│ ├── pages/ # Content pages (file-based routing)
|
|
305
316
|
│ │ └── home/
|
|
306
317
|
│ │ ├── page.yml
|
|
@@ -311,10 +322,9 @@ my-project/
|
|
|
311
322
|
├── package.json
|
|
312
323
|
├── vite.config.js # 3-line config
|
|
313
324
|
└── src/
|
|
314
|
-
├── index.js # Component exports
|
|
315
|
-
├── entry-runtime.js # Runtime entry (imports styles + index)
|
|
316
325
|
├── styles.css # Tailwind CSS v4
|
|
317
326
|
├── meta.js # Foundation metadata
|
|
327
|
+
├── runtime.js # (optional) Custom Layout, props
|
|
318
328
|
└── components/
|
|
319
329
|
└── Section/
|
|
320
330
|
├── index.jsx
|
|
@@ -343,7 +353,7 @@ my-workspace/
|
|
|
343
353
|
│ │ ├── package.json
|
|
344
354
|
│ │ ├── vite.config.js # 3-line config
|
|
345
355
|
│ │ ├── site.yml
|
|
346
|
-
│ │ ├── main.js
|
|
356
|
+
│ │ ├── main.js # Entry point (~6 lines)
|
|
347
357
|
│ │ └── pages/
|
|
348
358
|
│ └── docs/ # Documentation site
|
|
349
359
|
│
|
|
@@ -472,8 +482,7 @@ The `defineFoundationConfig()` function handles all Vite configuration for found
|
|
|
472
482
|
import { defineFoundationConfig } from "@uniweb/build";
|
|
473
483
|
|
|
474
484
|
export default defineFoundationConfig({
|
|
475
|
-
// All options are optional
|
|
476
|
-
entry: "src/entry-runtime.js", // Entry point path
|
|
485
|
+
// All options are optional - entry is auto-generated
|
|
477
486
|
fileName: "foundation", // Output file name
|
|
478
487
|
externals: [], // Additional packages to externalize
|
|
479
488
|
includeDefaultExternals: true, // Include react, @uniweb/core, etc.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.31",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"js-yaml": "^4.1.0",
|
|
37
37
|
"prompts": "^2.4.2",
|
|
38
38
|
"tar": "^7.0.0",
|
|
39
|
-
"@uniweb/build": "0.1.
|
|
40
|
-
"@uniweb/core": "0.1.
|
|
39
|
+
"@uniweb/build": "0.1.15",
|
|
40
|
+
"@uniweb/core": "0.1.7",
|
|
41
41
|
"@uniweb/kit": "0.1.4",
|
|
42
|
-
"@uniweb/runtime": "0.2.
|
|
42
|
+
"@uniweb/runtime": "0.2.8"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/commands/build.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
discoverComponents,
|
|
23
23
|
processAllPreviews,
|
|
24
24
|
} from '@uniweb/build'
|
|
25
|
+
import { readSiteConfig } from '@uniweb/build/site'
|
|
25
26
|
|
|
26
27
|
// Colors for terminal output
|
|
27
28
|
const colors = {
|
|
@@ -186,14 +187,8 @@ async function buildFoundation(projectDir, options = {}) {
|
|
|
186
187
|
* - '*' → explicitly all available locales
|
|
187
188
|
* - ['es', 'fr'] → only those specific locales
|
|
188
189
|
*/
|
|
189
|
-
async function loadI18nConfig(projectDir) {
|
|
190
|
-
const
|
|
191
|
-
if (!existsSync(siteYmlPath)) return null
|
|
192
|
-
|
|
193
|
-
const { readFile } = await import('node:fs/promises')
|
|
194
|
-
const yaml = await import('js-yaml')
|
|
195
|
-
const content = await readFile(siteYmlPath, 'utf-8')
|
|
196
|
-
const config = yaml.load(content) || {}
|
|
190
|
+
async function loadI18nConfig(projectDir, siteConfig = null) {
|
|
191
|
+
const config = siteConfig || readSiteConfig(projectDir)
|
|
197
192
|
|
|
198
193
|
const localesDir = config.i18n?.localesDir || 'locales'
|
|
199
194
|
const localesPath = join(projectDir, localesDir)
|
|
@@ -288,7 +283,7 @@ async function generateLocalizedHtml(projectDir, i18nConfig) {
|
|
|
288
283
|
* Build a site
|
|
289
284
|
*/
|
|
290
285
|
async function buildSite(projectDir, options = {}) {
|
|
291
|
-
const { prerender = false, foundationDir } = options
|
|
286
|
+
const { prerender = false, foundationDir, siteConfig = null } = options
|
|
292
287
|
|
|
293
288
|
info('Building site...')
|
|
294
289
|
|
|
@@ -298,7 +293,7 @@ async function buildSite(projectDir, options = {}) {
|
|
|
298
293
|
success('Site build complete')
|
|
299
294
|
|
|
300
295
|
// Check for i18n configuration
|
|
301
|
-
const i18nConfig = await loadI18nConfig(projectDir)
|
|
296
|
+
const i18nConfig = await loadI18nConfig(projectDir, siteConfig)
|
|
302
297
|
|
|
303
298
|
if (i18nConfig && i18nConfig.locales.length > 0) {
|
|
304
299
|
log('')
|
|
@@ -378,8 +373,9 @@ export async function build(args = []) {
|
|
|
378
373
|
}
|
|
379
374
|
}
|
|
380
375
|
|
|
381
|
-
// Check for --prerender
|
|
382
|
-
const
|
|
376
|
+
// Check for --prerender / --no-prerender flags
|
|
377
|
+
const prerenderFlag = args.includes('--prerender')
|
|
378
|
+
const noPrerenderFlag = args.includes('--no-prerender')
|
|
383
379
|
|
|
384
380
|
// Check for --foundation-dir flag (for prerendering)
|
|
385
381
|
let foundationDir = null
|
|
@@ -401,9 +397,9 @@ export async function build(args = []) {
|
|
|
401
397
|
info(`Detected project type: ${targetType}`)
|
|
402
398
|
}
|
|
403
399
|
|
|
404
|
-
// Validate prerender
|
|
405
|
-
if (
|
|
406
|
-
error('--prerender can only be used with site builds')
|
|
400
|
+
// Validate prerender flags are only used with site target
|
|
401
|
+
if ((prerenderFlag || noPrerenderFlag) && targetType !== 'site') {
|
|
402
|
+
error('--prerender/--no-prerender can only be used with site builds')
|
|
407
403
|
process.exit(1)
|
|
408
404
|
}
|
|
409
405
|
|
|
@@ -412,7 +408,16 @@ export async function build(args = []) {
|
|
|
412
408
|
if (targetType === 'foundation') {
|
|
413
409
|
await buildFoundation(projectDir)
|
|
414
410
|
} else {
|
|
415
|
-
|
|
411
|
+
// For sites, read config to determine prerender default
|
|
412
|
+
const siteConfig = readSiteConfig(projectDir)
|
|
413
|
+
const configPrerender = siteConfig.build?.prerender === true
|
|
414
|
+
|
|
415
|
+
// CLI flags override config: --prerender forces on, --no-prerender forces off
|
|
416
|
+
let prerender = configPrerender
|
|
417
|
+
if (prerenderFlag) prerender = true
|
|
418
|
+
if (noPrerenderFlag) prerender = false
|
|
419
|
+
|
|
420
|
+
await buildSite(projectDir, { prerender, foundationDir, siteConfig })
|
|
416
421
|
}
|
|
417
422
|
} catch (err) {
|
|
418
423
|
error(err.message)
|
package/src/index.js
CHANGED
|
@@ -334,10 +334,13 @@ ${colors.bright}Create Options:${colors.reset}
|
|
|
334
334
|
|
|
335
335
|
${colors.bright}Build Options:${colors.reset}
|
|
336
336
|
--target <type> Build target (foundation, site) - auto-detected if not specified
|
|
337
|
-
--prerender
|
|
337
|
+
--prerender Force pre-rendering (overrides site.yml)
|
|
338
|
+
--no-prerender Skip pre-rendering (overrides site.yml)
|
|
338
339
|
--foundation-dir Path to foundation directory (for prerendering)
|
|
339
340
|
--platform <name> Deployment platform (e.g., vercel) for platform-specific output
|
|
340
341
|
|
|
342
|
+
Pre-rendering is enabled by default when build.prerender: true in site.yml
|
|
343
|
+
|
|
341
344
|
${colors.bright}Docs Options:${colors.reset}
|
|
342
345
|
--output <file> Output filename (default: COMPONENTS.md)
|
|
343
346
|
--from-source Read meta.js files directly instead of schema.json
|
|
@@ -364,7 +367,8 @@ ${colors.bright}Examples:${colors.reset}
|
|
|
364
367
|
npx uniweb create my-project --template github:myorg/template
|
|
365
368
|
npx uniweb build
|
|
366
369
|
npx uniweb build --target foundation
|
|
367
|
-
npx uniweb build
|
|
370
|
+
npx uniweb build # Auto-prerenders if site.yml has build.prerender: true
|
|
371
|
+
npx uniweb build --no-prerender # Skip prerendering even if enabled in config
|
|
368
372
|
cd foundation && npx uniweb docs # Generate COMPONENTS.md
|
|
369
373
|
`)
|
|
370
374
|
}
|
|
@@ -40,24 +40,26 @@ cd site && pnpm build
|
|
|
40
40
|
|
|
41
41
|
**Foundation:**
|
|
42
42
|
- `foundation/vite.config.js` - 3-line config using `defineFoundationConfig()` from `@uniweb/build`
|
|
43
|
-
- `foundation/src/entry-runtime.js` - Runtime entry point (imports styles + components)
|
|
44
|
-
- `foundation/src/index.js` - Component exports
|
|
45
43
|
- `foundation/src/styles.css` - Tailwind CSS v4 theme
|
|
46
|
-
- `foundation/src/components/*/meta.js` - Component metadata
|
|
44
|
+
- `foundation/src/components/*/meta.js` - Component metadata (makes component exposed)
|
|
45
|
+
- `foundation/src/runtime.js` - (optional) Custom Layout and foundation props
|
|
46
|
+
- `foundation/src/_entry.generated.js` - Auto-generated at build/dev time
|
|
47
47
|
|
|
48
48
|
## Architecture
|
|
49
49
|
|
|
50
50
|
### Foundation Package (`/foundation`)
|
|
51
51
|
|
|
52
|
-
The **foundation** is a React component library.
|
|
52
|
+
The **foundation** is a React component library. Components with a `meta.js` file are **exposed** (available to content creators via `type:` in frontmatter). Exposed components:
|
|
53
53
|
|
|
54
|
-
1.
|
|
55
|
-
2.
|
|
56
|
-
3.
|
|
54
|
+
1. Receive structured content parsed from markdown
|
|
55
|
+
2. Have configurable parameters (theme, layout, etc.)
|
|
56
|
+
3. Render content according to their design
|
|
57
|
+
|
|
58
|
+
Internal components (no `meta.js`) are regular React components used within exposed components.
|
|
57
59
|
|
|
58
60
|
**Key directories:**
|
|
59
61
|
- `src/components/*/` - Component implementations
|
|
60
|
-
- `src/components/*/meta.js` - Component metadata
|
|
62
|
+
- `src/components/*/meta.js` - Component metadata (makes component exposed)
|
|
61
63
|
- `src/styles.css` - Global Tailwind styles
|
|
62
64
|
|
|
63
65
|
### Site Package (`/site`)
|
|
@@ -79,9 +79,9 @@ pnpm build:all
|
|
|
79
79
|
|
|
80
80
|
**Foundations:**
|
|
81
81
|
- `foundations/*/vite.config.js` - 3-line config using `defineFoundationConfig()` from `@uniweb/build`
|
|
82
|
-
- `foundations/*/src/entry-runtime.js` - Runtime entry point
|
|
83
82
|
- `foundations/*/src/styles.css` - Tailwind CSS v4 theme
|
|
84
|
-
- `foundations/*/src/components/*/meta.js` - Component metadata
|
|
83
|
+
- `foundations/*/src/components/*/meta.js` - Component metadata (makes component exposed)
|
|
84
|
+
- `foundations/*/src/runtime.js` - (optional) Custom Layout and foundation props
|
|
85
85
|
|
|
86
86
|
## Architecture
|
|
87
87
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"name": "default",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./src/
|
|
5
|
+
"main": "./src/_entry.generated.js",
|
|
6
6
|
"exports": {
|
|
7
|
-
".": "./src/
|
|
7
|
+
".": "./src/_entry.generated.js",
|
|
8
8
|
"./styles": "./src/styles.css",
|
|
9
9
|
"./dist": "./dist/foundation.js",
|
|
10
10
|
"./dist/styles": "./dist/assets/style.css"
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"name": "foundation",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./src/
|
|
5
|
+
"main": "./src/_entry.generated.js",
|
|
6
6
|
"exports": {
|
|
7
|
-
".": "./src/
|
|
7
|
+
".": "./src/_entry.generated.js",
|
|
8
8
|
"./styles": "./src/styles.css",
|
|
9
9
|
"./dist": "./dist/foundation.js",
|
|
10
10
|
"./dist/styles": "./dist/assets/style.css"
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"name": "foundation",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./src/
|
|
5
|
+
"main": "./src/_entry.generated.js",
|
|
6
6
|
"exports": {
|
|
7
|
-
".": "./src/
|
|
7
|
+
".": "./src/_entry.generated.js",
|
|
8
8
|
"./styles": "./src/styles.css",
|
|
9
9
|
"./dist": "./dist/foundation.js",
|
|
10
10
|
"./dist/styles": "./dist/assets/style.css"
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Foundation Entry Point
|
|
3
|
-
*
|
|
4
|
-
* Export all components from this file.
|
|
5
|
-
* Components are discovered from src/components/{Name}/meta.js during build.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import Section from './components/Section/index.jsx'
|
|
9
|
-
|
|
10
|
-
const components = {
|
|
11
|
-
Section,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function getComponent(name) {
|
|
15
|
-
return components[name]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function listComponents() {
|
|
19
|
-
return Object.keys(components)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function getSchema(name) {
|
|
23
|
-
return components[name]?.schema
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getAllSchemas() {
|
|
27
|
-
const schemas = {}
|
|
28
|
-
for (const [name, component] of Object.entries(components)) {
|
|
29
|
-
if (component.schema) schemas[name] = component.schema
|
|
30
|
-
}
|
|
31
|
-
return schemas
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export { Section }
|
|
35
|
-
export default { getComponent, listComponents, getSchema, getAllSchemas, components }
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Foundation Entry Point
|
|
3
|
-
*
|
|
4
|
-
* Export all your template's components here.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import Hero from './components/Hero/index.jsx'
|
|
8
|
-
import Features from './components/Features/index.jsx'
|
|
9
|
-
|
|
10
|
-
const components = {
|
|
11
|
-
Hero,
|
|
12
|
-
Features,
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function getComponent(name) {
|
|
16
|
-
return components[name]
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function listComponents() {
|
|
20
|
-
return Object.keys(components)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function getSchema(name) {
|
|
24
|
-
return components[name]?.schema
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function getAllSchemas() {
|
|
28
|
-
const schemas = {}
|
|
29
|
-
for (const [name, component] of Object.entries(components)) {
|
|
30
|
-
if (component.schema) schemas[name] = component.schema
|
|
31
|
-
}
|
|
32
|
-
return schemas
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { Hero, Features }
|
|
36
|
-
export default { getComponent, listComponents, getSchema, getAllSchemas, components }
|