@uniweb/build 0.1.28 → 0.1.29
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/package.json +3 -3
- package/src/site/config.js +46 -1
- package/src/site/plugin.js +31 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"sharp": "^0.33.2"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"@uniweb/
|
|
54
|
-
"@uniweb/
|
|
53
|
+
"@uniweb/runtime": "0.2.16",
|
|
54
|
+
"@uniweb/content-reader": "1.0.4"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
package/src/site/config.js
CHANGED
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { existsSync, readFileSync } from 'node:fs'
|
|
24
|
-
import { resolve, dirname } from 'node:path'
|
|
24
|
+
import { resolve, dirname, join } from 'node:path'
|
|
25
25
|
import yaml from 'js-yaml'
|
|
26
|
+
import { generateEntryPoint } from '../generate-entry.js'
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Detect foundation type from the foundation config value
|
|
@@ -177,8 +178,52 @@ export async function defineSiteConfig(options = {}) {
|
|
|
177
178
|
foundationDevPlugin = modules[3].foundationDevPlugin
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
// Plugin to ensure foundation entry file exists (for bundled mode with local foundation)
|
|
182
|
+
const ensureFoundationEntryPlugin = !isRuntimeMode && foundationInfo.type === 'local' ? {
|
|
183
|
+
name: 'uniweb:ensure-foundation-entry',
|
|
184
|
+
async config() {
|
|
185
|
+
const srcDir = join(foundationInfo.path, 'src')
|
|
186
|
+
const entryPath = join(srcDir, '_entry.generated.js')
|
|
187
|
+
|
|
188
|
+
// Always regenerate on dev start to ensure it's current
|
|
189
|
+
// This handles new components being added
|
|
190
|
+
if (existsSync(srcDir)) {
|
|
191
|
+
console.log('[site] Ensuring foundation entry is up to date...')
|
|
192
|
+
try {
|
|
193
|
+
await generateEntryPoint(srcDir, entryPath)
|
|
194
|
+
} catch (err) {
|
|
195
|
+
console.warn('[site] Failed to generate foundation entry:', err.message)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
configureServer(server) {
|
|
201
|
+
// Watch foundation src for meta.js changes to regenerate entry
|
|
202
|
+
const srcDir = join(foundationInfo.path, 'src')
|
|
203
|
+
const entryPath = join(srcDir, '_entry.generated.js')
|
|
204
|
+
|
|
205
|
+
server.watcher.add(join(srcDir, '**', 'meta.js'))
|
|
206
|
+
|
|
207
|
+
server.watcher.on('all', async (event, path) => {
|
|
208
|
+
// Regenerate entry when meta.js files change (new/deleted components)
|
|
209
|
+
if (path.includes(srcDir) && path.endsWith('meta.js')) {
|
|
210
|
+
console.log(`[site] Foundation meta.js changed, regenerating entry...`)
|
|
211
|
+
try {
|
|
212
|
+
await generateEntryPoint(srcDir, entryPath)
|
|
213
|
+
server.ws.send({ type: 'full-reload' })
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.warn('[site] Failed to regenerate foundation entry:', err.message)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
} : null
|
|
221
|
+
|
|
180
222
|
// Build the plugins array
|
|
181
223
|
const plugins = [
|
|
224
|
+
// Ensure foundation entry exists first (bundled mode only)
|
|
225
|
+
ensureFoundationEntryPlugin,
|
|
226
|
+
|
|
182
227
|
// Standard plugins
|
|
183
228
|
tailwind && tailwindcss(),
|
|
184
229
|
react(),
|
package/src/site/plugin.js
CHANGED
|
@@ -274,6 +274,7 @@ export function siteContentPlugin(options = {}) {
|
|
|
274
274
|
let server = null
|
|
275
275
|
let localeTranslations = {} // Cache: { locale: translations }
|
|
276
276
|
let localesDir = 'locales' // Default, updated from site config
|
|
277
|
+
let collectionsConfig = null // Cached for watcher setup
|
|
277
278
|
|
|
278
279
|
/**
|
|
279
280
|
* Load translations for a specific locale
|
|
@@ -332,10 +333,28 @@ export function siteContentPlugin(options = {}) {
|
|
|
332
333
|
return {
|
|
333
334
|
name: 'uniweb:site-content',
|
|
334
335
|
|
|
335
|
-
configResolved(config) {
|
|
336
|
+
async configResolved(config) {
|
|
336
337
|
resolvedSitePath = resolve(config.root, sitePath)
|
|
337
338
|
resolvedOutDir = resolve(config.root, config.build.outDir)
|
|
338
339
|
isProduction = config.command === 'build'
|
|
340
|
+
|
|
341
|
+
// In dev mode, process collections early so JSON files exist before server starts
|
|
342
|
+
// This runs before configureServer, ensuring data is available immediately
|
|
343
|
+
if (!isProduction) {
|
|
344
|
+
try {
|
|
345
|
+
// Do an early content collection to get the collections config
|
|
346
|
+
const earlyContent = await collectSiteContent(resolvedSitePath)
|
|
347
|
+
collectionsConfig = earlyContent.config?.collections
|
|
348
|
+
|
|
349
|
+
if (collectionsConfig) {
|
|
350
|
+
console.log('[site-content] Processing content collections...')
|
|
351
|
+
const collections = await processCollections(resolvedSitePath, collectionsConfig)
|
|
352
|
+
await writeCollectionFiles(resolvedSitePath, collections)
|
|
353
|
+
}
|
|
354
|
+
} catch (err) {
|
|
355
|
+
console.warn('[site-content] Early collection processing failed:', err.message)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
339
358
|
},
|
|
340
359
|
|
|
341
360
|
async buildStart() {
|
|
@@ -345,8 +364,9 @@ export function siteContentPlugin(options = {}) {
|
|
|
345
364
|
console.log(`[site-content] Collected ${siteContent.pages?.length || 0} pages`)
|
|
346
365
|
|
|
347
366
|
// Process content collections if defined in site.yml
|
|
348
|
-
//
|
|
349
|
-
|
|
367
|
+
// In dev mode, this was already done in configResolved (before server starts)
|
|
368
|
+
// In production, do it here
|
|
369
|
+
if (isProduction && siteContent.config?.collections) {
|
|
350
370
|
console.log('[site-content] Processing content collections...')
|
|
351
371
|
const collections = await processCollections(resolvedSitePath, siteContent.config.collections)
|
|
352
372
|
await writeCollectionFiles(resolvedSitePath, collections)
|
|
@@ -399,9 +419,11 @@ export function siteContentPlugin(options = {}) {
|
|
|
399
419
|
collectionRebuildTimeout = setTimeout(async () => {
|
|
400
420
|
console.log('[site-content] Collection content changed, regenerating JSON...')
|
|
401
421
|
try {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
422
|
+
// Use collectionsConfig (cached from configResolved) or siteContent
|
|
423
|
+
const collections = collectionsConfig || siteContent?.config?.collections
|
|
424
|
+
if (collections) {
|
|
425
|
+
const processed = await processCollections(resolvedSitePath, collections)
|
|
426
|
+
await writeCollectionFiles(resolvedSitePath, processed)
|
|
405
427
|
}
|
|
406
428
|
// Send full reload to client
|
|
407
429
|
server.ws.send({ type: 'full-reload' })
|
|
@@ -437,9 +459,10 @@ export function siteContentPlugin(options = {}) {
|
|
|
437
459
|
}
|
|
438
460
|
|
|
439
461
|
// Watch content/ folder for collection changes
|
|
440
|
-
|
|
462
|
+
// Use collectionsConfig cached from configResolved (siteContent may be null here)
|
|
463
|
+
if (collectionsConfig) {
|
|
441
464
|
const contentPaths = new Set()
|
|
442
|
-
for (const config of Object.values(
|
|
465
|
+
for (const config of Object.values(collectionsConfig)) {
|
|
443
466
|
const collectionPath = typeof config === 'string' ? config : config.path
|
|
444
467
|
if (collectionPath) {
|
|
445
468
|
contentPaths.add(resolve(resolvedSitePath, collectionPath))
|