akfun 5.2.3 → 5.2.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akfun",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.6",
|
|
4
4
|
"description": "前端脚手架:支持Vue技术栈和react技术栈",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"前端工程",
|
|
@@ -58,7 +58,9 @@
|
|
|
58
58
|
"@babel/plugin-proposal-export-namespace-from": "^7.16.7",
|
|
59
59
|
"@babel/plugin-proposal-function-sent": "^7.16.7",
|
|
60
60
|
"@babel/plugin-proposal-json-strings": "^7.16.7",
|
|
61
|
+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7",
|
|
61
62
|
"@babel/plugin-proposal-numeric-separator": "^7.16.7",
|
|
63
|
+
"@babel/plugin-proposal-optional-chaining": "^7.16.7",
|
|
62
64
|
"@babel/plugin-proposal-throw-expressions": "^7.16.7",
|
|
63
65
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
64
66
|
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
|
@@ -4,7 +4,7 @@ module.exports = {
|
|
|
4
4
|
'@babel/preset-env',
|
|
5
5
|
{
|
|
6
6
|
loose: true,
|
|
7
|
-
modules: false // 是否启用将ES6模块语法转换为其他模块类型的功能,当前设置为false,以便webpack进行tree shaking。
|
|
7
|
+
modules: false // 是否启用将 ES6 模块语法转换为其他模块类型的功能,当前设置为 false,以便 webpack 进行 tree shaking。
|
|
8
8
|
/*
|
|
9
9
|
备注:后续升级babel版本时,再启用此配置
|
|
10
10
|
useBuiltIns: 'usage', // 按需引入 polyfill,替代 @babel/polyfill
|
|
@@ -26,6 +26,8 @@ module.exports = {
|
|
|
26
26
|
'@babel/plugin-syntax-dynamic-import',
|
|
27
27
|
'@babel/plugin-syntax-import-meta',
|
|
28
28
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
|
29
|
-
'@babel/plugin-proposal-json-strings'
|
|
29
|
+
'@babel/plugin-proposal-json-strings',
|
|
30
|
+
'@babel/plugin-proposal-optional-chaining', // 支持可选链操作符 ?.
|
|
31
|
+
'@babel/plugin-proposal-nullish-coalescing-operator' // 支持空值合并操作符 ??
|
|
30
32
|
]
|
|
31
33
|
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Babel 插件:自动在 React 组件的最外层元素添加 data-scope 属性
|
|
3
|
+
*
|
|
4
|
+
* 使用场景:
|
|
5
|
+
* - 在构建 React 组件时,自动为组件的根元素添加 data-scope 属性
|
|
6
|
+
* - 支持函数组件和类组件
|
|
7
|
+
* - 如果组件返回 Fragment 或数组,会在 Fragment 的第一个子元素或数组的第一个元素上添加
|
|
8
|
+
*/
|
|
9
|
+
module.exports = function ({ types: t }) {
|
|
10
|
+
/**
|
|
11
|
+
* 检查函数是否返回 JSX(用于判断是否是 React 组件)
|
|
12
|
+
*/
|
|
13
|
+
function returnsJSX(path) {
|
|
14
|
+
const body = path.get('body');
|
|
15
|
+
|
|
16
|
+
if (body.isBlockStatement()) {
|
|
17
|
+
// 检查函数体中是否有返回 JSX 的语句
|
|
18
|
+
let hasJSXReturn = false;
|
|
19
|
+
body.traverse({
|
|
20
|
+
ReturnStatement(returnPath) {
|
|
21
|
+
const argument = returnPath.get('argument');
|
|
22
|
+
if (argument.node && (
|
|
23
|
+
argument.isJSXElement() ||
|
|
24
|
+
argument.isJSXFragment() ||
|
|
25
|
+
argument.isArrayExpression()
|
|
26
|
+
)) {
|
|
27
|
+
hasJSXReturn = true;
|
|
28
|
+
returnPath.stop();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return hasJSXReturn;
|
|
33
|
+
} else if (body.isJSXElement() || body.isJSXFragment()) {
|
|
34
|
+
// 箭头函数直接返回 JSX
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 在 JSX 元素上添加 data-scope 属性
|
|
43
|
+
*/
|
|
44
|
+
function addDataScopeAttribute(jsxElement) {
|
|
45
|
+
const openingElement = jsxElement.openingElement;
|
|
46
|
+
const attributes = openingElement.attributes;
|
|
47
|
+
|
|
48
|
+
// 检查是否已经存在 data-scope 属性
|
|
49
|
+
const hasDataScope = attributes.some(
|
|
50
|
+
attr => t.isJSXAttribute(attr) && attr.name.name === 'data-scope'
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (!hasDataScope) {
|
|
54
|
+
// 创建 data-scope 属性
|
|
55
|
+
const dataScopeAttr = t.jsxAttribute(
|
|
56
|
+
t.jsxIdentifier('data-scope'),
|
|
57
|
+
t.stringLiteral('')
|
|
58
|
+
);
|
|
59
|
+
// 添加到属性列表的开头
|
|
60
|
+
attributes.unshift(dataScopeAttr);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 处理返回语句中的 JSX
|
|
66
|
+
*/
|
|
67
|
+
function processReturnStatement(path) {
|
|
68
|
+
const argument = path.get('argument');
|
|
69
|
+
|
|
70
|
+
if (!argument.node) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 处理 JSX 元素
|
|
75
|
+
if (argument.isJSXElement()) {
|
|
76
|
+
addDataScopeAttribute(argument.node);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 处理 JSX Fragment
|
|
81
|
+
if (argument.isJSXFragment()) {
|
|
82
|
+
const children = argument.get('children');
|
|
83
|
+
// 找到第一个 JSX 元素子节点
|
|
84
|
+
for (const child of children) {
|
|
85
|
+
if (child.isJSXElement()) {
|
|
86
|
+
addDataScopeAttribute(child.node);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// 如果子节点是 Fragment,递归处理
|
|
90
|
+
if (child.isJSXFragment()) {
|
|
91
|
+
processReturnStatement(child);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// 处理数组返回(多个元素)
|
|
98
|
+
if (argument.isArrayExpression()) {
|
|
99
|
+
const elements = argument.get('elements');
|
|
100
|
+
// 找到第一个 JSX 元素
|
|
101
|
+
for (const element of elements) {
|
|
102
|
+
if (element.isJSXElement()) {
|
|
103
|
+
addDataScopeAttribute(element.node);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 处理条件表达式(三元运算符)
|
|
110
|
+
if (argument.isConditionalExpression()) {
|
|
111
|
+
// 处理 true 分支
|
|
112
|
+
const consequent = argument.get('consequent');
|
|
113
|
+
if (consequent.isJSXElement()) {
|
|
114
|
+
addDataScopeAttribute(consequent.node);
|
|
115
|
+
} else if (consequent.isJSXFragment() || consequent.isArrayExpression()) {
|
|
116
|
+
processReturnStatement(consequent);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 处理 false 分支
|
|
120
|
+
const alternate = argument.get('alternate');
|
|
121
|
+
if (alternate.isJSXElement()) {
|
|
122
|
+
addDataScopeAttribute(alternate.node);
|
|
123
|
+
} else if (alternate.isJSXFragment() || alternate.isArrayExpression()) {
|
|
124
|
+
processReturnStatement(alternate);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 处理逻辑表达式(&& 或 ||)
|
|
129
|
+
if (argument.isLogicalExpression()) {
|
|
130
|
+
const right = argument.get('right');
|
|
131
|
+
if (right.isJSXElement()) {
|
|
132
|
+
addDataScopeAttribute(right.node);
|
|
133
|
+
} else if (right.isJSXFragment() || right.isArrayExpression()) {
|
|
134
|
+
processReturnStatement(right);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
visitor: {
|
|
141
|
+
// 处理函数组件和箭头函数组件
|
|
142
|
+
Function(path) {
|
|
143
|
+
// 只处理返回 JSX 的函数(即 React 组件)
|
|
144
|
+
if (!returnsJSX(path)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const body = path.get('body');
|
|
149
|
+
|
|
150
|
+
// 处理函数体中的返回语句
|
|
151
|
+
if (body.isBlockStatement()) {
|
|
152
|
+
body.traverse({
|
|
153
|
+
ReturnStatement(returnPath) {
|
|
154
|
+
processReturnStatement(returnPath);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
} else if (body.isJSXElement()) {
|
|
158
|
+
// 箭头函数直接返回 JSX
|
|
159
|
+
addDataScopeAttribute(body.node);
|
|
160
|
+
} else if (body.isJSXFragment()) {
|
|
161
|
+
// 箭头函数直接返回 Fragment
|
|
162
|
+
const children = body.get('children');
|
|
163
|
+
for (const child of children) {
|
|
164
|
+
if (child.isJSXElement()) {
|
|
165
|
+
addDataScopeAttribute(child.node);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// 处理类组件的 render 方法
|
|
173
|
+
ClassMethod(path) {
|
|
174
|
+
if (path.node.kind === 'method' && path.node.key.name === 'render') {
|
|
175
|
+
const body = path.get('body');
|
|
176
|
+
if (body.isBlockStatement()) {
|
|
177
|
+
body.traverse({
|
|
178
|
+
ReturnStatement(returnPath) {
|
|
179
|
+
processReturnStatement(returnPath);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
|
package/src/rollup/build.js
CHANGED
|
@@ -72,8 +72,12 @@ module.exports = function (config, envConfig, _rollupConfig, _consoleTag) {
|
|
|
72
72
|
outputItem.plugins.push(terser());
|
|
73
73
|
}
|
|
74
74
|
});
|
|
75
|
-
} else if (compress && isObject(curRollupConfig.output)
|
|
76
|
-
curRollupConfig.
|
|
75
|
+
} else if (compress && isObject(curRollupConfig.output)) {
|
|
76
|
+
if (!curRollupConfig.plugins) {
|
|
77
|
+
curRollupConfig.output.plugins = [terser()];
|
|
78
|
+
} else {
|
|
79
|
+
curRollupConfig.plugins.push(terser());
|
|
80
|
+
}
|
|
77
81
|
}
|
|
78
82
|
const spinner = ora(`${consoleTag}开启${buildFormat}模块构建模式...`).start();
|
|
79
83
|
rollupBuildFunc(curRollupConfig, config).then(() => {
|