@vitarx/plugin-vite 1.0.0 → 1.0.2-alpha.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.
Files changed (34) hide show
  1. package/dist/hmr-client/index.d.ts +15 -5
  2. package/dist/hmr-client/index.js +47 -25
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +2 -6
  5. package/dist/passes/hmr/inject-imports.d.ts +4 -1
  6. package/dist/passes/hmr/inject-imports.js +8 -1
  7. package/dist/passes/hmr/inject-state.d.ts +6 -1
  8. package/dist/passes/hmr/inject-state.js +58 -5
  9. package/dist/passes/hmr/inject.d.ts +1 -1
  10. package/dist/passes/hmr/inject.js +27 -2
  11. package/dist/passes/imports/collectImports.d.ts +4 -4
  12. package/dist/passes/imports/collectImports.js +20 -5
  13. package/dist/passes/imports/collectRefVariables.d.ts +2 -2
  14. package/dist/passes/imports/collectRefVariables.js +47 -3
  15. package/dist/passes/imports/injectImports.d.ts +1 -0
  16. package/dist/passes/imports/injectImports.js +28 -2
  17. package/dist/transform.js +11 -1
  18. package/dist/utils/ast-builders.d.ts +49 -41
  19. package/dist/utils/ast-builders.js +60 -41
  20. package/dist/utils/ast-guards.d.ts +2 -1
  21. package/dist/utils/ast-guards.js +4 -1
  22. package/dist/utils/collect-names.d.ts +13 -4
  23. package/dist/utils/collect-names.js +38 -4
  24. package/dist/utils/component-collect.d.ts +4 -2
  25. package/dist/utils/component-collect.js +181 -6
  26. package/dist/utils/generate.d.ts +3 -0
  27. package/dist/utils/generate.js +4 -0
  28. package/dist/utils/jsx-helpers.d.ts +14 -0
  29. package/dist/utils/jsx-helpers.js +21 -0
  30. package/dist/utils/pattern-helpers.d.ts +4 -4
  31. package/dist/utils/pattern-helpers.js +13 -4
  32. package/dist/utils/vif-helpers.d.ts +8 -0
  33. package/dist/utils/vif-helpers.js +36 -0
  34. package/package.json +2 -2
@@ -1,78 +1,91 @@
1
1
  /**
2
2
  * AST 节点构建函数
3
+ * 提供各类运行时 API 调用的创建辅助函数
3
4
  * @module utils/ast-builders
4
5
  */
5
6
  import * as t from '@babel/types';
6
7
  import { isIdentifier } from '@babel/types';
7
8
  import { PURE_COMMENT } from '../constants/index.js';
8
9
  /**
9
- * 创建 unref 调用
10
- * @param argument - 参数表达式
11
- * @param alias - unref 别名
12
- * @returns CallExpression
10
+ * 创建 unref 调用表达式
11
+ * @param argument - 需要解包的表达式
12
+ * @param alias - unref 的本地别名
13
+ * @returns unref(arg) 调用表达式
13
14
  */
14
15
  export function createUnrefCall(argument, alias) {
16
+ // 使用别名或默认名称创建标识符
15
17
  return t.callExpression(t.identifier(alias || 'unref'), [argument]);
16
18
  }
17
19
  /**
18
- * 创建 accessor 调用
20
+ * 创建 accessor 调用表达式
21
+ * 用于细粒度响应式追踪,只追踪对象的特定属性
19
22
  * @param object - 对象表达式
20
- * @param key - 键表达式
21
- * @param alias - accessor 别名
22
- * @returns CallExpression
23
+ * @param key - 属性键表达式
24
+ * @param alias - accessor 的本地别名
25
+ * @returns accessor(obj, key) 调用表达式
23
26
  */
24
27
  export function createAccessorCall(object, key, alias) {
28
+ // 如果键是标识符,转换为字符串字面量;否则保持原样
25
29
  const keyArg = isIdentifier(key) ? t.stringLiteral(key.name) : key;
26
30
  return t.callExpression(t.identifier(alias || 'accessor'), [object, keyArg]);
27
31
  }
28
32
  /**
29
- * 创建 expr 调用
30
- * @param argument - 参数表达式
31
- * @param alias - expr 别名
32
- * @returns CallExpression
33
+ * 创建 expr 调用表达式
34
+ * 用于粗粒度响应式追踪,包装任意表达式
35
+ * @param argument - 需要包装的表达式
36
+ * @param alias - expr 的本地别名
37
+ * @returns expr(() => arg) 调用表达式
33
38
  */
34
39
  export function createExprCall(argument, alias) {
40
+ // 将表达式包装在箭头函数中传递给 expr
35
41
  return t.callExpression(t.identifier(alias || 'expr'), [t.arrowFunctionExpression([], argument)]);
36
42
  }
37
43
  /**
38
- * 创建 branch 调用
39
- * @param condition - 条件函数
44
+ * 创建 branch 调用表达式
45
+ * 用于条件分支渲染,支持多分支选择
46
+ * @param condition - 返回分支索引的箭头函数
40
47
  * @param branches - 分支函数数组
41
- * @param alias - branch 别名
42
- * @returns CallExpression
48
+ * @param alias - branch 的本地别名
49
+ * @returns branch(condition, [branches]) 调用表达式
43
50
  */
44
51
  export function createBranchCall(condition, branches, alias) {
45
52
  return t.callExpression(t.identifier(alias || 'branch'), [condition, t.arrayExpression(branches)]);
46
53
  }
47
54
  /**
48
- * 创建 createView 调用
49
- * @param type - 元素类型
50
- * @param props - props 对象
51
- * @param locInfo - 位置信息对象
52
- * @param alias - createView 别名
53
- * @returns CallExpression
55
+ * 创建 createView 调用表达式
56
+ * 这是核心的视图创建函数,将 JSX 转换为运行时调用
57
+ * @param type - 元素类型(字符串表示原生元素,标识符表示组件)
58
+ * @param props - 属性对象表达式
59
+ * @param locInfo - 开发环境下的位置信息(用于错误定位)
60
+ * @param alias - createView 的本地别名
61
+ * @returns createView(type, props?, locInfo?) 调用表达式
54
62
  */
55
63
  export function createCreateViewCall(type, props, locInfo, alias) {
56
64
  const args = [type];
65
+ // 根据参数情况构建调用参数
57
66
  if (props) {
58
67
  args.push(props);
59
68
  }
60
69
  else if (locInfo) {
70
+ // 有位置信息但无 props 时,props 位置传 null
61
71
  args.push(t.nullLiteral());
62
72
  }
73
+ // 添加位置信息(仅开发环境)
63
74
  if (locInfo) {
64
75
  args.push(locInfo);
65
76
  }
66
77
  return t.callExpression(t.identifier(alias || 'createView'), args);
67
78
  }
68
79
  /**
69
- * 创建 withDirectives 调用
70
- * @param view - 视图节点
71
- * @param directives - 指令数组,每项为 [指令名, 指令值]
72
- * @param alias - withDirectives 别名
73
- * @returns CallExpression
80
+ * 创建 withDirectives 调用表达式
81
+ * 用于为视图节点添加自定义指令
82
+ * @param view - 视图节点表达式
83
+ * @param directives - 指令数组,每项为 [指令名, 指令值] 元组
84
+ * @param alias - withDirectives 的本地别名
85
+ * @returns withDirectives(view, [[name, value], ...]) 调用表达式
74
86
  */
75
87
  export function createWithDirectivesCall(view, directives, alias) {
88
+ // 将指令数组转换为嵌套数组表达式
76
89
  const directiveArray = directives.map(([name, value]) => {
77
90
  return t.arrayExpression([t.stringLiteral(name), value]);
78
91
  });
@@ -82,56 +95,62 @@ export function createWithDirectivesCall(view, directives, alias) {
82
95
  ]);
83
96
  }
84
97
  /**
85
- * 创建箭头函数
98
+ * 创建无参数箭头函数
86
99
  * @param body - 函数体表达式
87
- * @returns ArrowFunctionExpression
100
+ * @returns () => body 箭头函数表达式
88
101
  */
89
102
  export function createArrowFunction(body) {
90
103
  return t.arrowFunctionExpression([], body);
91
104
  }
92
105
  /**
93
106
  * 为调用表达式添加 @__PURE__ 注释
107
+ * 标记纯函数调用,帮助 Tree Shaking 优化
94
108
  * @param node - 调用表达式节点
95
- * @param ctx - 转换上下文
96
- * @returns 添加注释后的节点
109
+ * @param ctx - 转换上下文(用于去重)
110
+ * @returns 添加注释后的节点(可能是原节点)
97
111
  */
98
112
  export function addPureComment(node, ctx) {
113
+ // 避免重复添加注释
99
114
  if (ctx.pureCommentedNodes.has(node)) {
100
115
  return node;
101
116
  }
102
117
  ctx.pureCommentedNodes.add(node);
118
+ // 在节点前添加注释
103
119
  t.addComment(node, 'leading', ` ${PURE_COMMENT} `, false);
104
120
  return node;
105
121
  }
106
122
  /**
107
- * 获取 API 别名
108
- * @param aliases - 别名映射
109
- * @param name - API 名称
110
- * @returns 别名或原名
123
+ * 获取 API 的本地别名
124
+ * @param aliases - 别名映射对象
125
+ * @param name - API 原始名称
126
+ * @returns 本地别名或原始名称
111
127
  */
112
128
  export function getAlias(aliases, name) {
113
129
  return aliases[name] || name;
114
130
  }
115
131
  /**
116
- * 创建位置信息对象
117
- * @param filename - 文件名
118
- * @param loc - 源码位置
119
- * @returns ObjectExpression
132
+ * 创建源码位置信息对象
133
+ * 用于开发环境下的错误定位
134
+ * @param filename - 当前文件名
135
+ * @param loc - 源码位置信息
136
+ * @returns 位置信息对象 { fileName, lineNumber, columnNumber }
120
137
  */
121
138
  export function createLocationObject(filename, loc) {
122
139
  return t.objectExpression([
123
140
  t.objectProperty(t.identifier('fileName'), t.stringLiteral(filename)),
124
141
  t.objectProperty(t.identifier('lineNumber'), t.numericLiteral(loc.start.line)),
142
+ // 列号从 1 开始(与编辑器一致)
125
143
  t.objectProperty(t.identifier('columnNumber'), t.numericLiteral(loc.start.column + 1))
126
144
  ]);
127
145
  }
128
146
  /**
129
147
  * 获取开发环境下的位置信息对象
130
- * 仅在开发环境下返回位置信息,生产环境返回 null
148
+ * 仅在开发模式且节点有位置信息时返回
131
149
  * @param ctx - 转换上下文
132
- * @param node - AST 节点或位置信息
150
+ * @param node - AST 节点或包含 loc 属性的对象
133
151
  * @returns 位置信息对象或 null
134
152
  */
135
153
  export function getDevLocInfo(ctx, node) {
154
+ // 仅开发模式且有位置信息时创建
136
155
  return ctx.options.dev && node.loc ? createLocationObject(ctx.filename, node.loc) : null;
137
156
  }
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * AST 类型守卫函数
3
- * 用于判断节点类型
3
+ * 用于判断节点类型和属性
4
4
  * @module utils/ast-guards
5
5
  */
6
6
  import { type Node } from '@babel/types';
7
7
  /**
8
8
  * 判断 JSXText 是否为纯空白文本
9
+ * 空白文本在渲染时通常需要被过滤掉
9
10
  * @param node - AST 节点
10
11
  * @returns 是否为纯空白文本
11
12
  */
@@ -1,16 +1,19 @@
1
1
  /**
2
2
  * AST 类型守卫函数
3
- * 用于判断节点类型
3
+ * 用于判断节点类型和属性
4
4
  * @module utils/ast-guards
5
5
  */
6
6
  import { isJSXText } from '@babel/types';
7
7
  /**
8
8
  * 判断 JSXText 是否为纯空白文本
9
+ * 空白文本在渲染时通常需要被过滤掉
9
10
  * @param node - AST 节点
10
11
  * @returns 是否为纯空白文本
11
12
  */
12
13
  export function isWhitespaceJSXText(node) {
14
+ // 先判断是否为 JSXText 类型
13
15
  if (!isJSXText(node))
14
16
  return false;
17
+ // 使用正则表达式判断是否只包含空白字符
15
18
  return /^\s*$/.test(node.value);
16
19
  }
@@ -5,24 +5,33 @@
5
5
  */
6
6
  import type * as t from '@babel/types';
7
7
  /**
8
- * 从命名导出中收集名称
8
+ * 从命名导出声明中收集名称
9
+ * @param node - 命名导出声明节点
10
+ * @param names - 存储名称的集合
9
11
  */
10
12
  export declare function collectFromNamedExport(node: t.ExportNamedDeclaration, names: Set<string>): void;
11
13
  /**
12
- * 从默认导出中收集名称
14
+ * 从默认导出声明中收集名称
15
+ * @param node - 默认导出声明节点
16
+ * @param names - 存储名称的集合
13
17
  */
14
18
  export declare function collectFromDefaultExport(node: t.ExportDefaultDeclaration, names: Set<string>): void;
15
19
  /**
16
20
  * 收集所有导出的标识符名称
21
+ * @param program - AST Program 节点
22
+ * @returns 导出名称集合
17
23
  */
18
24
  export declare function collectExportedNames(program: t.Program): Set<string>;
19
25
  /**
20
26
  * 收集模块中所有绑定的名称(用于避免命名冲突)
27
+ * 包括函数声明、变量声明、导入声明和导出声明
28
+ * @param program - AST Program 节点
29
+ * @returns 所有绑定名称集合
21
30
  */
22
31
  export declare function collectAllBindingNames(program: t.Program): Set<string>;
23
32
  /**
24
33
  * 判断调用表达式是否是 builder 调用
25
- * @param callExpr - 调用表达式
34
+ * @param callExpr - 调用表达式节点
26
35
  * @param builderAlias - builder 的本地别名
27
36
  * @returns 是否是 builder 调用
28
37
  */
@@ -32,6 +41,6 @@ export declare function isBuilderCall(callExpr: t.CallExpression, builderAlias:
32
41
  * 检测 builder(Comp) 或 builder(Comp, options) 形式的调用
33
42
  * @param program - AST Program 节点
34
43
  * @param builderAlias - builder 的本地别名
35
- * @returns 被 builder 调用的组件名称集合
44
+ * @returns 被 builder 包装的组件名称集合
36
45
  */
37
46
  export declare function collectBuilderWrappedNames(program: t.Program, builderAlias: string | null): Set<string>;
@@ -1,7 +1,10 @@
1
1
  /**
2
- * 从命名导出中收集名称
2
+ * 从命名导出声明中收集名称
3
+ * @param node - 命名导出声明节点
4
+ * @param names - 存储名称的集合
3
5
  */
4
6
  export function collectFromNamedExport(node, names) {
7
+ // 处理内联声明(export function/const)
5
8
  if (node.declaration) {
6
9
  if (node.declaration.type === 'FunctionDeclaration' && node.declaration.id) {
7
10
  names.add(node.declaration.id.name);
@@ -14,6 +17,7 @@ export function collectFromNamedExport(node, names) {
14
17
  }
15
18
  }
16
19
  }
20
+ // 处理导出说明符(export { a, b })
17
21
  if (node.specifiers) {
18
22
  for (const spec of node.specifiers) {
19
23
  if (spec.type === 'ExportSpecifier') {
@@ -23,22 +27,29 @@ export function collectFromNamedExport(node, names) {
23
27
  }
24
28
  }
25
29
  /**
26
- * 从默认导出中收集名称
30
+ * 从默认导出声明中收集名称
31
+ * @param node - 默认导出声明节点
32
+ * @param names - 存储名称的集合
27
33
  */
28
34
  export function collectFromDefaultExport(node, names) {
29
35
  const decl = node.declaration;
36
+ // 处理命名函数声明
30
37
  if (decl.type === 'FunctionDeclaration' && decl.id) {
31
38
  names.add(decl.id.name);
32
39
  }
33
40
  else if (decl.type === 'Identifier') {
41
+ // 处理标识符引用(export default Component)
34
42
  names.add(decl.name);
35
43
  }
36
44
  }
37
45
  /**
38
46
  * 从变量声明中收集变量名
47
+ * @param node - 变量声明节点
48
+ * @param names - 存储名称的集合
39
49
  */
40
50
  function collectFromVariableDeclaration(node, names) {
41
51
  for (const decl of node.declarations) {
52
+ // 只处理简单标识符(不处理解构)
42
53
  if (decl.id.type === 'Identifier') {
43
54
  names.add(decl.id.name);
44
55
  }
@@ -46,17 +57,23 @@ function collectFromVariableDeclaration(node, names) {
46
57
  }
47
58
  /**
48
59
  * 从导入声明中收集绑定的名称
60
+ * @param node - 导入声明节点
61
+ * @param names - 存储名称的集合
49
62
  */
50
63
  function collectFromImportDeclaration(node, names) {
51
64
  for (const spec of node.specifiers) {
65
+ // 收集本地绑定名称
52
66
  names.add(spec.local.name);
53
67
  }
54
68
  }
55
69
  /**
56
70
  * 收集所有导出的标识符名称
71
+ * @param program - AST Program 节点
72
+ * @returns 导出名称集合
57
73
  */
58
74
  export function collectExportedNames(program) {
59
75
  const names = new Set();
76
+ // 遍历程序体中的所有节点
60
77
  for (const node of program.body) {
61
78
  if (node.type === 'ExportNamedDeclaration') {
62
79
  collectFromNamedExport(node, names);
@@ -69,23 +86,32 @@ export function collectExportedNames(program) {
69
86
  }
70
87
  /**
71
88
  * 收集模块中所有绑定的名称(用于避免命名冲突)
89
+ * 包括函数声明、变量声明、导入声明和导出声明
90
+ * @param program - AST Program 节点
91
+ * @returns 所有绑定名称集合
72
92
  */
73
93
  export function collectAllBindingNames(program) {
74
94
  const names = new Set();
95
+ // 遍历程序体中的所有节点
75
96
  for (const node of program.body) {
97
+ // 函数声明
76
98
  if (node.type === 'FunctionDeclaration' && node.id) {
77
99
  names.add(node.id.name);
78
100
  }
79
101
  else if (node.type === 'VariableDeclaration') {
102
+ // 变量声明
80
103
  collectFromVariableDeclaration(node, names);
81
104
  }
82
105
  else if (node.type === 'ImportDeclaration') {
106
+ // 导入声明
83
107
  collectFromImportDeclaration(node, names);
84
108
  }
85
109
  else if (node.type === 'ExportNamedDeclaration') {
110
+ // 命名导出
86
111
  collectFromNamedExport(node, names);
87
112
  }
88
113
  else if (node.type === 'ExportDefaultDeclaration') {
114
+ // 默认导出
89
115
  collectFromDefaultExport(node, names);
90
116
  }
91
117
  }
@@ -93,14 +119,16 @@ export function collectAllBindingNames(program) {
93
119
  }
94
120
  /**
95
121
  * 判断调用表达式是否是 builder 调用
96
- * @param callExpr - 调用表达式
122
+ * @param callExpr - 调用表达式节点
97
123
  * @param builderAlias - builder 的本地别名
98
124
  * @returns 是否是 builder 调用
99
125
  */
100
126
  export function isBuilderCall(callExpr, builderAlias) {
127
+ // 如果没有配置 builder 别名,直接返回 false
101
128
  if (!builderAlias)
102
129
  return false;
103
130
  const callee = callExpr.callee;
131
+ // 检查调用者是否为标识符且名称匹配
104
132
  return callee.type === 'Identifier' && callee.name === builderAlias;
105
133
  }
106
134
  /**
@@ -108,13 +136,16 @@ export function isBuilderCall(callExpr, builderAlias) {
108
136
  * 检测 builder(Comp) 或 builder(Comp, options) 形式的调用
109
137
  * @param program - AST Program 节点
110
138
  * @param builderAlias - builder 的本地别名
111
- * @returns 被 builder 调用的组件名称集合
139
+ * @returns 被 builder 包装的组件名称集合
112
140
  */
113
141
  export function collectBuilderWrappedNames(program, builderAlias) {
114
142
  const wrappedNames = new Set();
143
+ // 如果没有配置 builder 别名,直接返回空集合
115
144
  if (!builderAlias)
116
145
  return wrappedNames;
146
+ // 遍历程序体中的所有节点
117
147
  for (const node of program.body) {
148
+ // 处理独立调用语句:builder(Comp)
118
149
  if (node.type === 'ExpressionStatement' && node.expression.type === 'CallExpression') {
119
150
  const callExpr = node.expression;
120
151
  if (isBuilderCall(callExpr, builderAlias)) {
@@ -125,6 +156,7 @@ export function collectBuilderWrappedNames(program, builderAlias) {
125
156
  }
126
157
  }
127
158
  else if (node.type === 'ExportDefaultDeclaration' && node.declaration.type === 'CallExpression') {
159
+ // 处理默认导出:export default builder(Comp)
128
160
  const callExpr = node.declaration;
129
161
  if (isBuilderCall(callExpr, builderAlias)) {
130
162
  const arg = callExpr.arguments[0];
@@ -134,6 +166,7 @@ export function collectBuilderWrappedNames(program, builderAlias) {
134
166
  }
135
167
  }
136
168
  else if (node.type === 'VariableDeclaration') {
169
+ // 处理变量声明:const Comp = builder(CompImpl)
137
170
  for (const decl of node.declarations) {
138
171
  if (decl.init?.type === 'CallExpression' && isBuilderCall(decl.init, builderAlias)) {
139
172
  const arg = decl.init.arguments[0];
@@ -144,6 +177,7 @@ export function collectBuilderWrappedNames(program, builderAlias) {
144
177
  }
145
178
  }
146
179
  else if (node.type === 'ExportNamedDeclaration' && node.declaration?.type === 'VariableDeclaration') {
180
+ // 处理命名导出:export const Comp = builder(CompImpl)
147
181
  for (const decl of node.declaration.declarations) {
148
182
  if (decl.init?.type === 'CallExpression' && isBuilderCall(decl.init, builderAlias)) {
149
183
  const arg = decl.init.arguments[0];
@@ -5,16 +5,18 @@
5
5
  */
6
6
  import * as t from '@babel/types';
7
7
  /**
8
- * 组件信息
8
+ * 组件信息接口
9
+ * 描述从 AST 中提取的组件函数信息
9
10
  */
10
11
  export interface ComponentInfo {
11
12
  name: string;
12
13
  node: t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression;
13
- /** 是否为包装组件(传递给 builder/defineComponent 等函数) */
14
+ /** 是否为包装组件(传递给 builder 函数) */
14
15
  isWrapped?: boolean;
15
16
  }
16
17
  /**
17
18
  * 收集模块中的组件函数
19
+ * 遍历 AST 程序节点,提取所有导出的组件函数
18
20
  * @param program - AST Program 节点
19
21
  * @param builderAlias - builder 函数的本地别名(用于识别纯构建组件)
20
22
  * @returns 组件信息数组