@maiyunnet/kebab 9.18.1 → 9.19.0
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/doc/kebab-rag.md +288 -150
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/undici/request.d.ts +10 -0
- package/lib/undici/request.js +16 -0
- package/lib/undici.d.ts +16 -0
- package/lib/undici.js +33 -1
- package/package.json +1 -1
- package/sys/child.js +1 -1
- package/sys/ctr.d.ts +9 -12
- package/sys/ctr.js +51 -95
- package/sys/route.d.ts +2 -1
- package/sys/route.js +48 -9
- package/www/example/ctr/test.js +6 -6
- package/www/example/stc/view/hello.page.d.ts +2 -1
- package/www/example/stc/view/hello.page.js +2 -1
- package/www/example/stc/view/hello.page.tsx +2 -1
- package/www/example/stc/view/react-router.page.d.ts +3 -3
- package/www/example/stc/view/react-router.page.js +3 -3
- package/www/example/stc/view/react-router.page.tsx +3 -4
- package/www/example/stc/view/react.page.d.ts +5 -9
- package/www/example/stc/view/react.page.js +7 -11
- package/www/example/stc/view/react.page.tsx +8 -14
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* 1. 这个 .page.tsx 文件(组件 + IProps)
|
|
6
6
|
* 2. 一个 <link> 标签引入 CSS(如果不需要样式可省略)
|
|
7
7
|
* 3. 在 Ctr 方法里调用 _loadReactPage('view/hello', props)
|
|
8
|
-
*
|
|
8
|
+
* 4. 执行 node ./source/main build -d source/www/example/stc 生成客户端水合 bundle
|
|
9
|
+
* 其他一切由框架自动处理:SSR 渲染、props 注入、客户端水合。
|
|
9
10
|
*/
|
|
10
11
|
import { useState, type ReactElement } from 'react';
|
|
11
12
|
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* 3. 嵌套路由通过 Outlet 渲染子路由内容
|
|
16
16
|
*
|
|
17
17
|
* 【编译方式】
|
|
18
|
-
* tsc watch 会自动编译本文件为同路径的 .js
|
|
19
|
-
*
|
|
18
|
+
* tsc watch 会自动编译本文件为同路径的 .js,供服务端 SSR 使用。
|
|
19
|
+
* 客户端水合必须执行:node ./source/main build -d source/www/example/stc
|
|
20
20
|
*
|
|
21
21
|
* 【Tailwind CSS 构建】
|
|
22
22
|
* 需提前执行 node ./source/main build -d source/www/example/stc 生成 CSS 产物。
|
|
23
23
|
* 框架通过 _staticPath 和 _staticVer 自动拼接带版本号 URL;
|
|
24
|
-
*
|
|
24
|
+
* props JSON、水合脚本均由框架自动注入 HTML,组件无需手动处理。
|
|
25
25
|
*/
|
|
26
26
|
interface IUser {
|
|
27
27
|
'id': string;
|
|
@@ -16,13 +16,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
16
16
|
* 3. 嵌套路由通过 Outlet 渲染子路由内容
|
|
17
17
|
*
|
|
18
18
|
* 【编译方式】
|
|
19
|
-
* tsc watch 会自动编译本文件为同路径的 .js
|
|
20
|
-
*
|
|
19
|
+
* tsc watch 会自动编译本文件为同路径的 .js,供服务端 SSR 使用。
|
|
20
|
+
* 客户端水合必须执行:node ./source/main build -d source/www/example/stc
|
|
21
21
|
*
|
|
22
22
|
* 【Tailwind CSS 构建】
|
|
23
23
|
* 需提前执行 node ./source/main build -d source/www/example/stc 生成 CSS 产物。
|
|
24
24
|
* 框架通过 _staticPath 和 _staticVer 自动拼接带版本号 URL;
|
|
25
|
-
*
|
|
25
|
+
* props JSON、水合脚本均由框架自动注入 HTML,组件无需手动处理。
|
|
26
26
|
*/
|
|
27
27
|
import { useState, useEffect } from 'react';
|
|
28
28
|
import { Routes, Route, Link, NavLink, useParams, useNavigate, useLocation, Outlet } from 'react-router-dom';
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* 3. 嵌套路由通过 Outlet 渲染子路由内容
|
|
16
16
|
*
|
|
17
17
|
* 【编译方式】
|
|
18
|
-
* tsc watch 会自动编译本文件为同路径的 .js
|
|
19
|
-
*
|
|
18
|
+
* tsc watch 会自动编译本文件为同路径的 .js,供服务端 SSR 使用。
|
|
19
|
+
* 客户端水合必须执行:node ./source/main build -d source/www/example/stc
|
|
20
20
|
*
|
|
21
21
|
* 【Tailwind CSS 构建】
|
|
22
22
|
* 需提前执行 node ./source/main build -d source/www/example/stc 生成 CSS 产物。
|
|
23
23
|
* 框架通过 _staticPath 和 _staticVer 自动拼接带版本号 URL;
|
|
24
|
-
*
|
|
24
|
+
* props JSON、水合脚本均由框架自动注入 HTML,组件无需手动处理。
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import { useState, useEffect } from 'react';
|
|
@@ -336,7 +336,6 @@ export default function ReactRouterPage({
|
|
|
336
336
|
<meta charSet="UTF-8" />
|
|
337
337
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
338
338
|
<title suppressHydrationWarning>{title}</title>
|
|
339
|
-
{/* --- import map 由框架自动注入在此标签前,无需手动添加 --- */}
|
|
340
339
|
{/* --- dev: 需先执行 node ./source/main build -d source/www/example/stc 生成 CSS --- */}
|
|
341
340
|
<link rel="stylesheet" href={`${_urlStc}view/react-router.page.css?v=${_staticVer}`} />
|
|
342
341
|
</head>
|
|
@@ -9,26 +9,22 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 【使用方式】
|
|
11
11
|
* 在 Ctr 方法中调用 _loadReactPage('view/react', { ...props }),
|
|
12
|
-
* 框架自动将
|
|
12
|
+
* 框架自动将 props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
|
|
13
13
|
*
|
|
14
14
|
* 【多页面 / 共用组件】
|
|
15
15
|
* 将公共 UI(如 Label/Input/Checkbox)放在 stc/lib/ui/ 目录,各页面 import 进来。
|
|
16
16
|
* 这和 shadcn/ui 推荐的 components/ui/ 目录结构完全一致。
|
|
17
|
-
* tsc watch 会自动将所有 .tsx 编译为同路径的 .js
|
|
17
|
+
* tsc watch 会自动将所有 .tsx 编译为同路径的 .js,供服务端 SSR 使用。
|
|
18
18
|
*
|
|
19
19
|
* 【编译方式】
|
|
20
20
|
* 本文件 (.tsx) 已集成到 source/tsconfig.json 的 include 中,
|
|
21
|
-
* 开启 `tsc: watch - source/tsconfig.json`
|
|
21
|
+
* 开启 `tsc: watch - source/tsconfig.json` 即可自动编译服务端文件。
|
|
22
22
|
* 编译输出:stc/view/react.page.js(由 tsc 覆盖写入,勿手动编辑 .js 文件)
|
|
23
|
+
* 客户端水合需执行:node ./source/main build -d source/www/example/stc
|
|
23
24
|
*
|
|
24
25
|
* 【运行时机】
|
|
25
26
|
* - 服务端(Node.js):_loadReactPage() 调用 renderToString(),产出完整 HTML 字符串。
|
|
26
|
-
* -
|
|
27
|
-
* - 两端使用同一份 JS 文件:服务端从磁盘读,浏览器从静态 URL 下载。
|
|
28
|
-
*
|
|
29
|
-
* 【第三方包 import map 自动解析】
|
|
30
|
-
* 开发模式下,框架会自动扫描入口 JS 及其相对引用中的所有 bare specifier,
|
|
31
|
-
* 并通过 esm.sh CDN 自动生成 import map 条目,无需手动配置。
|
|
27
|
+
* - 客户端(浏览器):加载 kebab build 生成的 bundle,由 hydrateRoot 接管 document。
|
|
32
28
|
*
|
|
33
29
|
* 【限制】
|
|
34
30
|
* - 不能包含 Node.js 专属代码(fs/path/lDb 等),数据必须通过 props 传入。
|
|
@@ -10,26 +10,22 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
*
|
|
11
11
|
* 【使用方式】
|
|
12
12
|
* 在 Ctr 方法中调用 _loadReactPage('view/react', { ...props }),
|
|
13
|
-
* 框架自动将
|
|
13
|
+
* 框架自动将 props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
|
|
14
14
|
*
|
|
15
15
|
* 【多页面 / 共用组件】
|
|
16
16
|
* 将公共 UI(如 Label/Input/Checkbox)放在 stc/lib/ui/ 目录,各页面 import 进来。
|
|
17
17
|
* 这和 shadcn/ui 推荐的 components/ui/ 目录结构完全一致。
|
|
18
|
-
* tsc watch 会自动将所有 .tsx 编译为同路径的 .js
|
|
18
|
+
* tsc watch 会自动将所有 .tsx 编译为同路径的 .js,供服务端 SSR 使用。
|
|
19
19
|
*
|
|
20
20
|
* 【编译方式】
|
|
21
21
|
* 本文件 (.tsx) 已集成到 source/tsconfig.json 的 include 中,
|
|
22
|
-
* 开启 `tsc: watch - source/tsconfig.json`
|
|
22
|
+
* 开启 `tsc: watch - source/tsconfig.json` 即可自动编译服务端文件。
|
|
23
23
|
* 编译输出:stc/view/react.page.js(由 tsc 覆盖写入,勿手动编辑 .js 文件)
|
|
24
|
+
* 客户端水合需执行:node ./source/main build -d source/www/example/stc
|
|
24
25
|
*
|
|
25
26
|
* 【运行时机】
|
|
26
27
|
* - 服务端(Node.js):_loadReactPage() 调用 renderToString(),产出完整 HTML 字符串。
|
|
27
|
-
* -
|
|
28
|
-
* - 两端使用同一份 JS 文件:服务端从磁盘读,浏览器从静态 URL 下载。
|
|
29
|
-
*
|
|
30
|
-
* 【第三方包 import map 自动解析】
|
|
31
|
-
* 开发模式下,框架会自动扫描入口 JS 及其相对引用中的所有 bare specifier,
|
|
32
|
-
* 并通过 esm.sh CDN 自动生成 import map 条目,无需手动配置。
|
|
28
|
+
* - 客户端(浏览器):加载 kebab build 生成的 bundle,由 hydrateRoot 接管 document。
|
|
33
29
|
*
|
|
34
30
|
* 【限制】
|
|
35
31
|
* - 不能包含 Node.js 专属代码(fs/path/lDb 等),数据必须通过 props 传入。
|
|
@@ -102,7 +98,7 @@ function ShadcnDemo() {
|
|
|
102
98
|
e.preventDefault();
|
|
103
99
|
setSubmitted(true);
|
|
104
100
|
}
|
|
105
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "shadcn/ui Components" }), _jsxs("p", { className: "text-slate-500 text-xs leading-relaxed", children: ["All components below are imported from ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "stc/lib/ui/" }), ", following the same ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " structure recommended by shadcn/ui. Built on Radix UI primitives, styled with Tailwind CSS.
|
|
101
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "shadcn/ui Components" }), _jsxs("p", { className: "text-slate-500 text-xs leading-relaxed", children: ["All components below are imported from ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "stc/lib/ui/" }), ", following the same ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " structure recommended by shadcn/ui. Built on Radix UI primitives, styled with Tailwind CSS. Client dependencies are bundled locally by the Kebab build command."] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Label + Input" }), _jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: nameId, children: "Username" }), _jsx(Input, { id: nameId, type: "text", placeholder: "Enter your username", value: name, onChange: e => { setName(e.target.value); } })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: emailId, children: "Email" }), _jsx(Input, { id: emailId, type: "email", placeholder: "you@example.com", value: email, onChange: e => { setEmail(e.target.value); } })] })] }), _jsx("p", { className: "text-xs text-slate-400 mt-3", children: "Click the Label text to focus the corresponding input (Radix UI a11y semantics)" })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Checkbox" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: agreeId, checked: agree, onCheckedChange: setAgree }), _jsx(Label, { htmlFor: agreeId, children: "I have read and agree to the Terms of Service" })] }), _jsxs("p", { className: "text-xs text-slate-400 mt-3", children: ["Value: ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: String(agree) }), "\u00A0(supports ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "true | false | 'indeterminate'" }), " tri-state)"] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Switch" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: newsletterId, checked: newsletter, onCheckedChange: setNewsletter }), _jsx(Label, { htmlFor: newsletterId, children: "Subscribe to product updates" })] }), _jsxs("p", { className: "text-xs text-slate-400 mt-3", children: ["Value: ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: newsletter ? 'true' : 'false' })] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Combined Form (Submit Demo)" }), submitted ? (_jsxs("div", { className: "space-y-2 text-sm", children: [_jsx("p", { className: "text-green-700 font-medium", children: "\u2713 Submitted! Received data:" }), _jsx("pre", { className: "bg-slate-50 border border-slate-200 rounded-lg p-3 text-xs text-slate-700 overflow-auto", children: JSON.stringify({ name, email, agree: Boolean(agree), newsletter }, null, 2) }), _jsx("button", { onClick: () => { setSubmitted(false); }, className: "text-xs text-blue-500 hover:underline cursor-pointer", children: "Reset" })] })) : (_jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsxs(Label, { htmlFor: `${nameId}-form`, children: ["Username ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: `${nameId}-form`, required: true, placeholder: "At least 2 characters", value: name, onChange: e => { setName(e.target.value); } })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsxs(Label, { htmlFor: `${emailId}-form`, children: ["Email ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: `${emailId}-form`, type: "email", required: true, placeholder: "you@example.com", value: email, onChange: e => { setEmail(e.target.value); } })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: `${agreeId}-form`, checked: agree, onCheckedChange: setAgree, required: true }), _jsx(Label, { htmlFor: `${agreeId}-form`, children: "Agree to terms" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: `${newsletterId}-form`, checked: newsletter, onCheckedChange: setNewsletter }), _jsx(Label, { htmlFor: `${newsletterId}-form`, children: "Subscribe" })] }), _jsx("button", { type: "submit", className: "inline-flex items-center px-4 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white text-sm font-medium cursor-pointer", children: "Submit" })] }))] })] }));
|
|
106
102
|
}
|
|
107
103
|
// ─── 页面主组件 ────────────────────────────────────────────────────────────────
|
|
108
104
|
/** --- Kebab React 全页面演示 --- */
|
|
@@ -153,7 +149,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
|
|
|
153
149
|
checkbox.tsx # shadcn Checkbox
|
|
154
150
|
switch.tsx # shadcn Switch
|
|
155
151
|
view/
|
|
156
|
-
react-page.tsx # Page component (import + compose)` }), _jsxs("p", { className: "text-slate-500 text-xs mt-3", children: ["Mirrors the shadcn/ui", ' ', _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " convention.
|
|
152
|
+
react-page.tsx # Page component (import + compose)` }), _jsxs("p", { className: "text-slate-500 text-xs mt-3", children: ["Mirrors the shadcn/ui", ' ', _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " convention. Client dependencies are bundled locally by the Kebab build command."] })] })] })), tab === 'routing' && (_jsxs(MemoryRouter, { children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-1", children: "React Router Demo" }), _jsxs("p", { className: "text-slate-500 text-xs mb-4", children: ["Uses ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "MemoryRouter" }), ' ', "to demonstrate route navigation, dynamic params (useParams), and programmatic navigation (useNavigate). Works on both server SSR and client hydration with no extra server configuration."] }), _jsxs(Routes, { children: [_jsx(Route, { path: "/", element: _jsx(RouterHome, {}) }), _jsx(Route, { path: "/about", element: _jsx(RouterAbout, {}) }), _jsx(Route, { path: "/user/:id", element: _jsx(RouterUser, {}) })] })] }), _jsxs(Card, { className: "mt-4", children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "Full-Page BrowserRouter Setup" }), _jsx("p", { className: "text-slate-500 text-xs mb-3", children: "To let React Router manage the real URL (e.g. /app, /app/about), replace MemoryRouter with BrowserRouter and route all sub-paths to the same Ctr method on the server:" }), _jsx("pre", { className: "bg-slate-50 border border-slate-200 rounded-lg p-4 text-xs overflow-auto leading-relaxed text-slate-700", children: `// 1. route.json: 将所有子路径路由到同一 Ctr 方法
|
|
157
153
|
{
|
|
158
154
|
"app": "ctr/app@reactPage",
|
|
159
155
|
"app\\/.*": "ctr/app@reactPage"
|
|
@@ -9,26 +9,22 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 【使用方式】
|
|
11
11
|
* 在 Ctr 方法中调用 _loadReactPage('view/react', { ...props }),
|
|
12
|
-
* 框架自动将
|
|
12
|
+
* 框架自动将 props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
|
|
13
13
|
*
|
|
14
14
|
* 【多页面 / 共用组件】
|
|
15
15
|
* 将公共 UI(如 Label/Input/Checkbox)放在 stc/lib/ui/ 目录,各页面 import 进来。
|
|
16
16
|
* 这和 shadcn/ui 推荐的 components/ui/ 目录结构完全一致。
|
|
17
|
-
* tsc watch 会自动将所有 .tsx 编译为同路径的 .js
|
|
17
|
+
* tsc watch 会自动将所有 .tsx 编译为同路径的 .js,供服务端 SSR 使用。
|
|
18
18
|
*
|
|
19
19
|
* 【编译方式】
|
|
20
20
|
* 本文件 (.tsx) 已集成到 source/tsconfig.json 的 include 中,
|
|
21
|
-
* 开启 `tsc: watch - source/tsconfig.json`
|
|
21
|
+
* 开启 `tsc: watch - source/tsconfig.json` 即可自动编译服务端文件。
|
|
22
22
|
* 编译输出:stc/view/react.page.js(由 tsc 覆盖写入,勿手动编辑 .js 文件)
|
|
23
|
+
* 客户端水合需执行:node ./source/main build -d source/www/example/stc
|
|
23
24
|
*
|
|
24
25
|
* 【运行时机】
|
|
25
26
|
* - 服务端(Node.js):_loadReactPage() 调用 renderToString(),产出完整 HTML 字符串。
|
|
26
|
-
* -
|
|
27
|
-
* - 两端使用同一份 JS 文件:服务端从磁盘读,浏览器从静态 URL 下载。
|
|
28
|
-
*
|
|
29
|
-
* 【第三方包 import map 自动解析】
|
|
30
|
-
* 开发模式下,框架会自动扫描入口 JS 及其相对引用中的所有 bare specifier,
|
|
31
|
-
* 并通过 esm.sh CDN 自动生成 import map 条目,无需手动配置。
|
|
27
|
+
* - 客户端(浏览器):加载 kebab build 生成的 bundle,由 hydrateRoot 接管 document。
|
|
32
28
|
*
|
|
33
29
|
* 【限制】
|
|
34
30
|
* - 不能包含 Node.js 专属代码(fs/path/lDb 等),数据必须通过 props 传入。
|
|
@@ -210,7 +206,7 @@ function ShadcnDemo() {
|
|
|
210
206
|
All components below are imported from <code className="bg-slate-100 px-1 rounded">stc/lib/ui/</code>,
|
|
211
207
|
following the same <code className="bg-slate-100 px-1 rounded">components/ui/</code> structure recommended by shadcn/ui.
|
|
212
208
|
Built on Radix UI primitives, styled with Tailwind CSS.
|
|
213
|
-
|
|
209
|
+
Client dependencies are bundled locally by the Kebab build command.
|
|
214
210
|
</p>
|
|
215
211
|
</Card>
|
|
216
212
|
|
|
@@ -392,8 +388,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
|
|
|
392
388
|
<meta charSet="UTF-8" />
|
|
393
389
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
394
390
|
<title>{title}</title>
|
|
395
|
-
{/*
|
|
396
|
-
{/* dev: Tailwind Play CDN;prod: 将此行替换为 kebab build 编译的 CSS 文件 */}
|
|
391
|
+
{/* CSS 和客户端水合 bundle 均由 kebab build 生成 */}
|
|
397
392
|
<link href={`${_urlStc}view/react.page.css?v=${_staticVer}`} rel="stylesheet" />
|
|
398
393
|
</head>
|
|
399
394
|
<body className="bg-slate-50 min-h-screen font-sans">
|
|
@@ -494,8 +489,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
|
|
|
494
489
|
<p className="text-slate-500 text-xs mt-3">
|
|
495
490
|
Mirrors the shadcn/ui{' '}
|
|
496
491
|
<code className="bg-slate-100 px-1 rounded">components/ui/</code> convention.
|
|
497
|
-
|
|
498
|
-
no manual import map configuration needed.
|
|
492
|
+
Client dependencies are bundled locally by the Kebab build command.
|
|
499
493
|
</p>
|
|
500
494
|
</Card>
|
|
501
495
|
|