@maiyunnet/kebab 9.0.2 → 9.1.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/LICENSE +0 -0
- package/README.md +0 -0
- package/bin/kebab.js +0 -0
- package/doc/kebab-rag.md +604 -604
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/ai.d.ts +0 -0
- package/lib/ai.js +0 -0
- package/lib/buffer.d.ts +0 -0
- package/lib/buffer.js +0 -0
- package/lib/captcha/zcool-addict-italic.ttf +0 -0
- package/lib/captcha.d.ts +0 -0
- package/lib/captcha.js +0 -0
- package/lib/consistent.d.ts +0 -0
- package/lib/consistent.js +0 -0
- package/lib/core.d.ts +0 -0
- package/lib/core.js +0 -0
- package/lib/cron.d.ts +0 -0
- package/lib/cron.js +0 -0
- package/lib/crypto.d.ts +0 -0
- package/lib/crypto.js +0 -0
- package/lib/db/conn.d.ts +0 -0
- package/lib/db/conn.js +0 -0
- package/lib/db/pool.d.ts +0 -0
- package/lib/db/pool.js +0 -0
- package/lib/db/tran.d.ts +0 -0
- package/lib/db/tran.js +8 -8
- package/lib/db.d.ts +0 -0
- package/lib/db.js +0 -0
- package/lib/dns.d.ts +0 -0
- package/lib/dns.js +0 -0
- package/lib/fs.d.ts +0 -0
- package/lib/fs.js +0 -0
- package/lib/kv.d.ts +0 -0
- package/lib/kv.js +0 -0
- package/lib/lan.d.ts +0 -0
- package/lib/lan.js +0 -0
- package/lib/lang.d.ts +0 -0
- package/lib/lang.js +0 -0
- package/lib/net/cacert.pem +0 -0
- package/lib/net/formdata.d.ts +0 -0
- package/lib/net/formdata.js +0 -0
- package/lib/net/request.d.ts +0 -0
- package/lib/net/request.js +0 -0
- package/lib/net/response.d.ts +0 -0
- package/lib/net/response.js +0 -0
- package/lib/net.d.ts +0 -0
- package/lib/net.js +0 -0
- package/lib/ratelimit.d.ts +0 -0
- package/lib/ratelimit.js +0 -0
- package/lib/s3.d.ts +0 -0
- package/lib/s3.js +0 -0
- package/lib/scan.d.ts +0 -0
- package/lib/scan.js +0 -0
- package/lib/session.d.ts +0 -0
- package/lib/session.js +0 -0
- package/lib/socket.d.ts +0 -0
- package/lib/socket.js +0 -0
- package/lib/sql.d.ts +0 -0
- package/lib/sql.js +0 -0
- package/lib/ssh/sftp.d.ts +0 -0
- package/lib/ssh/sftp.js +0 -0
- package/lib/ssh/shell.d.ts +0 -0
- package/lib/ssh/shell.js +0 -0
- package/lib/ssh.d.ts +0 -0
- package/lib/ssh.js +0 -0
- package/lib/text/tld.json +0 -0
- package/lib/text.d.ts +0 -0
- package/lib/text.js +0 -0
- package/lib/time.d.ts +0 -0
- package/lib/time.js +0 -0
- package/lib/turnstile.d.ts +0 -0
- package/lib/turnstile.js +0 -0
- package/lib/vector.d.ts +0 -0
- package/lib/vector.js +0 -0
- package/lib/ws.d.ts +0 -0
- package/lib/ws.js +0 -0
- package/lib/zip.d.ts +0 -0
- package/lib/zip.js +0 -0
- package/lib/zlib.d.ts +0 -0
- package/lib/zlib.js +0 -0
- package/main.d.ts +0 -0
- package/main.js +0 -0
- package/package.json +9 -2
- package/sys/child.d.ts +0 -0
- package/sys/child.js +0 -0
- package/sys/cmd.d.ts +0 -0
- package/sys/cmd.js +69 -42
- package/sys/ctr.d.ts +8 -0
- package/sys/ctr.js +86 -36
- package/sys/master.d.ts +0 -0
- package/sys/master.js +0 -0
- package/sys/mod.d.ts +0 -0
- package/sys/mod.js +0 -0
- package/sys/monitor/watchdog.d.ts +0 -0
- package/sys/monitor/watchdog.js +0 -0
- package/sys/monitor.d.ts +0 -0
- package/sys/monitor.js +1 -1
- package/sys/route.d.ts +0 -0
- package/sys/route.js +0 -0
- package/www/example/ctr/main.d.ts +0 -0
- package/www/example/ctr/main.js +0 -0
- package/www/example/ctr/middle.d.ts +0 -0
- package/www/example/ctr/middle.js +0 -0
- package/www/example/ctr/test.d.ts +4 -0
- package/www/example/ctr/test.js +12 -3
- package/www/example/data/locale/en.test.json +0 -0
- package/www/example/data/locale/index.html +0 -0
- package/www/example/data/locale/ja.test.json +0 -0
- package/www/example/data/locale/sc.test.json +0 -0
- package/www/example/data/locale/tc.test.json +0 -0
- package/www/example/data/test.zip +0 -0
- package/www/example/kebab.json +0 -0
- package/www/example/mod/test.d.ts +0 -0
- package/www/example/mod/test.js +0 -0
- package/www/example/mod/testdata.d.ts +0 -0
- package/www/example/mod/testdata.js +0 -0
- package/www/example/route.json +0 -0
- package/www/example/stc/chunk-YJ3GYATF.js +81 -0
- package/www/example/stc/lib/ui/checkbox.d.ts +9 -0
- package/www/example/stc/lib/ui/checkbox.js +11 -0
- package/www/example/stc/lib/ui/checkbox.tsx +30 -0
- package/www/example/stc/lib/ui/input.d.ts +3 -0
- package/www/example/stc/lib/ui/input.js +10 -0
- package/www/example/stc/lib/ui/input.tsx +24 -0
- package/www/example/stc/lib/ui/label.d.ts +11 -0
- package/www/example/stc/lib/ui/label.js +13 -0
- package/www/example/stc/lib/ui/label.tsx +24 -0
- package/www/example/stc/lib/ui/switch.d.ts +9 -0
- package/www/example/stc/lib/ui/switch.js +11 -0
- package/www/example/stc/lib/ui/switch.tsx +31 -0
- package/www/example/stc/lib/utils.d.ts +7 -0
- package/www/example/stc/lib/utils.js +10 -0
- package/www/example/stc/view/hello.page.bundle.js +1 -0
- package/www/example/stc/view/hello.page.css +2 -0
- package/www/example/stc/view/hello.page.d.ts +17 -0
- package/www/example/stc/view/hello.page.js +15 -0
- package/www/example/stc/view/hello.page.tsx +49 -0
- package/www/example/stc/view/react-router.page.bundle.js +1 -0
- package/www/example/stc/view/react-router.page.css +2 -0
- package/www/example/stc/view/{react-router-page.d.ts → react-router.page.d.ts} +1 -1
- package/www/example/stc/view/{react-router-page.js → react-router.page.js} +1 -1
- package/www/example/stc/view/{react-router-page.tsx → react-router.page.tsx} +1 -1
- package/www/example/stc/view/react.page.bundle.js +26 -0
- package/www/example/stc/view/react.page.css +2 -0
- package/www/example/stc/view/{react-page.d.ts → react.page.d.ts} +16 -18
- package/www/example/stc/view/react.page.js +181 -0
- package/www/example/stc/view/{react-page.tsx → react.page.tsx} +259 -111
- package/www/example/view/test.ejs +0 -0
- package/www/example/ws/handler.d.ts +0 -0
- package/www/example/ws/handler.js +0 -0
- package/www/example/ws/main.d.ts +0 -0
- package/www/example/ws/main.js +0 -0
- package/www/example/ws/mproxy.d.ts +0 -0
- package/www/example/ws/mproxy.js +0 -0
- package/www/example/ws/rproxy.d.ts +0 -0
- package/www/example/ws/rproxy.js +0 -0
- package/www/example/ws/rsocket.d.ts +0 -0
- package/www/example/ws/rsocket.js +0 -0
- package/www/example/ws/test.d.ts +0 -0
- package/www/example/ws/test.js +0 -0
- package/www/example/stc/view/react-page.bundle.js +0 -97
- package/www/example/stc/view/react-page.css +0 -2
- package/www/example/stc/view/react-page.js +0 -136
- package/www/example/stc/view/react-router-page.bundle.js +0 -81
- package/www/example/stc/view/react-router-page.css +0 -2
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
7
|
*/
|
|
8
8
|
/** --- 当前系统版本号 --- */
|
|
9
|
-
export const VER = '9.0
|
|
9
|
+
export const VER = '9.1.0';
|
|
10
10
|
// --- 服务端用的路径 ---
|
|
11
11
|
const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
|
|
12
12
|
/** --- /xxx/xxx --- */
|
package/lib/ai.d.ts
CHANGED
|
File without changes
|
package/lib/ai.js
CHANGED
|
File without changes
|
package/lib/buffer.d.ts
CHANGED
|
File without changes
|
package/lib/buffer.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/captcha.d.ts
CHANGED
|
File without changes
|
package/lib/captcha.js
CHANGED
|
File without changes
|
package/lib/consistent.d.ts
CHANGED
|
File without changes
|
package/lib/consistent.js
CHANGED
|
File without changes
|
package/lib/core.d.ts
CHANGED
|
File without changes
|
package/lib/core.js
CHANGED
|
File without changes
|
package/lib/cron.d.ts
CHANGED
|
File without changes
|
package/lib/cron.js
CHANGED
|
File without changes
|
package/lib/crypto.d.ts
CHANGED
|
File without changes
|
package/lib/crypto.js
CHANGED
|
File without changes
|
package/lib/db/conn.d.ts
CHANGED
|
File without changes
|
package/lib/db/conn.js
CHANGED
|
File without changes
|
package/lib/db/pool.d.ts
CHANGED
|
File without changes
|
package/lib/db/pool.js
CHANGED
|
File without changes
|
package/lib/db/tran.d.ts
CHANGED
|
File without changes
|
package/lib/db/tran.js
CHANGED
|
@@ -42,8 +42,8 @@ export class Transaction {
|
|
|
42
42
|
async query(sql, values) {
|
|
43
43
|
if (!this._conn) {
|
|
44
44
|
// --- 当前连接已不可用 ---
|
|
45
|
-
lCore.display('[DB][Transaction][query] has been closed ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql);
|
|
46
|
-
lCore.log({}, '[DB][Transaction][query] has been closed ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql, '-error');
|
|
45
|
+
lCore.display('[DB][Transaction][query] has been closed, so you cannot execute SQL: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql);
|
|
46
|
+
lCore.log({}, '[DB][Transaction][query] has been closed, so you cannot execute SQL: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql, '-error');
|
|
47
47
|
return {
|
|
48
48
|
'rows': null,
|
|
49
49
|
'fields': [],
|
|
@@ -65,8 +65,8 @@ export class Transaction {
|
|
|
65
65
|
async execute(sql, values) {
|
|
66
66
|
if (!this._conn) {
|
|
67
67
|
// --- 当前连接已不可用 ---
|
|
68
|
-
lCore.display('[DB][Transaction][execute] has been closed ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql);
|
|
69
|
-
lCore.log({}, '
|
|
68
|
+
lCore.display('[DB][Transaction][execute] has been closed, so you cannot execute SQL: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql);
|
|
69
|
+
lCore.log({}, '[DB][Transaction][execute] has been closed, so you cannot execute SQL: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr') + ': ' + sql, '-error');
|
|
70
70
|
return {
|
|
71
71
|
'packet': null,
|
|
72
72
|
'fields': [],
|
|
@@ -83,8 +83,8 @@ export class Transaction {
|
|
|
83
83
|
async commit() {
|
|
84
84
|
if (!this._conn) {
|
|
85
85
|
// --- 当前连接已不可用 ---
|
|
86
|
-
lCore.display('[DB][Transaction][commit] has been closed ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'));
|
|
87
|
-
lCore.log({}, '[DB][Transaction][commit] has been closed ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'), '-error');
|
|
86
|
+
lCore.display('[DB][Transaction][commit] has been closed, so you cannot commit: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'));
|
|
87
|
+
lCore.log({}, '[DB][Transaction][commit] has been closed, so you cannot commit: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'), '-error');
|
|
88
88
|
return false;
|
|
89
89
|
}
|
|
90
90
|
const r = await this._conn.commit();
|
|
@@ -104,8 +104,8 @@ export class Transaction {
|
|
|
104
104
|
async rollback() {
|
|
105
105
|
if (!this._conn) {
|
|
106
106
|
// --- 当前连接已不可用 ---
|
|
107
|
-
lCore.display('[DB][Transaction][rollback] has been closed: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'));
|
|
108
|
-
lCore.log({}, '[DB][Transaction][rollback] has been closed: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'), '-error');
|
|
107
|
+
lCore.display('[DB][Transaction][rollback] has been closed, so you cannot rollback: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'));
|
|
108
|
+
lCore.log({}, '[DB][Transaction][rollback] has been closed, so you cannot rollback: ' + (this._ctr?.getPrototype('_config').const.path ?? 'no ctr'), '-error');
|
|
109
109
|
return false;
|
|
110
110
|
}
|
|
111
111
|
const r = await this._conn.rollback();
|
package/lib/db.d.ts
CHANGED
|
File without changes
|
package/lib/db.js
CHANGED
|
File without changes
|
package/lib/dns.d.ts
CHANGED
|
File without changes
|
package/lib/dns.js
CHANGED
|
File without changes
|
package/lib/fs.d.ts
CHANGED
|
File without changes
|
package/lib/fs.js
CHANGED
|
File without changes
|
package/lib/kv.d.ts
CHANGED
|
File without changes
|
package/lib/kv.js
CHANGED
|
File without changes
|
package/lib/lan.d.ts
CHANGED
|
File without changes
|
package/lib/lan.js
CHANGED
|
File without changes
|
package/lib/lang.d.ts
CHANGED
|
File without changes
|
package/lib/lang.js
CHANGED
|
File without changes
|
package/lib/net/cacert.pem
CHANGED
|
File without changes
|
package/lib/net/formdata.d.ts
CHANGED
|
File without changes
|
package/lib/net/formdata.js
CHANGED
|
File without changes
|
package/lib/net/request.d.ts
CHANGED
|
File without changes
|
package/lib/net/request.js
CHANGED
|
File without changes
|
package/lib/net/response.d.ts
CHANGED
|
File without changes
|
package/lib/net/response.js
CHANGED
|
File without changes
|
package/lib/net.d.ts
CHANGED
|
File without changes
|
package/lib/net.js
CHANGED
|
File without changes
|
package/lib/ratelimit.d.ts
CHANGED
|
File without changes
|
package/lib/ratelimit.js
CHANGED
|
File without changes
|
package/lib/s3.d.ts
CHANGED
|
File without changes
|
package/lib/s3.js
CHANGED
|
File without changes
|
package/lib/scan.d.ts
CHANGED
|
File without changes
|
package/lib/scan.js
CHANGED
|
File without changes
|
package/lib/session.d.ts
CHANGED
|
File without changes
|
package/lib/session.js
CHANGED
|
File without changes
|
package/lib/socket.d.ts
CHANGED
|
File without changes
|
package/lib/socket.js
CHANGED
|
File without changes
|
package/lib/sql.d.ts
CHANGED
|
File without changes
|
package/lib/sql.js
CHANGED
|
File without changes
|
package/lib/ssh/sftp.d.ts
CHANGED
|
File without changes
|
package/lib/ssh/sftp.js
CHANGED
|
File without changes
|
package/lib/ssh/shell.d.ts
CHANGED
|
File without changes
|
package/lib/ssh/shell.js
CHANGED
|
File without changes
|
package/lib/ssh.d.ts
CHANGED
|
File without changes
|
package/lib/ssh.js
CHANGED
|
File without changes
|
package/lib/text/tld.json
CHANGED
|
File without changes
|
package/lib/text.d.ts
CHANGED
|
File without changes
|
package/lib/text.js
CHANGED
|
File without changes
|
package/lib/time.d.ts
CHANGED
|
File without changes
|
package/lib/time.js
CHANGED
|
File without changes
|
package/lib/turnstile.d.ts
CHANGED
|
File without changes
|
package/lib/turnstile.js
CHANGED
|
File without changes
|
package/lib/vector.d.ts
CHANGED
|
File without changes
|
package/lib/vector.js
CHANGED
|
File without changes
|
package/lib/ws.d.ts
CHANGED
|
File without changes
|
package/lib/ws.js
CHANGED
|
File without changes
|
package/lib/zip.d.ts
CHANGED
|
File without changes
|
package/lib/zip.js
CHANGED
|
File without changes
|
package/lib/zlib.d.ts
CHANGED
|
File without changes
|
package/lib/zlib.js
CHANGED
|
File without changes
|
package/main.d.ts
CHANGED
|
File without changes
|
package/main.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maiyunnet/kebab",
|
|
3
|
-
"version": "9.0
|
|
3
|
+
"version": "9.1.0",
|
|
4
4
|
"description": "Simple, easy-to-use, and fully-featured Node.js framework that is ready-to-use out of the box.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -28,12 +28,18 @@
|
|
|
28
28
|
"@litert/mime": "^0.1.3",
|
|
29
29
|
"@litert/redis": "^3.2.0",
|
|
30
30
|
"@litert/websocket": "^0.2.8",
|
|
31
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
32
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
33
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
34
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
35
|
+
"@tailwindcss/cli": "^4.2.2",
|
|
31
36
|
"@types/ssh2": "^1.15.5",
|
|
32
37
|
"@zilliz/milvus2-sdk-node": "^2.6.11",
|
|
33
38
|
"ajv": "^8.18.0",
|
|
34
39
|
"ajv-formats": "^3.0.1",
|
|
40
|
+
"class-variance-authority": "^0.7.1",
|
|
41
|
+
"clsx": "^2.1.1",
|
|
35
42
|
"ejs": "^5.0.1",
|
|
36
|
-
"@tailwindcss/cli": "^4.2.2",
|
|
37
43
|
"esbuild": "^0.27.4",
|
|
38
44
|
"jszip": "^3.10.1",
|
|
39
45
|
"mysql2": "^3.20.0",
|
|
@@ -45,6 +51,7 @@
|
|
|
45
51
|
"react-router-dom": "^7.13.1",
|
|
46
52
|
"ssh2": "^1.17.0",
|
|
47
53
|
"svg-captcha": "^1.4.0",
|
|
54
|
+
"tailwind-merge": "^3.5.0",
|
|
48
55
|
"tencentcloud-sdk-nodejs": "^4.1.199"
|
|
49
56
|
},
|
|
50
57
|
"devDependencies": {
|
package/sys/child.d.ts
CHANGED
|
File without changes
|
package/sys/child.js
CHANGED
|
File without changes
|
package/sys/cmd.d.ts
CHANGED
|
File without changes
|
package/sys/cmd.js
CHANGED
|
@@ -351,10 +351,11 @@ async function run() {
|
|
|
351
351
|
process.exit();
|
|
352
352
|
}
|
|
353
353
|
if (cmds[0] === 'build') {
|
|
354
|
-
// --- 构建命令:使用 esbuild
|
|
355
|
-
// ---
|
|
356
|
-
// ---
|
|
357
|
-
// ---
|
|
354
|
+
// --- 构建命令:使用 esbuild 打包 *.page.tsx 文件为自包含 bundle ---
|
|
355
|
+
// --- 约定:文件名以 .page.tsx 结尾的为页面入口,会被打包;其余 .tsx 均视为组件,不参与打包 ---
|
|
356
|
+
// --- 与 Next.js 的 page.tsx 约定同理,开发者可自由组织目录结构,框架靠文件名区分入口与组件 ---
|
|
357
|
+
// --- 推荐目录结构:stc/view/home.page.tsx(入口)+ stc/view/components/header.tsx(组件)---
|
|
358
|
+
// --- 用法:node ./source/main build [-d www/myapp/stc] ---
|
|
358
359
|
let targetDir = '';
|
|
359
360
|
for (let i = 1; i < cmds.length; i++) {
|
|
360
361
|
if ((cmds[i] === '-d' || cmds[i] === '--dir') && cmds[i + 1]) {
|
|
@@ -362,7 +363,7 @@ async function run() {
|
|
|
362
363
|
i++;
|
|
363
364
|
}
|
|
364
365
|
}
|
|
365
|
-
/** ---
|
|
366
|
+
/** --- 递归扫描目录,收集所有 *.page.tsx 文件作为打包入口 --- */
|
|
366
367
|
const entryPoints = [];
|
|
367
368
|
const scanDir = async (dir) => {
|
|
368
369
|
const items = await lFs.readDir(dir);
|
|
@@ -370,13 +371,16 @@ async function run() {
|
|
|
370
371
|
if (item.name === '.' || item.name === '..') {
|
|
371
372
|
continue;
|
|
372
373
|
}
|
|
373
|
-
if (
|
|
374
|
+
if (item.isDirectory()) {
|
|
375
|
+
await scanDir(`${dir}/${item.name}`);
|
|
376
|
+
}
|
|
377
|
+
else if (item.name.endsWith('.page.tsx')) {
|
|
374
378
|
entryPoints.push(`${dir}/${item.name}`);
|
|
375
379
|
}
|
|
376
380
|
}
|
|
377
381
|
};
|
|
378
382
|
if (targetDir) {
|
|
379
|
-
// ---
|
|
383
|
+
// --- 指定了目录:递归扫描该目录下所有 *.page.tsx ---
|
|
380
384
|
const absTarget = targetDir.startsWith('/') || /^[A-Za-z]:/.test(targetDir)
|
|
381
385
|
? targetDir
|
|
382
386
|
: kebab.ROOT_CWD + targetDir.replace(/^\//, '');
|
|
@@ -390,8 +394,7 @@ async function run() {
|
|
|
390
394
|
}
|
|
391
395
|
}
|
|
392
396
|
else {
|
|
393
|
-
// ---
|
|
394
|
-
// --- 即扫描 stc/*.tsx 和 stc/*/*.tsx(如 stc/view/app.tsx),不再深入 ---
|
|
397
|
+
// --- 未指定目录:递归扫描所有站点的 www/*/stc/ ---
|
|
395
398
|
const wwwItems = await lFs.readDir(kebab.WWW_CWD);
|
|
396
399
|
for (const wwwItem of wwwItems) {
|
|
397
400
|
if (wwwItem.name === '.' || wwwItem.name === '..' || !wwwItem.isDirectory()) {
|
|
@@ -401,16 +404,7 @@ async function run() {
|
|
|
401
404
|
if (!await lFs.isDir(stcPath)) {
|
|
402
405
|
continue;
|
|
403
406
|
}
|
|
404
|
-
// --- 扫描 stc/ 直属文件 ---
|
|
405
407
|
await scanDir(stcPath);
|
|
406
|
-
// --- 扫描 stc/ 的直接子目录(如 view/),取其顶层 .tsx 作为入口 ---
|
|
407
|
-
const stcItems = await lFs.readDir(stcPath);
|
|
408
|
-
for (const stcItem of stcItems) {
|
|
409
|
-
if (stcItem.name === '.' || stcItem.name === '..' || !stcItem.isDirectory()) {
|
|
410
|
-
continue;
|
|
411
|
-
}
|
|
412
|
-
await scanDir(`${stcPath}/${stcItem.name}`);
|
|
413
|
-
}
|
|
414
408
|
}
|
|
415
409
|
}
|
|
416
410
|
if (entryPoints.length === 0) {
|
|
@@ -420,17 +414,32 @@ async function run() {
|
|
|
420
414
|
}
|
|
421
415
|
lCore.display('KEBAB', 'BUILD', `Found ${entryPoints.length} file(s).`);
|
|
422
416
|
const esbuild = await import('esbuild');
|
|
417
|
+
// --- 按 stc/ 根目录分组:同一站点内所有页面合并为一次 esbuild 构建 ---
|
|
418
|
+
// --- 不同站点(不同 stc/)相互隔离,同站点内跨子目录页面共享 chunk ---
|
|
419
|
+
// --- splitting: true 自动将任意共享 import(React/Header/utils 等)提取为独立 chunk ---
|
|
420
|
+
/**
|
|
421
|
+
* --- 查找路径中最后一段名为 stc 的祖先目录 ---
|
|
422
|
+
*/
|
|
423
|
+
const getStcRoot = (filePath) => {
|
|
424
|
+
const parts = filePath.split('/');
|
|
425
|
+
const idx = parts.lastIndexOf('stc');
|
|
426
|
+
return idx >= 0 ? parts.slice(0, idx + 1).join('/') : parts.slice(0, -1).join('/');
|
|
427
|
+
};
|
|
428
|
+
const byStc = new Map();
|
|
423
429
|
for (const entry of entryPoints) {
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
430
|
+
const stcRoot = getStcRoot(entry);
|
|
431
|
+
if (!byStc.has(stcRoot)) {
|
|
432
|
+
byStc.set(stcRoot, []);
|
|
433
|
+
}
|
|
434
|
+
byStc.get(stcRoot).push(entry);
|
|
435
|
+
}
|
|
436
|
+
for (const [stcRoot, entries] of byStc) {
|
|
437
|
+
// --- 为每个页面写入水合入口临时文件(实际文件,splitting 不支持 stdin 多入口)---
|
|
438
|
+
const tempFiles = [];
|
|
439
|
+
for (const entry of entries) {
|
|
428
440
|
const basename = entry.split('/').pop().replace(/\.tsx$/, '');
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
// --- stdin 入口:含水合逻辑,_routerBase 在 props 中时自动包裹 BrowserRouter ---
|
|
432
|
-
// --- React/react-dom/react-router-dom 全部打入 bundle,浏览器只加载一个 JS ---
|
|
433
|
-
const stdinContent = [
|
|
441
|
+
const entryDir = entry.substring(0, entry.lastIndexOf('/'));
|
|
442
|
+
const hydrateCode = [
|
|
434
443
|
`import{hydrateRoot}from'react-dom/client';`,
|
|
435
444
|
`import{createElement}from'react';`,
|
|
436
445
|
`import{BrowserRouter}from'react-router-dom';`,
|
|
@@ -445,31 +454,52 @@ async function run() {
|
|
|
445
454
|
`}`,
|
|
446
455
|
`}`,
|
|
447
456
|
].join('');
|
|
457
|
+
const tempFile = `${entryDir}/${basename}.hydrate.tsx`;
|
|
458
|
+
await lFs.putContent(tempFile, hydrateCode);
|
|
459
|
+
tempFiles.push(tempFile);
|
|
460
|
+
lCore.display('KEBAB', 'BUILD', entry.replace(kebab.ROOT_CWD, ''), '→', entry.replace(kebab.ROOT_CWD, '').replace(/\.tsx$/, '.bundle.js'));
|
|
461
|
+
}
|
|
462
|
+
// --- JS 构建:整站一次构建,splitting 按实际共享情况自动提取 chunk ---
|
|
463
|
+
// --- outbase = outdir = stcRoot,入口保留子目录结构,chunk 落在 stcRoot 根 ---
|
|
464
|
+
try {
|
|
448
465
|
await esbuild.build({
|
|
449
|
-
'
|
|
450
|
-
'contents': stdinContent,
|
|
451
|
-
'resolveDir': resolveDir,
|
|
452
|
-
'sourcefile': basename + '.hydrate.tsx',
|
|
453
|
-
'loader': 'tsx',
|
|
454
|
-
},
|
|
466
|
+
'entryPoints': tempFiles,
|
|
455
467
|
'bundle': true,
|
|
456
|
-
|
|
468
|
+
'splitting': true,
|
|
457
469
|
'format': 'esm',
|
|
458
470
|
'jsx': 'automatic',
|
|
459
471
|
'jsxImportSource': 'react',
|
|
460
472
|
'platform': 'browser',
|
|
461
473
|
'target': 'es2022',
|
|
462
474
|
'minify': true,
|
|
463
|
-
'
|
|
475
|
+
'outbase': stcRoot,
|
|
476
|
+
'outdir': stcRoot,
|
|
477
|
+
'entryNames': '[dir]/[name]',
|
|
478
|
+
'chunkNames': 'chunk-[hash]',
|
|
464
479
|
});
|
|
465
|
-
|
|
466
|
-
|
|
480
|
+
// --- 将 *.hydrate.js 重命名为 *.bundle.js ---
|
|
481
|
+
for (const tempFile of tempFiles) {
|
|
482
|
+
const hydrateJs = tempFile.replace(/\.tsx$/, '.js');
|
|
483
|
+
const bundleJs = hydrateJs.replace(/\.hydrate\.js$/, '.bundle.js');
|
|
484
|
+
await lFs.rename(hydrateJs, bundleJs);
|
|
485
|
+
lCore.display('KEBAB', 'BUILD', 'JS', bundleJs.replace(kebab.ROOT_CWD, ''));
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
catch (e) {
|
|
489
|
+
lCore.display('KEBAB', 'BUILD', 'JS FAILED', stcRoot.replace(kebab.ROOT_CWD, ''), e.message ?? '');
|
|
490
|
+
}
|
|
491
|
+
finally {
|
|
492
|
+
// --- 清理临时水合入口文件 ---
|
|
493
|
+
for (const tempFile of tempFiles) {
|
|
494
|
+
await lFs.unlink(tempFile);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// --- CSS:每个入口单独构建 Tailwind ---
|
|
498
|
+
for (const entry of entries) {
|
|
467
499
|
const cssOut = entry.replace(/\.tsx$/, '.css');
|
|
468
|
-
/** --- 临时 CSS 输入文件,@source 扫描当前目录及子目录所有 tsx 文件 --- */
|
|
469
500
|
const tmpCss = entry + '.__tw__.css';
|
|
470
501
|
await lFs.putContent(tmpCss, `@import "tailwindcss";\n@source "./**/*.tsx";\n`);
|
|
471
502
|
try {
|
|
472
|
-
/** --- 直接用当前 Node.js 执行 CLI 的 JS 入口,跨平台无需 shell --- */
|
|
473
503
|
const twJs = fileURLToPath(new URL('../node_modules/@tailwindcss/cli/dist/index.mjs', import.meta.url));
|
|
474
504
|
await new Promise((resolve, reject) => {
|
|
475
505
|
const proc = childProcess.spawn(process.execPath, [twJs, '-i', tmpCss, '-o', cssOut, '--minify'], { 'shell': false });
|
|
@@ -493,9 +523,6 @@ async function run() {
|
|
|
493
523
|
await lFs.unlink(tmpCss);
|
|
494
524
|
}
|
|
495
525
|
}
|
|
496
|
-
catch (e) {
|
|
497
|
-
lCore.display('KEBAB', 'BUILD', 'FAILED', entry.replace(kebab.ROOT_CWD, ''), e.message ?? '');
|
|
498
|
-
}
|
|
499
526
|
}
|
|
500
527
|
lCore.display('DONE');
|
|
501
528
|
process.exit();
|
package/sys/ctr.d.ts
CHANGED
|
@@ -185,6 +185,14 @@ export declare class Ctr {
|
|
|
185
185
|
*/
|
|
186
186
|
'staticPath'?: string;
|
|
187
187
|
}): Promise<string>;
|
|
188
|
+
/**
|
|
189
|
+
* --- 递归扫描 JS 文件中的 import 语句,收集第三方 bare specifier ---
|
|
190
|
+
* @param filePath 当前要扫描的文件绝对路径
|
|
191
|
+
* @param scannedFiles 已扫描文件集(去重用)
|
|
192
|
+
* @param extraImports 收集到的第三方包名集合
|
|
193
|
+
* @param builtinImports 内置 import map,已有条目不重复添加
|
|
194
|
+
*/
|
|
195
|
+
private _scanImports;
|
|
188
196
|
/**
|
|
189
197
|
* --- 设置校验错误返回值 ---
|
|
190
198
|
* @param rtn 返回值数组
|