@meituan-nocode/vite-plugin-nocode-compiler 0.1.0-beta.5 → 0.1.0-beta.6

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.
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.JSXCompiler = void 0;
7
7
  const parser_1 = require("@babel/parser");
8
+ const traverse_1 = __importDefault(require("@babel/traverse"));
8
9
  const magic_string_1 = __importDefault(require("magic-string"));
9
10
  const path_1 = __importDefault(require("path"));
10
11
  const utils_1 = require("../utils/utils");
11
- const estree_walker_1 = require("estree-walker");
12
12
  /**
13
13
  * JSX 编译器类
14
14
  * 负责处理 JSX 文件的编译逻辑
@@ -43,37 +43,68 @@ class JSXCompiler {
43
43
  const ast = (0, parser_1.parse)(code, parserOptions);
44
44
  const magicString = new magic_string_1.default(code);
45
45
  let changedElementsCount = 0;
46
- let currentElement = null;
47
46
  let arrayContext = null;
48
- (0, estree_walker_1.walk)(ast, {
49
- enter: (node) => {
47
+ // 使用 @babel/traverse 替代 estree-walker
48
+ (0, traverse_1.default)(ast, {
49
+ enter: path => {
50
+ const node = path.node;
50
51
  // 检测数组的 map 调用
51
- if (node.type === 'CallExpression' && node.callee?.type === 'MemberExpression' && node.callee.property?.name === 'map') {
52
- this.logger.log('Found array map:', node);
53
- const callee = node.callee;
54
- const arrayName = callee.object.name || (callee.object.type === 'MemberExpression' ? `${callee.object.object.name}.${callee.object.property.name}` : null);
55
- if (arrayName) {
56
- const paramName = node.arguments[0].params?.[1]?.name || 'index';
57
- arrayContext = { arrayName, paramName };
58
- this.logger.log('Found array map:', { arrayName, paramName });
52
+ if (node.type === 'CallExpression') {
53
+ const callExpr = node;
54
+ if (callExpr.callee.type === 'MemberExpression') {
55
+ const memberExpr = callExpr.callee;
56
+ if (memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'map') {
57
+ this.logger.log('Found array map:', node);
58
+ let arrayName = null;
59
+ // 获取数组名称
60
+ if (memberExpr.object.type === 'Identifier') {
61
+ arrayName = memberExpr.object.name;
62
+ }
63
+ else if (memberExpr.object.type === 'MemberExpression') {
64
+ const innerMember = memberExpr.object;
65
+ if (innerMember.object.type === 'Identifier' && innerMember.property.type === 'Identifier') {
66
+ arrayName = `${innerMember.object.name}.${innerMember.property.name}`;
67
+ }
68
+ }
69
+ // 获取参数名(通常是 index)
70
+ let paramName = 'index';
71
+ if (callExpr.arguments.length > 0) {
72
+ const callback = callExpr.arguments[0];
73
+ if (callback.type === 'ArrowFunctionExpression' || callback.type === 'FunctionExpression') {
74
+ const func = callback;
75
+ if (func.params.length > 1 && func.params[1].type === 'Identifier') {
76
+ paramName = func.params[1].name;
77
+ }
78
+ }
79
+ }
80
+ if (arrayName) {
81
+ arrayContext = { arrayName, paramName };
82
+ this.logger.log('Found array map:', { arrayName, paramName });
83
+ }
84
+ }
59
85
  }
60
86
  }
61
- if (node.type === 'JSXElement') {
62
- currentElement = node;
63
- }
87
+ // 处理 JSX 开标签
64
88
  if (node.type === 'JSXOpeningElement') {
65
- const jsxNode = node;
89
+ const jsxOpeningElement = node;
66
90
  let elementName;
67
- if (jsxNode.name.type === 'JSXIdentifier') {
68
- elementName = jsxNode.name.name;
91
+ // 获取元素名称
92
+ if (jsxOpeningElement.name.type === 'JSXIdentifier') {
93
+ elementName = jsxOpeningElement.name.name;
69
94
  }
70
- else if (jsxNode.name.type === 'JSXMemberExpression') {
71
- const memberExpr = jsxNode.name;
72
- elementName = `${memberExpr.object.name}.${memberExpr.property.name}`;
95
+ else if (jsxOpeningElement.name.type === 'JSXMemberExpression') {
96
+ const memberExpr = jsxOpeningElement.name;
97
+ if (memberExpr.object.type === 'JSXIdentifier' && memberExpr.property.type === 'JSXIdentifier') {
98
+ elementName = `${memberExpr.object.name}.${memberExpr.property.name}`;
99
+ }
100
+ else {
101
+ return;
102
+ }
73
103
  }
74
104
  else {
75
105
  return;
76
106
  }
107
+ // 跳过 Fragment
77
108
  if (elementName === 'Fragment' || elementName === 'React.Fragment') {
78
109
  return;
79
110
  }
@@ -84,21 +115,33 @@ class JSXCompiler {
84
115
  hasArrayContext: !!arrayContext,
85
116
  });
86
117
  if (shouldTag) {
87
- const line = jsxNode.loc?.start?.line ?? 0;
88
- const col = jsxNode.loc?.start?.column ?? 0;
118
+ const line = node.loc?.start?.line ?? 0;
119
+ const col = node.loc?.start?.column ?? 0;
89
120
  const attributes = (0, utils_1.generateDataAttributes)(relativePath, line, col, elementName, arrayContext);
90
121
  this.logger.log('Adding attributes:', attributes);
91
- magicString.appendLeft(jsxNode.name.end ?? 0, attributes);
92
- changedElementsCount++;
122
+ // 使用 path 获取准确的节点位置信息
123
+ const nameEndPosition = jsxOpeningElement.name.end;
124
+ if (nameEndPosition !== null) {
125
+ magicString.appendLeft(nameEndPosition, attributes);
126
+ changedElementsCount++;
127
+ }
93
128
  }
94
129
  }
95
130
  },
96
- leave: (node) => {
97
- if (node.type === 'CallExpression' && node.callee?.type === 'MemberExpression' && node.callee.property?.name === 'map') {
98
- if (arrayContext) {
99
- this.logger.log('Leaving array map context:', arrayContext.arrayName);
131
+ exit: path => {
132
+ const node = path.node;
133
+ // 离开 map 调用时清除上下文
134
+ if (node.type === 'CallExpression') {
135
+ const callExpr = node;
136
+ if (callExpr.callee.type === 'MemberExpression') {
137
+ const memberExpr = callExpr.callee;
138
+ if (memberExpr.property.type === 'Identifier' && memberExpr.property.name === 'map') {
139
+ if (arrayContext) {
140
+ this.logger.log('Leaving array map context:', arrayContext.arrayName);
141
+ }
142
+ arrayContext = null;
143
+ }
100
144
  }
101
- arrayContext = null;
102
145
  }
103
146
  },
104
147
  });
@@ -21,7 +21,7 @@ function generateDataAttributes(relativePath, line, col, elementName, arrayConte
21
21
  const dataComponentId = `${relativePath}:${line}:${col}`;
22
22
  let arrayAttrs = '';
23
23
  if (arrayContext) {
24
- arrayAttrs = ` data-nocode-array="${arrayContext.arrayName}" data-nocode-index="\${${arrayContext.paramName}}"`;
24
+ arrayAttrs = ` data-nocode-array="${arrayContext.arrayName}"`;
25
25
  }
26
26
  return ` data-nocode-id="${dataComponentId}" data-nocode-name="${elementName}"${arrayAttrs}`;
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meituan-nocode/vite-plugin-nocode-compiler",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-beta.6",
4
4
  "description": "nocode编译插件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -17,14 +17,15 @@
17
17
  "vite": "^5.4.0"
18
18
  },
19
19
  "devDependencies": {
20
+ "@types/babel__traverse": "^7.28.0",
20
21
  "@types/node": "^20.0.0",
21
22
  "typescript": "^5.0.0",
22
23
  "vite": "^5.4.0"
23
24
  },
24
25
  "dependencies": {
25
26
  "@babel/parser": "^7.23.0",
27
+ "@babel/traverse": "^7.28.4",
26
28
  "@babel/types": "^7.23.0",
27
- "magic-string": "^0.30.0",
28
- "estree-walker": "^3.0.0"
29
+ "magic-string": "^0.30.0"
29
30
  }
30
31
  }