@love-sqjm/magic 2026.4.15
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 +674 -0
- package/README.md +93 -0
- package/app.js +51 -0
- package/doc/api/examples.md +563 -0
- package/doc/api/index.md +563 -0
- package/doc/architecture.md +322 -0
- package/doc/config-reference.md +646 -0
- package/doc/data-model.md +622 -0
- package/doc/development-guide.md +582 -0
- package/doc/magic-file/index.md +610 -0
- package/doc/user-guide/index.md +485 -0
- package/doc/workflow.md +548 -0
- package/index.js +157 -0
- package/magic.bat +2 -0
- package/magic.ps1 +5 -0
- package/package.json +44 -0
- package/script/build-project.js +16 -0
- package/script/config.js +23 -0
- package/script/create-project.js +73 -0
- package/script/global/printf.js +13 -0
- package/script/global/project-build-config.js +161 -0
- package/script/global/support-platform.js +5 -0
- package/script/module/compiler/global.js +43 -0
- package/script/module/compiler/id-generate.js +18 -0
- package/script/module/compiler/index-dom.js +78 -0
- package/script/module/compiler/macro-replace.js +22 -0
- package/script/module/compiler/macro.js +6 -0
- package/script/module/compiler/start.js +10 -0
- package/script/module/compiler/step/1.js +253 -0
- package/script/module/compiler/step/2.js +79 -0
- package/script/module/compiler/step/3.js +37 -0
- package/script/module/compiler/step/4.js +20 -0
- package/script/module/compiler/step/5.js +634 -0
- package/script/module/compiler/step/6.js +304 -0
- package/script/module/compiler/step/end.js +124 -0
- package/script/run-project.js +249 -0
- package/script/util/bun-fs.js +40 -0
- package/script/util/copy-dir.js +21 -0
- package/script/util/create-simple-dom-element.js +23 -0
- package/script/util/file-util.js +95 -0
- package/script/util/filtration-file.js +20 -0
- package/script/util/get-dir-all-file.js +28 -0
- package/script/util/get-first-object-key.js +9 -0
- package/script/util/is-empty-object.js +8 -0
- package/script/util/is-string-over-size.js +4 -0
- package/script/util/is.js +18 -0
- package/script/util/logging.js +142 -0
- package/script/util/task.js +16 -0
- package/script/util/traversal.js +28 -0
- package/template/platform-config/node-webkit +23 -0
- package/template/platform-config/web +1 -0
- package/template/project-base/app.xml +5 -0
- package/template/project-base/build.module.toml +37 -0
- package/template/project-base/build.toml +43 -0
- package/template/runtime/runtime.css +3 -0
- package/template/runtime/runtime.js +895 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Magic 框架技术架构
|
|
2
|
+
|
|
3
|
+
## 1. 系统概述
|
|
4
|
+
|
|
5
|
+
Magic 是一个基于 Bun.js 的全栈 Web 开发框架,采用命令行工具 + 编译器的架构设计。框架核心是一个自定义的 `.m` 文件编译器,将声明式的组件文件编译为标准 JavaScript 和 CSS。
|
|
6
|
+
|
|
7
|
+
## 2. 整体架构
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ CLI 层 │
|
|
12
|
+
│ (index.js / commander.js) │
|
|
13
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
14
|
+
│
|
|
15
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
16
|
+
│ 核心业务层 │
|
|
17
|
+
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
18
|
+
│ │ create-project│ │ build-project │ │ run-project │ │
|
|
19
|
+
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
20
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
21
|
+
│
|
|
22
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
23
|
+
│ 编译器层 │
|
|
24
|
+
│ ┌──────────────────────────────────────────────────────┐ │
|
|
25
|
+
│ │ Compiler Pipeline │ │
|
|
26
|
+
│ │ Step1 → Step2 → Step3 → Step4 → Step5 → Step6 → End │ │
|
|
27
|
+
│ └──────────────────────────────────────────────────────┘ │
|
|
28
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
29
|
+
│
|
|
30
|
+
┌─────────────────────────▼───────────────────────────────────┐
|
|
31
|
+
│ 运行时层 │
|
|
32
|
+
│ (runtime.js / runtime.css) │
|
|
33
|
+
└─────────────────────────────────────────────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 3. 目录结构
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
magic/
|
|
40
|
+
├── index.js # CLI 入口
|
|
41
|
+
├── app.js # 全局配置
|
|
42
|
+
├── package.json # 依赖配置
|
|
43
|
+
│
|
|
44
|
+
├── script/ # 核心业务逻辑
|
|
45
|
+
│ ├── global/ # 全局工具
|
|
46
|
+
│ │ ├── printf.js # 日志系统
|
|
47
|
+
│ │ ├── project-build-config.js # 配置校验
|
|
48
|
+
│ │ └── support-platform.js # 平台列表
|
|
49
|
+
│ │
|
|
50
|
+
│ ├── module/ # 功能模块
|
|
51
|
+
│ │ └── compiler/ # 编译器
|
|
52
|
+
│ │ ├── start.js # 编译入口
|
|
53
|
+
│ │ ├── global.js # 编译状态
|
|
54
|
+
│ │ ├── macro.js # 宏定义
|
|
55
|
+
│ │ ├── macro-replace.js # 宏替换
|
|
56
|
+
│ │ ├── index-dom.js # HTML 生成
|
|
57
|
+
│ │ ├── id-generate.js # ID 生成
|
|
58
|
+
│ │ └── step/ # 编译步骤
|
|
59
|
+
│ │ ├── 1.js # 配置解析
|
|
60
|
+
│ │ ├── 2.js # 文件扫描
|
|
61
|
+
│ │ ├── 3.js # 目录初始化
|
|
62
|
+
│ │ ├── 4.js # 文件分类
|
|
63
|
+
│ │ ├── 5.js # 核心编译
|
|
64
|
+
│ │ ├── 6.js # 代码生成
|
|
65
|
+
│ │ └── end.js # 压缩输出
|
|
66
|
+
│ │
|
|
67
|
+
│ ├── util/ # 工具函数
|
|
68
|
+
│ │ ├── task.js # 任务包装
|
|
69
|
+
│ │ ├── logging.js # 日志类
|
|
70
|
+
│ │ ├── file-util.js # 文件操作
|
|
71
|
+
│ │ ├── filtration-file.js # 文件过滤
|
|
72
|
+
│ │ ├── copy-dir.js # 目录复制
|
|
73
|
+
│ │ ├── traversal.js # 对象遍历
|
|
74
|
+
│ │ └── ...
|
|
75
|
+
│ │
|
|
76
|
+
│ ├── build-project.js # 构建逻辑
|
|
77
|
+
│ ├── create-project.js # 创建逻辑
|
|
78
|
+
│ ├── run-project.js # 运行逻辑
|
|
79
|
+
│ └── config.js # 运行配置
|
|
80
|
+
│
|
|
81
|
+
├── template/ # 项目模板
|
|
82
|
+
│ ├── platform-config/ # 平台配置
|
|
83
|
+
│ │ ├── web
|
|
84
|
+
│ │ └── node-webkit
|
|
85
|
+
│ ├── project-base/ # 项目基础
|
|
86
|
+
│ │ ├── build.toml
|
|
87
|
+
│ │ ├── build.module.toml
|
|
88
|
+
│ │ └── app.xml
|
|
89
|
+
│ └── runtime/ # 运行时文件
|
|
90
|
+
│ ├── runtime.js
|
|
91
|
+
│ └── runtime.css
|
|
92
|
+
│
|
|
93
|
+
└── doc/ # 文档
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 4. 核心模块详解
|
|
97
|
+
|
|
98
|
+
### 4.1 CLI 入口 (index.js)
|
|
99
|
+
|
|
100
|
+
负责命令行参数解析和命令分发。
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// 可用命令
|
|
104
|
+
magic init [name] --web // 创建 Web 项目
|
|
105
|
+
magic init [name] --node-webkit // 创建桌面项目
|
|
106
|
+
magic init [name] --module // 创建模块项目
|
|
107
|
+
magic build // 构建项目
|
|
108
|
+
magic run // 运行项目
|
|
109
|
+
magic build-run // 构建并运行
|
|
110
|
+
magic create-m [filename] // 创建组件文件 (.m)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 4.2 项目创建 (create-project.js)
|
|
114
|
+
|
|
115
|
+
- 读取平台配置模板
|
|
116
|
+
- 创建项目目录结构
|
|
117
|
+
- 生成 `build.toml` 和 `app.xml`
|
|
118
|
+
|
|
119
|
+
### 4.3 项目构建 (build-project.js)
|
|
120
|
+
|
|
121
|
+
调用编译器流水线处理源码。
|
|
122
|
+
|
|
123
|
+
### 4.4 编译器流水线
|
|
124
|
+
|
|
125
|
+
#### Step 1: 配置解析 (step/1.js)
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
examine_BuildConfig() // 校验 build.toml
|
|
129
|
+
examine_AppConfig() // 解析 app.xml
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Step 2: 文件扫描 (step/2.js)
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
source_file = {
|
|
136
|
+
".m": [source, source, ...],
|
|
137
|
+
".css": [source, ...],
|
|
138
|
+
".js": [...],
|
|
139
|
+
"*it": () => [...] // 迭代所有文件
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Step 3: 目录初始化 (step/3.js)
|
|
144
|
+
|
|
145
|
+
- 清空并创建输出目录
|
|
146
|
+
- 复制 runtime 文件
|
|
147
|
+
|
|
148
|
+
#### Step 4: 文件分类 (step/4.js)
|
|
149
|
+
|
|
150
|
+
- `.m` 文件收集到数组待处理
|
|
151
|
+
- 其他文件直接复制到输出目录
|
|
152
|
+
|
|
153
|
+
#### Step 5: 核心编译 (step/5.js)
|
|
154
|
+
|
|
155
|
+
`.m` 文件解析的关键处理:
|
|
156
|
+
|
|
157
|
+
| 标签 | 处理内容 |
|
|
158
|
+
|------|----------|
|
|
159
|
+
| `<import>` | 模块导入解析 |
|
|
160
|
+
| `<template>` | DOM 模板解析 |
|
|
161
|
+
| `<script>` | 脚本分类编译 |
|
|
162
|
+
| `<css>` | CSS 作用域处理 |
|
|
163
|
+
| `<expose-event>` | 事件暴露定义 |
|
|
164
|
+
|
|
165
|
+
#### Step 6: 代码生成 (step/6.js)
|
|
166
|
+
|
|
167
|
+
- 生成独立的 `.js` 和 `.css` 文件
|
|
168
|
+
- 处理模块导入
|
|
169
|
+
- Debug/Release 模式分别处理
|
|
170
|
+
|
|
171
|
+
#### End: 压缩输出 (step/end.js)
|
|
172
|
+
|
|
173
|
+
- HTML/JS/CSS 压缩
|
|
174
|
+
- CSS Autoprefixer 处理
|
|
175
|
+
- 生成最终 `index.html`
|
|
176
|
+
|
|
177
|
+
### 4.5 项目运行 (run-project.js)
|
|
178
|
+
|
|
179
|
+
| 平台 | 处理方式 |
|
|
180
|
+
|------|----------|
|
|
181
|
+
| web (server) | 启动 HTTP 服务器 + WebSocket 热更新 |
|
|
182
|
+
| web (browser) | 直接打开浏览器 |
|
|
183
|
+
| node-webkit | 调用 NW.js 启动 |
|
|
184
|
+
|
|
185
|
+
## 5. 数据流
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
源码 (.m)
|
|
189
|
+
│
|
|
190
|
+
▼
|
|
191
|
+
┌─────────┐
|
|
192
|
+
│ Step 1 │ ← build.toml / app.xml
|
|
193
|
+
└────┬────┘
|
|
194
|
+
▼
|
|
195
|
+
┌─────────┐
|
|
196
|
+
│ Step 2 │ ← 文件扫描过滤
|
|
197
|
+
└────┬────┘
|
|
198
|
+
▼
|
|
199
|
+
┌─────────┐
|
|
200
|
+
│ Step 3 │ ← 初始化输出目录
|
|
201
|
+
└────┬────┘
|
|
202
|
+
▼
|
|
203
|
+
┌─────────┐
|
|
204
|
+
│ Step 4 │ ← 分离 .m 文件
|
|
205
|
+
└────┬────┘
|
|
206
|
+
▼
|
|
207
|
+
┌─────────┐
|
|
208
|
+
│ Step 5 │ ← AST 解析 + 宏处理 + 代码转换
|
|
209
|
+
└────┬────┘
|
|
210
|
+
▼
|
|
211
|
+
┌─────────┐
|
|
212
|
+
│ Step 6 │ ← 生成 .js / .css
|
|
213
|
+
└────┬────┘
|
|
214
|
+
▼
|
|
215
|
+
┌─────────┐
|
|
216
|
+
│ End │ ← 压缩 + 输出 index.html
|
|
217
|
+
└────┬────┘
|
|
218
|
+
▼
|
|
219
|
+
输出目录
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## 6. 关键技术点
|
|
223
|
+
|
|
224
|
+
### 6.1 Babel AST 转换
|
|
225
|
+
|
|
226
|
+
编译器使用 Babel 生态进行 JavaScript 代码转换:
|
|
227
|
+
|
|
228
|
+
- `@babel/parser` - 解析源码为 AST
|
|
229
|
+
- `@babel/traverse` - 遍历和修改 AST
|
|
230
|
+
- `@babel/generator` - 将 AST 转换回代码
|
|
231
|
+
- `@babel/types` - 构建和操作 AST 节点
|
|
232
|
+
|
|
233
|
+
### 6.2 CSS 作用域
|
|
234
|
+
|
|
235
|
+
Magic 使用特有的 `#id:xx` 选择器实现样式作用域:
|
|
236
|
+
|
|
237
|
+
```css
|
|
238
|
+
/* 源码 */
|
|
239
|
+
<css scope="#id:myComponent">
|
|
240
|
+
div { color: red; }
|
|
241
|
+
</css>
|
|
242
|
+
|
|
243
|
+
/* 编译后 */
|
|
244
|
+
.m-css-scope-abc123 div { color: red; }
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 6.3 宏系统
|
|
248
|
+
|
|
249
|
+
编译时宏在 Step 5 中通过 Babel 插件处理:
|
|
250
|
+
|
|
251
|
+
| 宏 | 功能 |
|
|
252
|
+
|----|------|
|
|
253
|
+
| `magic_define_include` | 文件内容替换 |
|
|
254
|
+
| `magic_define_ui_data` | 创建 UiData 对象 |
|
|
255
|
+
| `magic_dynamic_value_bind` | 动态值绑定 |
|
|
256
|
+
|
|
257
|
+
### 6.4 模块导入
|
|
258
|
+
|
|
259
|
+
模块通过 `importM()` 函数在运行时加载:
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
// 定义模块 (编译后)
|
|
263
|
+
window["__MAGIC__"]["M"]["uisharengcsettingdialog"] = function(...) {...}
|
|
264
|
+
|
|
265
|
+
// 导入模块 (运行时)
|
|
266
|
+
const dialog = magic.importM("ui/share/ngc-setting-dialog");
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## 7. 配置校验机制
|
|
270
|
+
|
|
271
|
+
使用 `Type` 类定义配置项约束:
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
const Type = class {
|
|
275
|
+
constructor(type, key = true, scope)
|
|
276
|
+
getScope() // 获取枚举范围
|
|
277
|
+
getType() // 获取类型
|
|
278
|
+
isKey() // 是否必需
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
`ProjectBuildConfigContrast()` 对比校验配置合法性。
|
|
283
|
+
|
|
284
|
+
## 8. 扩展性设计
|
|
285
|
+
|
|
286
|
+
### 8.1 平台扩展
|
|
287
|
+
|
|
288
|
+
在 `template/platform-config/` 添加新平台配置即可扩展。
|
|
289
|
+
|
|
290
|
+
### 8.2 编译器扩展
|
|
291
|
+
|
|
292
|
+
在 `step/` 目录添加新的编译步骤文件。
|
|
293
|
+
|
|
294
|
+
### 8.3 宏扩展
|
|
295
|
+
|
|
296
|
+
在 `step/5.js` 的 `pretreatmentMagicMacro()` 中添加新的宏处理逻辑。
|
|
297
|
+
|
|
298
|
+
## 9. 性能考虑
|
|
299
|
+
|
|
300
|
+
- Step 5 中多个 `.m` 文件并行处理
|
|
301
|
+
- CSS/JS 代码分块输出 (默认 1MB/块)
|
|
302
|
+
- 文件变化通过 WebSocket 轮询检测
|
|
303
|
+
|
|
304
|
+
## 10. 依赖关系图
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
index.js
|
|
308
|
+
├── commander
|
|
309
|
+
├── app.js
|
|
310
|
+
├── build-project.js → compiler/*
|
|
311
|
+
├── create-project.js → app.js
|
|
312
|
+
└── run-project.js → app.js, ws
|
|
313
|
+
|
|
314
|
+
compiler/*
|
|
315
|
+
├── step/1.js → app.js, babel/parser
|
|
316
|
+
├── step/2.js → app.js, fast-glob
|
|
317
|
+
├── step/3.js → app.js
|
|
318
|
+
├── step/4.js
|
|
319
|
+
├── step/5.js → babel/*, postcss, node-html-parser
|
|
320
|
+
├── step/6.js → app.js, terser
|
|
321
|
+
└── end.js → terser, html-minifier, postcss, autoprefixer
|
|
322
|
+
```
|