@uniweb/build 0.80.3 → 0.80.4
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 +11 -11
- package/src/foundation/config.js +3 -0
- package/src/jsx-extension.js +68 -0
- package/src/schema.js +18 -5
- package/src/site/config.js +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/build",
|
|
3
|
-
"version": "0.80.
|
|
3
|
+
"version": "0.80.4",
|
|
4
4
|
"description": "Build tooling for the Uniweb Component Web Platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -53,19 +53,19 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@citestyle/bibtex": "^1.1.0",
|
|
56
|
-
"esbuild": "^0.21.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.27.0",
|
|
56
|
+
"esbuild": "^0.21.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.27.0 || ^0.28.0",
|
|
57
57
|
"js-yaml": "^4.1.0",
|
|
58
58
|
"sharp": "^0.35.3",
|
|
59
59
|
"yaml": "^2.5.0",
|
|
60
|
-
"@uniweb/
|
|
61
|
-
"@uniweb/
|
|
62
|
-
"@uniweb/content-writer": "
|
|
63
|
-
"@uniweb/schemas": "
|
|
64
|
-
"@uniweb/
|
|
65
|
-
"@uniweb/
|
|
60
|
+
"@uniweb/semantic-parser": "~1.5.1",
|
|
61
|
+
"@uniweb/theming": "~0.2.0",
|
|
62
|
+
"@uniweb/content-writer": "~0.3.4",
|
|
63
|
+
"@uniweb/schemas": "~0.13.0",
|
|
64
|
+
"@uniweb/content-reader": "~1.2.8",
|
|
65
|
+
"@uniweb/projections": "~0.7.16"
|
|
66
66
|
},
|
|
67
67
|
"optionalDependencies": {
|
|
68
|
-
"@uniweb/runtime": "
|
|
68
|
+
"@uniweb/runtime": "~0.29.7"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"@tailwindcss/vite": "^4.0.0",
|
|
75
75
|
"@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
|
|
76
76
|
"vite-plugin-svgr": "^4.0.0",
|
|
77
|
-
"@uniweb/
|
|
78
|
-
"@uniweb/
|
|
77
|
+
"@uniweb/runtime": "~0.29.7",
|
|
78
|
+
"@uniweb/core": "~0.38.2"
|
|
79
79
|
},
|
|
80
80
|
"peerDependenciesMeta": {
|
|
81
81
|
"vite": {
|
package/src/foundation/config.js
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
import { resolve } from 'node:path'
|
|
27
27
|
import { foundationPlugin } from '../vite-foundation-plugin.js'
|
|
28
|
+
import { jsxExtensionGuard } from '../jsx-extension.js'
|
|
28
29
|
import { resolveFoundationSrcDir } from '../utils/foundation-source-root.js'
|
|
29
30
|
// The ONE definition. This list used to be re-typed here, and again in
|
|
30
31
|
// vite-foundation-plugin.js — three hand-synced copies of "what a foundation
|
|
@@ -107,6 +108,8 @@ export async function defineFoundationConfig(options = {}) {
|
|
|
107
108
|
// foundationPlugin handles entry generation and schema building
|
|
108
109
|
const plugins = [
|
|
109
110
|
foundationPlugin({ srcDir, sections: sectionPaths }),
|
|
111
|
+
// JSX compiles only in .jsx files: a .js file holding it fails with that said.
|
|
112
|
+
jsxExtensionGuard(),
|
|
110
113
|
tailwind && tailwindcss(),
|
|
111
114
|
react(),
|
|
112
115
|
svgr(),
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSX compiles only in `.jsx` and `.tsx` files — in a foundation's Vite build, in a
|
|
3
|
+
* site build that bundles its foundation, and in the step that reads `main.js`
|
|
4
|
+
* (`schema.js`, `importFoundationConfig`).
|
|
5
|
+
*
|
|
6
|
+
* ⭐ THE RULE, SAID WHERE IT FAILS. A `.js` file holding JSX fails each of those with a
|
|
7
|
+
* parser's message that never says why — Vite's "Expression expected", esbuild's "The JSX
|
|
8
|
+
* syntax extension is not currently enabled" — and section discovery accepts `.js`
|
|
9
|
+
* components, which build only without JSX. Ruled 2026-10-11: JSX stays in `.jsx` files,
|
|
10
|
+
* and the failure names the file and the fix.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { basename, relative } from 'node:path'
|
|
14
|
+
|
|
15
|
+
const JS_FILE = /\.m?js$/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* What to tell an author whose `.js` file holds JSX — the rule and the fix, without the
|
|
19
|
+
* location, which each caller states its own way (Vite prefixes `file (line:col):`).
|
|
20
|
+
*
|
|
21
|
+
* @param {string} file - the file holding JSX
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
export function jsxInJsMessage(file) {
|
|
25
|
+
const name = basename(file)
|
|
26
|
+
// `main.js` is the one name a foundation's declarations are read from, so it cannot
|
|
27
|
+
// become `main.jsx`: its components move out instead.
|
|
28
|
+
if (name === 'main.js') {
|
|
29
|
+
return 'JSX compiles only in .jsx and .tsx files, and main.js is plain JavaScript: move the component into a .jsx file and import it.'
|
|
30
|
+
}
|
|
31
|
+
return `JSX compiles only in .jsx and .tsx files — rename ${name} to ${name.replace(JS_FILE, '.jsx')}.`
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A Vite plugin that turns a parse failure on JSX in a `.js` file into
|
|
36
|
+
* {@link jsxInJsMessage}. Silent otherwise: a file that parses, or fails for any other
|
|
37
|
+
* reason, is left to Vite. A file under `node_modules` is skipped — the advice is for files
|
|
38
|
+
* the author can rename.
|
|
39
|
+
*
|
|
40
|
+
* It parses only a project `.js` file that contains a `<`, and the failure it reports is the
|
|
41
|
+
* one the build would hit next: the parser stopped at that `<`.
|
|
42
|
+
*
|
|
43
|
+
* @returns {import('vite').Plugin}
|
|
44
|
+
*/
|
|
45
|
+
export function jsxExtensionGuard() {
|
|
46
|
+
let root = process.cwd()
|
|
47
|
+
return {
|
|
48
|
+
name: 'uniweb-jsx-extension',
|
|
49
|
+
enforce: 'pre',
|
|
50
|
+
configResolved(config) {
|
|
51
|
+
root = config.root
|
|
52
|
+
},
|
|
53
|
+
transform(code, id) {
|
|
54
|
+
const file = id.split('?')[0]
|
|
55
|
+
if (!JS_FILE.test(file) || file.includes('/node_modules/') || !code.includes('<')) return null
|
|
56
|
+
if (typeof this.parse !== 'function') return null
|
|
57
|
+
try {
|
|
58
|
+
this.parse(code)
|
|
59
|
+
} catch (error) {
|
|
60
|
+
const pos = error?.pos
|
|
61
|
+
if (typeof pos === 'number' && code[pos] === '<') {
|
|
62
|
+
this.error(jsxInJsMessage(relative(root, file)), pos)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/schema.js
CHANGED
|
@@ -14,8 +14,9 @@ import { readdir, readFile, rm } from 'node:fs/promises'
|
|
|
14
14
|
import { existsSync } from 'node:fs'
|
|
15
15
|
import { createHash } from 'node:crypto'
|
|
16
16
|
import { isFontVar } from '@uniweb/theming'
|
|
17
|
-
import { join, dirname, extname, basename } from 'node:path'
|
|
17
|
+
import { join, dirname, extname, basename, relative, resolve } from 'node:path'
|
|
18
18
|
import { pathToFileURL } from 'node:url'
|
|
19
|
+
import { jsxInJsMessage } from './jsx-extension.js'
|
|
19
20
|
import { describeChildren, describeVisuals, lowerChildren } from '@uniweb/schemas/component'
|
|
20
21
|
import { describeContent, lowerData } from '@uniweb/schemas/content'
|
|
21
22
|
import { normalizeData, schemaDeclarationOf } from '@uniweb/schemas/foundation'
|
|
@@ -433,6 +434,16 @@ async function importFoundationConfig(filePath) {
|
|
|
433
434
|
logLevel: 'silent',
|
|
434
435
|
})
|
|
435
436
|
return await import(`${pathToFileURL(outfile).href}?content=${content}`)
|
|
437
|
+
} catch (bundleError) {
|
|
438
|
+
// JSX in a `.js` file — `main.js` itself or a module it imports — compiles nowhere
|
|
439
|
+
// (jsx-extension.js): say so, rather than esbuild's "The JSX syntax extension is not
|
|
440
|
+
// currently enabled".
|
|
441
|
+
const jsx = bundleError?.errors?.find(
|
|
442
|
+
(e) => /JSX syntax extension/.test(e.text) && /\.m?js$/.test(e.location?.file ?? ''),
|
|
443
|
+
)
|
|
444
|
+
if (!jsx) throw bundleError
|
|
445
|
+
const file = relative(dirname(filePath), resolve(jsx.location.file))
|
|
446
|
+
throw new Error(`${file} (line ${jsx.location.line}): ${jsxInJsMessage(file)}`, { cause: bundleError })
|
|
436
447
|
} finally {
|
|
437
448
|
await rm(outfile, { force: true }).catch(() => {})
|
|
438
449
|
}
|
|
@@ -482,13 +493,15 @@ export async function loadFoundationConfig(srcDir) {
|
|
|
482
493
|
)
|
|
483
494
|
}
|
|
484
495
|
// ⛔ The same for `main.jsx`, which the entry used to import while this read nothing — the
|
|
485
|
-
// editor saw none of its declarations, the runtime all of them (until 2026-10-01).
|
|
486
|
-
// may hold JSX
|
|
496
|
+
// editor saw none of its declarations, the runtime all of them (until 2026-10-01).
|
|
497
|
+
// ⛔ This said "rename it to main.js, which may hold JSX" until 2026-10-11, and main.js never
|
|
498
|
+
// could: JSX compiles only in .jsx files, here and in Vite (jsx-extension.js). A main.jsx's
|
|
499
|
+
// components move into a .jsx file the new main.js imports.
|
|
487
500
|
const jsx = join(srcDir, 'main.jsx')
|
|
488
501
|
if (existsSync(jsx)) {
|
|
489
502
|
throw new Error(
|
|
490
|
-
`${jsx} is not read — rename it to main.js,
|
|
491
|
-
` A foundation's declarations live in main.js; left as main.jsx, the build would continue with none of them.`,
|
|
503
|
+
`${jsx} is not read — rename it to main.js, and move any JSX it holds into a .jsx file it imports.\n` +
|
|
504
|
+
` A foundation's declarations live in main.js, which is plain JavaScript; left as main.jsx, the build would continue with none of them.`,
|
|
492
505
|
)
|
|
493
506
|
}
|
|
494
507
|
return {}
|
package/src/site/config.js
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
getStructuralWatchPaths
|
|
31
31
|
} from '../generate-entry.js'
|
|
32
32
|
import { importMapPlugin } from '../import-map-plugin.js'
|
|
33
|
+
import { jsxExtensionGuard } from '../jsx-extension.js'
|
|
33
34
|
import { resolveModuleUrl, resolveExtensionUrls } from './extension-urls.js'
|
|
34
35
|
import { resolveFoundationSrcPath } from '../utils/foundation-source-root.js'
|
|
35
36
|
import { checkFoundationResolution } from '../utils/foundation-resolution-check.js'
|
|
@@ -317,6 +318,8 @@ export async function defineSiteConfig(options = {}) {
|
|
|
317
318
|
ensureFoundationEntryPlugin,
|
|
318
319
|
|
|
319
320
|
// Standard plugins
|
|
321
|
+
// JSX compiles only in .jsx files — a bundled foundation's too.
|
|
322
|
+
jsxExtensionGuard(),
|
|
320
323
|
tailwind && tailwindcss(),
|
|
321
324
|
react(),
|
|
322
325
|
svgr(),
|