niuma-ui 1.2.0 → 1.2.1
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/CHANGELOG.md +11 -0
- package/README.en.md +1 -1
- package/README.md +3 -3
- package/dist/styles.css +1 -0
- package/dist/vite-plugins/monaco-zh-nls.d.ts +6 -1
- package/dist/vite-plugins/monaco-zh-nls.js +14 -22
- package/dist/vite-plugins/niuma-ui-host.d.ts +22 -0
- package/dist/vite-plugins/niuma-ui-host.js +254 -0
- package/dist/vite-plugins/rewrite-named-imports.d.ts +5 -0
- package/dist/vite-plugins/rewrite-named-imports.js +5 -0
- package/dist/vite-plugins/silence-antlr-parse-console.d.ts +15 -5
- package/dist/vite-plugins/silence-antlr-parse-console.js +17 -8
- package/package.json +21 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.2.1] - 2026-08-30
|
|
10
|
+
|
|
11
|
+
### 变更
|
|
12
|
+
|
|
13
|
+
- Vite 插件按库级惯例收口:`niumaUiHost` 走 `es-module-lexer` + `magic-string` + `createFilter`,导出改为 `niuma-ui/vite-plugins/niuma-ui-host`;`monaco-zh-nls` 统一 `node:`;`silence-antlr-parse-console` 带 options 与 sourcemap。
|
|
14
|
+
|
|
15
|
+
### 变更
|
|
16
|
+
|
|
17
|
+
- `styles.css` 源码与 `dist` 都透传 `@import 'tailwindcss'`,打包不再剥掉。宿主只处理这一份,业务 CSS 不要再写一遍。
|
|
18
|
+
- 宿主插件 `niumaUiHost`:业务 `pnpm dev` 联调用到的源码(HMR),`vite build` / npm 走同一批组件的 `dist` 子路径。不要把主入口别名到 `src/index.ts`。轻量宿主在自己的 `ui.ts` 里具名 re-export,不在本包维护第二入口。
|
|
19
|
+
|
|
9
20
|
## [1.2.0] - 2026-08-30
|
|
10
21
|
|
|
11
22
|
### 变更
|
package/README.en.md
CHANGED
|
@@ -29,7 +29,7 @@ Built for ops consoles, database workbenches, and internal admin UIs. Marketing
|
|
|
29
29
|
| Package manager | npm / pnpm / yarn (this repo develops with pnpm) |
|
|
30
30
|
| Vue | ^3.5 (`peerDependency`) |
|
|
31
31
|
| Bundler | Vite 5+ recommended; `RsMonacoEditor` needs Vite `?worker` |
|
|
32
|
-
| Styles | `import 'niuma-ui/styles.css'`
|
|
32
|
+
| Styles | `import 'niuma-ui/styles.css'` passes through `@import 'tailwindcss'`; Vite hosts need `@tailwindcss/vite` |
|
|
33
33
|
|
|
34
34
|
## Install
|
|
35
35
|
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Vue 3 **工作台**设计系统:一致的 `Rs*` 组件、`--rs-*` token,以
|
|
|
19
19
|
- **Rs\* 组件**:Button、Form、Dialog、Table、Tree、Tabs 等完整交互控件
|
|
20
20
|
- **专业工具向**:Monaco、CodeMirror、xterm 等编辑器 / 终端封装(按需引入)
|
|
21
21
|
- **无障碍与焦点**:底层基于 [Reka UI](https://reka-ui.com/),业务层只消费 `niuma-ui`
|
|
22
|
-
- **Vite
|
|
22
|
+
- **Vite 友好**:宿主开 `niumaUiHost`——`pnpm dev` 联调源码,打包走 npm `dist`
|
|
23
23
|
|
|
24
24
|
## 要求
|
|
25
25
|
|
|
@@ -29,7 +29,7 @@ Vue 3 **工作台**设计系统:一致的 `Rs*` 组件、`--rs-*` token,以
|
|
|
29
29
|
| 包管理器 | npm / pnpm / yarn(本仓库开发用 pnpm) |
|
|
30
30
|
| Vue | ^3.5.0(peerDependency) |
|
|
31
31
|
| 打包器 | Vite 5+ 推荐;使用 `RsMonacoEditor` 时需要 Vite 处理 `?worker` |
|
|
32
|
-
| 样式 | `import 'niuma-ui/styles.css'
|
|
32
|
+
| 样式 | `import 'niuma-ui/styles.css'`(透传 `@import 'tailwindcss'`);Vite 宿主用 `@tailwindcss/vite` 处理 |
|
|
33
33
|
|
|
34
34
|
## 安装
|
|
35
35
|
|
|
@@ -78,7 +78,7 @@ import { RsConfigProvider, RsButton } from 'niuma-ui'
|
|
|
78
78
|
1. 应用与业务模块只允许 `import { … } from 'niuma-ui'`,**禁止**直接依赖 `reka-ui`。
|
|
79
79
|
2. 样式入口:`import 'niuma-ui/styles.css'`(须在业务品牌 CSS 之前或按文档顺序加载)。
|
|
80
80
|
3. 根节点使用 `RsConfigProvider` 提供主题、语言与默认控件尺寸。
|
|
81
|
-
4.
|
|
81
|
+
4. 从主入口具名导入;轻量宿主在自己的 `ui.ts` 里再导出。启用 `niumaUiHost`,不要 `import *`,也不要把主入口别名到 `src/index.ts`。
|
|
82
82
|
|
|
83
83
|
组件清单与新增组件规范见 **[组件说明](./docs/components.md)**。
|
|
84
84
|
|
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
|
-
|
|
2
|
+
/** MonacoZhNlsOptions 预留扩展(例如后续 locale)。 */
|
|
3
|
+
export type MonacoZhNlsOptions = object;
|
|
4
|
+
/**
|
|
5
|
+
* MonacoZhNlsPlugin 用官方中文 NLS 替换 monaco-editor 的 nls.messages.js。
|
|
6
|
+
*/
|
|
7
|
+
export declare function monacoZhNlsPlugin(_options?: MonacoZhNlsOptions): Plugin;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vite 插件:将 Monaco Editor 0.55 内置的官方中文 NLS
|
|
3
|
-
* `nls.messages.js` 模块,使编辑器右键菜单、命令面板等 UI 显示中文。
|
|
2
|
+
* Vite 插件:将 Monaco Editor 0.55 内置的官方中文 NLS 注入 `nls.messages.js`。
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Monaco 自带 min/vs/nls.messages.zh-cn.js.js,提供完整的官方中文翻译。
|
|
4
|
+
* localize() 使用数字索引,需设置 globalThis._VSCODE_NLS_MESSAGES。
|
|
5
|
+
* 官方文件:monaco-editor/min/vs/nls.messages.zh-cn.js.js。
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
* 1. config
|
|
11
|
-
* 2. Rollup load
|
|
7
|
+
* 两阶段 load:
|
|
8
|
+
* 1. config + rolldown plugin → Vite 8 optimizeDeps
|
|
9
|
+
* 2. Rollup load → 生产构建 / 未预构建的 dev
|
|
12
10
|
*/
|
|
13
|
-
import { readFileSync } from 'fs';
|
|
14
|
-
import { createRequire } from 'module';
|
|
11
|
+
import { readFileSync } from 'node:fs';
|
|
12
|
+
import { createRequire } from 'node:module';
|
|
15
13
|
function extractZhCnMessages() {
|
|
16
14
|
try {
|
|
17
15
|
const require = createRequire(import.meta.url);
|
|
@@ -41,7 +39,10 @@ function extractZhCnMessages() {
|
|
|
41
39
|
return '';
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
|
|
42
|
+
/**
|
|
43
|
+
* MonacoZhNlsPlugin 用官方中文 NLS 替换 monaco-editor 的 nls.messages.js。
|
|
44
|
+
*/
|
|
45
|
+
export function monacoZhNlsPlugin(_options = {}) {
|
|
45
46
|
const messagesCode = extractZhCnMessages();
|
|
46
47
|
if (!messagesCode) {
|
|
47
48
|
console.warn('[monaco-zh-nls] 中文 NLS 数组提取失败,跳过插件');
|
|
@@ -55,24 +56,17 @@ export function getNLSMessages() { return globalThis._VSCODE_NLS_MESSAGES; }
|
|
|
55
56
|
export function getNLSLanguage() { return globalThis._VSCODE_NLS_LANGUAGE; }
|
|
56
57
|
`;
|
|
57
58
|
const nlsFileFilter = /monaco-editor[/\\]esm[/\\]vs[/\\]nls\.messages\.js$/;
|
|
58
|
-
/** rolldown plugin —— 用于 Vite 8 optimizeDeps 预构建阶段 */
|
|
59
59
|
const rolldownPlugin = {
|
|
60
60
|
name: 'monaco-zh-nls-rolldown',
|
|
61
61
|
load(id) {
|
|
62
|
-
if (nlsFileFilter.test(id))
|
|
62
|
+
if (nlsFileFilter.test(id))
|
|
63
63
|
return nlsModuleCode;
|
|
64
|
-
}
|
|
65
64
|
return undefined;
|
|
66
65
|
},
|
|
67
66
|
};
|
|
68
67
|
return {
|
|
69
68
|
name: 'monaco-zh-nls',
|
|
70
69
|
enforce: 'pre',
|
|
71
|
-
/**
|
|
72
|
-
* 将 rolldown plugin 注入到 optimizeDeps,覆盖 Vite 8 开发模式预构建阶段。
|
|
73
|
-
* Monaco 没有 "type":"module",Vite 会用 rolldown 预构建它,
|
|
74
|
-
* 此时需要通过 rolldownOptions.plugins 拦截。
|
|
75
|
-
*/
|
|
76
70
|
config() {
|
|
77
71
|
return {
|
|
78
72
|
optimizeDeps: {
|
|
@@ -82,11 +76,9 @@ export function getNLSLanguage() { return globalThis._VSCODE_NLS_LANGUAGE; }
|
|
|
82
76
|
},
|
|
83
77
|
};
|
|
84
78
|
},
|
|
85
|
-
/** Rollup load hook —— 用于生产构建 / SSR / 非预构建 dev 场景 */
|
|
86
79
|
load(id) {
|
|
87
|
-
if (nlsFileFilter.test(id))
|
|
80
|
+
if (nlsFileFilter.test(id))
|
|
88
81
|
return nlsModuleCode;
|
|
89
|
-
}
|
|
90
82
|
},
|
|
91
83
|
};
|
|
92
84
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type FilterPattern } from '@rollup/pluginutils';
|
|
2
|
+
import type { Plugin } from 'vite';
|
|
3
|
+
/** NiumaUiHostOptions 为宿主提供 include / exclude / 包根覆盖。 */
|
|
4
|
+
export type NiumaUiHostOptions = {
|
|
5
|
+
include?: FilterPattern;
|
|
6
|
+
exclude?: FilterPattern;
|
|
7
|
+
root?: string;
|
|
8
|
+
};
|
|
9
|
+
/** NiumaUiBinding 描述主入口一个运行时导出如何落到源码 from。 */
|
|
10
|
+
export type NiumaUiBinding = {
|
|
11
|
+
from: string;
|
|
12
|
+
kind: 'default' | 'named';
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* NiumaUiHost 返回一组插件(Vite 会摊平)。serve 做 styles alias,两侧都改写具名导入。
|
|
16
|
+
*/
|
|
17
|
+
export declare function niumaUiHost(options?: NiumaUiHostOptions): Plugin[];
|
|
18
|
+
/**
|
|
19
|
+
* RewriteHostStatement 改写一条已由 lexer 切出的静态 import/export。
|
|
20
|
+
* 类型-only、namespace、动态 import 原样返回 null。
|
|
21
|
+
*/
|
|
22
|
+
export declare function rewriteHostStatement(stmt: string, spec: string, map: Map<string, NiumaUiBinding>, targetOf: (from: string) => string): string | null;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 第一方宿主插件:`pnpm dev` 联调用到的源码,`vite build` / npm 走发布子路径。
|
|
3
|
+
* 禁止把 @niuma/ui 别名到 src/index.ts(评估整桶会灌入未使用组件 CSS)。
|
|
4
|
+
*
|
|
5
|
+
* 写法对齐 Vite / unplugin 惯例:工厂 + options、createFilter、
|
|
6
|
+
* es-module-lexer 定位静态 import/export、magic-string 保留 sourcemap、
|
|
7
|
+
* apply / configResolved 区分 serve 与 build。
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
import { createFilter } from '@rollup/pluginutils';
|
|
13
|
+
import { init, parse } from 'es-module-lexer';
|
|
14
|
+
import MagicString from 'magic-string';
|
|
15
|
+
const SPECIFIERS = new Set(['@niuma/ui', 'niuma-ui']);
|
|
16
|
+
/**
|
|
17
|
+
* NiumaUiHost 返回一组插件(Vite 会摊平)。serve 做 styles alias,两侧都改写具名导入。
|
|
18
|
+
*/
|
|
19
|
+
export function niumaUiHost(options = {}) {
|
|
20
|
+
const root = options.root ?? resolvePkgRoot();
|
|
21
|
+
const ctx = {
|
|
22
|
+
root,
|
|
23
|
+
hasSrc: existsSync(join(root, 'src/index.ts')),
|
|
24
|
+
useSource: false,
|
|
25
|
+
map: loadRuntimeBindings(root),
|
|
26
|
+
filter: createFilter(options.include ?? [/\.([cm]?[jt]sx?|vue)(?:$|\?)/], options.exclude ?? [/\/node_modules\//]),
|
|
27
|
+
};
|
|
28
|
+
return [niumaUiHostAlias(ctx), niumaUiHostRewrite(ctx)];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* NiumaUiHostAlias 仅在 serve 且存在 src 时把 styles.css 指到源码,并排除整桶预构建。
|
|
32
|
+
*/
|
|
33
|
+
function niumaUiHostAlias(ctx) {
|
|
34
|
+
return {
|
|
35
|
+
name: 'niuma-ui-host:alias',
|
|
36
|
+
apply: 'serve',
|
|
37
|
+
enforce: 'pre',
|
|
38
|
+
config() {
|
|
39
|
+
if (!ctx.hasSrc)
|
|
40
|
+
return {};
|
|
41
|
+
const styles = join(ctx.root, 'src/styles.css');
|
|
42
|
+
const alias = existsSync(styles)
|
|
43
|
+
? [
|
|
44
|
+
{ find: '@niuma/ui/styles.css', replacement: styles },
|
|
45
|
+
{ find: 'niuma-ui/styles.css', replacement: styles },
|
|
46
|
+
]
|
|
47
|
+
: [];
|
|
48
|
+
return {
|
|
49
|
+
resolve: alias.length > 0 ? { alias } : {},
|
|
50
|
+
optimizeDeps: {
|
|
51
|
+
exclude: ['@niuma/ui', 'niuma-ui'],
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* NiumaUiHostRewrite 把静态具名导入改到源码文件或 dist 子路径。
|
|
59
|
+
*/
|
|
60
|
+
function niumaUiHostRewrite(ctx) {
|
|
61
|
+
return {
|
|
62
|
+
name: 'niuma-ui-host:rewrite',
|
|
63
|
+
enforce: 'pre',
|
|
64
|
+
configResolved(config) {
|
|
65
|
+
ctx.useSource = config.command === 'serve' && ctx.hasSrc;
|
|
66
|
+
},
|
|
67
|
+
async transform(code, id) {
|
|
68
|
+
if (!ctx.filter(id))
|
|
69
|
+
return null;
|
|
70
|
+
if (!code.includes('@niuma/ui') && !code.includes('niuma-ui'))
|
|
71
|
+
return null;
|
|
72
|
+
await init;
|
|
73
|
+
const [imports] = parse(code);
|
|
74
|
+
const s = new MagicString(code);
|
|
75
|
+
let changed = false;
|
|
76
|
+
for (const im of imports) {
|
|
77
|
+
if (im.d !== -1)
|
|
78
|
+
continue;
|
|
79
|
+
const spec = im.n;
|
|
80
|
+
if (!spec || !SPECIFIERS.has(spec))
|
|
81
|
+
continue;
|
|
82
|
+
const stmt = code.slice(im.ss, im.se);
|
|
83
|
+
const next = rewriteHostStatement(stmt, spec, ctx.map, (from) => resolveTarget(from, spec, ctx.root, ctx.useSource));
|
|
84
|
+
if (next && next !== stmt) {
|
|
85
|
+
s.overwrite(im.ss, im.se, next);
|
|
86
|
+
changed = true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!changed)
|
|
90
|
+
return null;
|
|
91
|
+
return {
|
|
92
|
+
code: s.toString(),
|
|
93
|
+
map: s.generateMap({ hires: 'boundary', source: id }),
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* RewriteHostStatement 改写一条已由 lexer 切出的静态 import/export。
|
|
100
|
+
* 类型-only、namespace、动态 import 原样返回 null。
|
|
101
|
+
*/
|
|
102
|
+
export function rewriteHostStatement(stmt, spec, map, targetOf) {
|
|
103
|
+
const parsed = parseStaticImport(stmt);
|
|
104
|
+
if (!parsed)
|
|
105
|
+
return null;
|
|
106
|
+
const keyword = parsed.isExport ? 'export' : 'import';
|
|
107
|
+
const lines = [];
|
|
108
|
+
const types = [];
|
|
109
|
+
if (parsed.defaultName) {
|
|
110
|
+
const binding = map.get(parsed.defaultName);
|
|
111
|
+
if (!binding) {
|
|
112
|
+
lines.push(`${keyword} ${parsed.defaultName} from '${spec}'`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const target = targetOf(binding.from);
|
|
116
|
+
lines.push(emitBinding(keyword, binding.kind, parsed.defaultName, parsed.defaultName, target));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const part of parsed.named) {
|
|
120
|
+
if (part.isType) {
|
|
121
|
+
types.push(part.clause);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const binding = map.get(part.imported);
|
|
125
|
+
if (!binding) {
|
|
126
|
+
types.push(part.clause);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const target = targetOf(binding.from);
|
|
130
|
+
lines.push(emitBinding(keyword, binding.kind, part.imported, part.local, target));
|
|
131
|
+
}
|
|
132
|
+
if (types.length > 0) {
|
|
133
|
+
const kw = parsed.isExport ? 'export type' : 'import type';
|
|
134
|
+
lines.push(`${kw} { ${types.join(', ')} } from '${spec}'`);
|
|
135
|
+
}
|
|
136
|
+
return lines.length > 0 ? lines.join('\n') : null;
|
|
137
|
+
}
|
|
138
|
+
function emitBinding(keyword, kind, imported, local, target) {
|
|
139
|
+
if (kind === 'default') {
|
|
140
|
+
return `${keyword} { default as ${local} } from '${target}'`;
|
|
141
|
+
}
|
|
142
|
+
const inner = imported === local ? imported : `${imported} as ${local}`;
|
|
143
|
+
return `${keyword} { ${inner} } from '${target}'`;
|
|
144
|
+
}
|
|
145
|
+
function parseStaticImport(stmt) {
|
|
146
|
+
const lead = stmt.trimStart();
|
|
147
|
+
if (lead.startsWith('import type ') || lead.startsWith('export type '))
|
|
148
|
+
return null;
|
|
149
|
+
if (/\*\s+as\s+\w+/.test(stmt))
|
|
150
|
+
return null;
|
|
151
|
+
const isExport = lead.startsWith('export');
|
|
152
|
+
let defaultName;
|
|
153
|
+
if (!isExport) {
|
|
154
|
+
const m = lead.match(/^import\s+(\w+)\s*(?:,|from\b)/);
|
|
155
|
+
if (m?.[1] && m[1] !== 'type')
|
|
156
|
+
defaultName = m[1];
|
|
157
|
+
}
|
|
158
|
+
const named = [];
|
|
159
|
+
const open = stmt.indexOf('{');
|
|
160
|
+
if (open !== -1) {
|
|
161
|
+
const close = stmt.lastIndexOf('}');
|
|
162
|
+
if (close > open) {
|
|
163
|
+
for (const raw of stmt.slice(open + 1, close).split(',')) {
|
|
164
|
+
const part = raw.trim();
|
|
165
|
+
if (!part)
|
|
166
|
+
continue;
|
|
167
|
+
const typeOnly = /^type\s+/.test(part);
|
|
168
|
+
const body = typeOnly ? part.replace(/^type\s+/, '') : part;
|
|
169
|
+
const aliased = body.match(/^(\w+)(?:\s+as\s+(\w+))?$/);
|
|
170
|
+
if (!aliased?.[1])
|
|
171
|
+
continue;
|
|
172
|
+
named.push({
|
|
173
|
+
imported: aliased[1],
|
|
174
|
+
local: aliased[2] ?? aliased[1],
|
|
175
|
+
isType: typeOnly,
|
|
176
|
+
clause: body,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (!defaultName && named.length === 0)
|
|
182
|
+
return null;
|
|
183
|
+
return { isExport, defaultName, named };
|
|
184
|
+
}
|
|
185
|
+
function resolvePkgRoot() {
|
|
186
|
+
const require = createRequire(import.meta.url);
|
|
187
|
+
try {
|
|
188
|
+
return dirname(require.resolve('@niuma/ui/package.json'));
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return dirname(require.resolve('niuma-ui/package.json'));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function loadRuntimeBindings(root) {
|
|
195
|
+
const indexPath = existsSync(join(root, 'src/index.ts'))
|
|
196
|
+
? join(root, 'src/index.ts')
|
|
197
|
+
: join(root, 'dist/index.js');
|
|
198
|
+
const source = readFileSync(indexPath, 'utf8');
|
|
199
|
+
const map = new Map();
|
|
200
|
+
const re = /export\s*\{([^}]+)\}\s*from\s*['"](\.[^'"]+)['"]/g;
|
|
201
|
+
let match;
|
|
202
|
+
while ((match = re.exec(source)) !== null) {
|
|
203
|
+
const from = match[2] ?? '';
|
|
204
|
+
if (!from)
|
|
205
|
+
continue;
|
|
206
|
+
for (const raw of (match[1] ?? '').split(',')) {
|
|
207
|
+
const part = raw.trim();
|
|
208
|
+
if (!part || part.startsWith('type '))
|
|
209
|
+
continue;
|
|
210
|
+
const def = part.match(/^default\s+as\s+(\w+)$/);
|
|
211
|
+
if (def?.[1]) {
|
|
212
|
+
map.set(def[1], { from, kind: 'default' });
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const aliased = part.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
216
|
+
if (aliased?.[2]) {
|
|
217
|
+
map.set(aliased[2], { from, kind: 'named' });
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (/^\w+$/.test(part)) {
|
|
221
|
+
map.set(part, { from, kind: 'named' });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return map;
|
|
226
|
+
}
|
|
227
|
+
function resolveTarget(from, spec, root, useSource) {
|
|
228
|
+
if (!useSource)
|
|
229
|
+
return `${spec}/${toPublishedRel(from)}`;
|
|
230
|
+
const rel = from.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
231
|
+
let abs = join(root, 'src', rel);
|
|
232
|
+
if (!existsSync(abs)) {
|
|
233
|
+
if (existsSync(`${abs}.ts`))
|
|
234
|
+
abs = `${abs}.ts`;
|
|
235
|
+
else if (existsSync(`${abs}.js`))
|
|
236
|
+
abs = `${abs}.js`;
|
|
237
|
+
}
|
|
238
|
+
return toViteFsPath(abs);
|
|
239
|
+
}
|
|
240
|
+
function toPublishedRel(from) {
|
|
241
|
+
let rel = from.replace(/\\/g, '/');
|
|
242
|
+
rel = rel.replace(/^\.\//, '');
|
|
243
|
+
rel = rel.replace(/\.vue$/, '.js');
|
|
244
|
+
if (!rel.endsWith('.js') && !rel.endsWith('.css')) {
|
|
245
|
+
rel = `${rel}.js`;
|
|
246
|
+
}
|
|
247
|
+
return rel;
|
|
248
|
+
}
|
|
249
|
+
function toViteFsPath(abs) {
|
|
250
|
+
const posix = abs.replace(/\\/g, '/');
|
|
251
|
+
if (/^[A-Za-z]:\//.test(posix))
|
|
252
|
+
return `/${posix}`;
|
|
253
|
+
return posix;
|
|
254
|
+
}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
import type { Plugin } from 'vite';
|
|
2
1
|
/**
|
|
3
2
|
* 静默 antlr4ng ConsoleErrorListener 的 parse 刷屏。
|
|
4
3
|
*
|
|
5
|
-
* dt-sql-parser
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* 针对 antlr4ng(monaco-sql-languages / dt-sql-parser 依赖):
|
|
5
|
+
* createParser(input) 未传 errorListener 时不会 removeErrorListeners(),
|
|
6
|
+
* 半成品 SQL 的 syntaxError 会打满 DevTools。真实诊断走 Monaco markers。
|
|
7
|
+
* 该 console.error 模板随 antlr4ng 版本,升级后若失效需核对此字面量。
|
|
8
|
+
*/
|
|
9
|
+
import { type FilterPattern } from '@rollup/pluginutils';
|
|
10
|
+
import type { Plugin } from 'vite';
|
|
11
|
+
/** SilenceAntlrParseConsoleOptions 允许收窄要补丁的模块。 */
|
|
12
|
+
export type SilenceAntlrParseConsoleOptions = {
|
|
13
|
+
include?: FilterPattern;
|
|
14
|
+
exclude?: FilterPattern;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* SilenceAntlrParseConsole 去掉 antlr4ng ConsoleErrorListener 的 console.error。
|
|
8
18
|
*/
|
|
9
|
-
export declare function silenceAntlrParseConsole(): Plugin;
|
|
19
|
+
export declare function silenceAntlrParseConsole(options?: SilenceAntlrParseConsoleOptions): Plugin;
|
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 静默 antlr4ng ConsoleErrorListener 的 parse 刷屏。
|
|
3
3
|
*
|
|
4
|
-
* dt-sql-parser
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* 针对 antlr4ng(monaco-sql-languages / dt-sql-parser 依赖):
|
|
5
|
+
* createParser(input) 未传 errorListener 时不会 removeErrorListeners(),
|
|
6
|
+
* 半成品 SQL 的 syntaxError 会打满 DevTools。真实诊断走 Monaco markers。
|
|
7
|
+
* 该 console.error 模板随 antlr4ng 版本,升级后若失效需核对此字面量。
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
+
import { createFilter } from '@rollup/pluginutils';
|
|
10
|
+
import MagicString from 'magic-string';
|
|
11
|
+
const ANTLR_LINE_ERROR = /console\.error\("line " \+ line \+ ":" \+ charPositionInLine \+ " " \+ msg\);/g;
|
|
12
|
+
/**
|
|
13
|
+
* SilenceAntlrParseConsole 去掉 antlr4ng ConsoleErrorListener 的 console.error。
|
|
14
|
+
*/
|
|
15
|
+
export function silenceAntlrParseConsole(options = {}) {
|
|
16
|
+
const filter = createFilter(options.include ?? /antlr4ng/, options.exclude);
|
|
9
17
|
return {
|
|
10
18
|
name: 'silence-antlr-parse-console',
|
|
11
19
|
enforce: 'pre',
|
|
12
20
|
transform(code, id) {
|
|
13
|
-
|
|
14
|
-
if (!normalized.includes('antlr4ng'))
|
|
21
|
+
if (!filter(id))
|
|
15
22
|
return null;
|
|
16
23
|
if (!code.includes('ConsoleErrorListener'))
|
|
17
24
|
return null;
|
|
18
25
|
if (!code.includes('console.error("line "'))
|
|
19
26
|
return null;
|
|
27
|
+
const s = new MagicString(code);
|
|
28
|
+
s.replace(ANTLR_LINE_ERROR, '/* niuma-ui: antlr4ng ConsoleErrorListener; diagnostics via Monaco markers */');
|
|
20
29
|
return {
|
|
21
|
-
code:
|
|
22
|
-
map:
|
|
30
|
+
code: s.toString(),
|
|
31
|
+
map: s.generateMap({ hires: 'boundary', source: id }),
|
|
23
32
|
};
|
|
24
33
|
},
|
|
25
34
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "niuma-ui",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Vue 3 工作台设计系统(Rs* 组件、--rs-* token;含可选编辑器 / 终端)",
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
"default": "./dist/index.js"
|
|
38
38
|
},
|
|
39
39
|
"./styles.css": "./dist/styles.css",
|
|
40
|
+
"./components/*": "./dist/components/*",
|
|
41
|
+
"./composables/*": "./dist/composables/*",
|
|
42
|
+
"./theme/*": "./dist/theme/*",
|
|
43
|
+
"./monaco/*": "./dist/monaco/*",
|
|
44
|
+
"./utils/*": "./dist/utils/*",
|
|
45
|
+
"./locale/*": "./dist/locale/*",
|
|
40
46
|
"./theme/brand.example.css": "./dist/theme/brand.example.css",
|
|
41
47
|
"./vite-plugins/monaco-zh-nls": {
|
|
42
48
|
"types": "./dist/vite-plugins/monaco-zh-nls.d.ts",
|
|
@@ -48,6 +54,16 @@
|
|
|
48
54
|
"import": "./dist/vite-plugins/silence-antlr-parse-console.js",
|
|
49
55
|
"default": "./dist/vite-plugins/silence-antlr-parse-console.js"
|
|
50
56
|
},
|
|
57
|
+
"./vite-plugins/niuma-ui-host": {
|
|
58
|
+
"types": "./dist/vite-plugins/niuma-ui-host.d.ts",
|
|
59
|
+
"import": "./dist/vite-plugins/niuma-ui-host.js",
|
|
60
|
+
"default": "./dist/vite-plugins/niuma-ui-host.js"
|
|
61
|
+
},
|
|
62
|
+
"./vite-plugins/rewrite-named-imports": {
|
|
63
|
+
"types": "./dist/vite-plugins/rewrite-named-imports.d.ts",
|
|
64
|
+
"import": "./dist/vite-plugins/rewrite-named-imports.js",
|
|
65
|
+
"default": "./dist/vite-plugins/rewrite-named-imports.js"
|
|
66
|
+
},
|
|
51
67
|
"./vite-prebundle/codemirror": "./dist/dev/vite-codemirror-deps.js",
|
|
52
68
|
"./vite-prebundle/xterm": "./dist/dev/vite-xterm-deps.js",
|
|
53
69
|
"./package.json": "./package.json"
|
|
@@ -102,7 +118,11 @@
|
|
|
102
118
|
"marked": "^18.0.9",
|
|
103
119
|
"monaco-editor": "^0.55.1",
|
|
104
120
|
"monaco-sql-languages": "^1.2.0",
|
|
121
|
+
"@rollup/pluginutils": "^5.3.0",
|
|
122
|
+
"es-module-lexer": "^1.7.0",
|
|
123
|
+
"magic-string": "^0.30.17",
|
|
105
124
|
"reka-ui": "^2.9.10",
|
|
125
|
+
"tailwindcss": "^4.3.2",
|
|
106
126
|
"vue-sonner": "^2.0.9"
|
|
107
127
|
},
|
|
108
128
|
"devDependencies": {
|
|
@@ -113,7 +133,6 @@
|
|
|
113
133
|
"@vue/server-renderer": "^3.5.39",
|
|
114
134
|
"@vue/test-utils": "^2.4.11",
|
|
115
135
|
"jsdom": "^29.1.1",
|
|
116
|
-
"tailwindcss": "^4.3.2",
|
|
117
136
|
"typescript": "^5.9.3",
|
|
118
137
|
"vite": "^8.1.3",
|
|
119
138
|
"vitest": "^4.1.9",
|