@hadss/hmrouter-plugin 1.0.0-rc.3 → 1.0.0-rc.5
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/README.md +18 -15
- package/dist/HMRouterAnalyzer.d.ts +40 -0
- package/{lib → dist}/HMRouterAnalyzer.js +17 -32
- package/dist/HMRouterHvigorPlugin.d.ts +15 -0
- package/{lib → dist}/HMRouterHvigorPlugin.js +18 -58
- package/dist/HMRouterPluginConfig.d.ts +28 -0
- package/dist/HMRouterPluginConfig.js +52 -0
- package/dist/HMRouterPluginHandle.d.ts +17 -0
- package/{lib → dist}/HMRouterPluginHandle.js +4 -43
- package/dist/Index.d.ts +4 -0
- package/{lib → dist}/Index.js +8 -50
- package/dist/common/Constant.d.ts +27 -0
- package/{lib → dist}/common/Constant.js +0 -15
- package/dist/common/Logger.d.ts +12 -0
- package/{lib → dist}/common/Logger.js +5 -15
- package/dist/common/PluginModel.d.ts +47 -0
- package/{lib → dist}/common/PluginModel.js +0 -15
- package/package.json +18 -12
- package/lib/HMRouterAnalyzer.js.map +0 -1
- package/lib/HMRouterHvigorPlugin.js.map +0 -1
- package/lib/HMRouterPluginConfig.js +0 -31
- package/lib/HMRouterPluginConfig.js.map +0 -1
- package/lib/HMRouterPluginHandle.js.map +0 -1
- package/lib/Index.js.map +0 -1
- package/lib/common/Constant.js.map +0 -1
- package/lib/common/Logger.js.map +0 -1
- package/lib/common/PluginModel.js.map +0 -1
- package/src/HMRouterAnalyzer.ts +0 -367
- package/src/HMRouterHvigorPlugin.ts +0 -199
- package/src/HMRouterPluginConfig.ts +0 -44
- package/src/HMRouterPluginHandle.ts +0 -177
- package/src/Index.ts +0 -147
- package/src/common/Constant.ts +0 -49
- package/src/common/Logger.ts +0 -72
- package/src/common/PluginModel.ts +0 -88
- package/tsconfig.json +0 -14
package/README.md
CHANGED
|
@@ -4,34 +4,37 @@
|
|
|
4
4
|
```json5
|
|
5
5
|
{
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@hadss/hmrouter-plugin": "^1.0.0-rc.
|
|
7
|
+
"@hadss/hmrouter-plugin": "^1.0.0-rc.4" // 使用npm仓版本号
|
|
8
8
|
},
|
|
9
9
|
// ...其他配置
|
|
10
10
|
}
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
2.
|
|
14
|
-
```json5
|
|
15
|
-
{
|
|
16
|
-
"scanDir": ["src/main/ets/components","src/main/ets/interceptors"],
|
|
17
|
-
// 如果不传则扫描src/main/ets目录,对代码进行全量扫描,建议配置可缩短编译耗时
|
|
18
|
-
"saveGeneratedFile": false, // 默认为false,改成true则不删除编译产物
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
3. 在模块中引入路由编译插件,修改`hvigorfile.ts`
|
|
13
|
+
2. 在模块中引入路由编译插件,修改`hvigorfile.ts`
|
|
23
14
|
```typescript
|
|
24
15
|
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
|
25
|
-
import { hapPlugin } from
|
|
16
|
+
import { hapPlugin } from '@hadss/hmrouter-plugin';
|
|
26
17
|
|
|
27
18
|
export default {
|
|
28
19
|
system: hapTasks,
|
|
29
|
-
plugins: [hapPlugin()]
|
|
20
|
+
plugins: [hapPlugin()] // 使用HMRouter框架中标签的模块均需要配置,与模块类型保持一致
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> 如果模块是Har则使用`harPlugin()`, 模块是Hsp则使用`hspPlugin()`
|
|
25
|
+
|
|
26
|
+
3. 项目根目录或者模块目录创建路由编译插件配置文件`hmrouter_config.json`(推荐)
|
|
27
|
+
```json5
|
|
28
|
+
{
|
|
29
|
+
// 如果不配置则扫描src/main/ets目录,对代码进行全量扫描,如果配置则数组不能为空,建议配置指定目录可缩短编译耗时
|
|
30
|
+
"scanDir": ["src/main/ets/components","src/main/ets/interceptors"],
|
|
31
|
+
"saveGeneratedFile": false, // 默认为false,调试排除错误时可以改成true,不删除编译产物
|
|
30
32
|
}
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
>
|
|
34
|
-
|
|
35
|
+
> 配置文件读取规则为 模块 > 工程 > 默认
|
|
36
|
+
> 优先使用本模块内的配置,如果没有配置,则找模块目录的上级目录(最多找三层目录,找到则停止),若找不到则使用默认配置
|
|
37
|
+
|
|
35
38
|
## HMRouter使用
|
|
36
39
|
|
|
37
40
|
详见[@hadss/hmrouter](https://ohpm.openharmony.cn/#/cn/detail/@hadss%2Fhmrouter)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { HMRouterPluginConfig } from './HMRouterPluginConfig';
|
|
2
|
+
import { AnalyzerResultLike } from './common/PluginModel';
|
|
3
|
+
export declare class Analyzer {
|
|
4
|
+
analyzeResultSet: Set<AnalyzerResultLike>;
|
|
5
|
+
private readonly sourcePath;
|
|
6
|
+
private readonly pluginConfig;
|
|
7
|
+
private analyzeResult;
|
|
8
|
+
private classMethodAnalyzeResult;
|
|
9
|
+
private keywordPos;
|
|
10
|
+
private importMap;
|
|
11
|
+
constructor(sourcePath: string, pluginConfig: HMRouterPluginConfig);
|
|
12
|
+
start(): void;
|
|
13
|
+
private resolveNode;
|
|
14
|
+
private resolveImportDeclaration;
|
|
15
|
+
private resolveMissingDeclaration;
|
|
16
|
+
private isDecoratedClass;
|
|
17
|
+
private resolveClass;
|
|
18
|
+
private resolveClassMethod;
|
|
19
|
+
private resolveDecorator;
|
|
20
|
+
private switchIdentifier;
|
|
21
|
+
private resolveCallExpression;
|
|
22
|
+
private resolveExpression;
|
|
23
|
+
private resolveBlock;
|
|
24
|
+
private parseAnnotation;
|
|
25
|
+
private parseConfig;
|
|
26
|
+
private resolvePropertyAccess;
|
|
27
|
+
private resolveIdentifier;
|
|
28
|
+
private resolveArrayLiteral;
|
|
29
|
+
private resolveNumericLiteral;
|
|
30
|
+
private resolveStringLiteral;
|
|
31
|
+
private resolveTrueKeyword;
|
|
32
|
+
private resolveFalseKeyword;
|
|
33
|
+
private getSourceFile;
|
|
34
|
+
private findConstantValueInSourceFile;
|
|
35
|
+
private findObjectValueInSourceFile;
|
|
36
|
+
private resolveConstantValue;
|
|
37
|
+
private resolveObjectValue;
|
|
38
|
+
private resolvePath;
|
|
39
|
+
private parseVariableDeclaration;
|
|
40
|
+
}
|
|
@@ -1,18 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
4
|
};
|
|
@@ -46,7 +32,6 @@ class Analyzer {
|
|
|
46
32
|
this.analyzeResultSet = new Set([...this.analyzeResultSet, ...this.classMethodAnalyzeResult]);
|
|
47
33
|
}
|
|
48
34
|
});
|
|
49
|
-
// 遍历map查看是否还有常量类型的属性值
|
|
50
35
|
this.analyzeResultSet.forEach(value => {
|
|
51
36
|
if (value.annotation === 'HMRouter') {
|
|
52
37
|
let hmRouterResult = value;
|
|
@@ -54,7 +39,8 @@ class Analyzer {
|
|
|
54
39
|
hmRouterResult.pageUrl = this.resolveConstantValue(hmRouterResult.pageUrl.value);
|
|
55
40
|
}
|
|
56
41
|
else if (hmRouterResult.pageUrl.type === 'object') {
|
|
57
|
-
hmRouterResult.pageUrl =
|
|
42
|
+
hmRouterResult.pageUrl =
|
|
43
|
+
this.resolveObjectValue(hmRouterResult.pageUrl.className, hmRouterResult.pageUrl.propertyName);
|
|
58
44
|
}
|
|
59
45
|
}
|
|
60
46
|
});
|
|
@@ -110,6 +96,7 @@ class Analyzer {
|
|
|
110
96
|
variableArr.push(child.name.escapedText);
|
|
111
97
|
}
|
|
112
98
|
});
|
|
99
|
+
variableArr.push(node.importClause?.name?.text);
|
|
113
100
|
let key = node.moduleSpecifier;
|
|
114
101
|
if (typescript_1.default.isModuleName(key)) {
|
|
115
102
|
this.importMap.set(key.text, variableArr);
|
|
@@ -120,14 +107,11 @@ class Analyzer {
|
|
|
120
107
|
node.forEachChild(child => this.resolveNode(child));
|
|
121
108
|
}
|
|
122
109
|
isDecoratedClass(node) {
|
|
123
|
-
// @ts-ignore
|
|
124
110
|
return node.modifiers?.some((item) => Constant_1.HMRouterPluginConstant.CLASS_ANNOTATION_ARR.includes(item.expression?.expression?.text));
|
|
125
111
|
}
|
|
126
112
|
resolveClass(node) {
|
|
127
|
-
// 解析到类声明,先清空一次返回结果
|
|
128
113
|
this.analyzeResult = {};
|
|
129
114
|
node.modifiers?.forEach(modifier => {
|
|
130
|
-
// 遍历分析装饰器
|
|
131
115
|
this.resolveNode(modifier);
|
|
132
116
|
});
|
|
133
117
|
if (this.analyzeResult.annotation) {
|
|
@@ -142,7 +126,6 @@ class Analyzer {
|
|
|
142
126
|
member.modifiers?.forEach((modifier) => {
|
|
143
127
|
this.resolveNode(modifier);
|
|
144
128
|
});
|
|
145
|
-
// @ts-ignore
|
|
146
129
|
this.analyzeResult.functionName = member.name?.text;
|
|
147
130
|
this.analyzeResult.name = node.name?.text;
|
|
148
131
|
if (this.analyzeResult.annotation) {
|
|
@@ -204,13 +187,13 @@ class Analyzer {
|
|
|
204
187
|
if (propertyName === 'pageUrl') {
|
|
205
188
|
if (node.initializer.kind === typescript_1.default.SyntaxKind.Identifier) {
|
|
206
189
|
propertyValue = {
|
|
207
|
-
type: 'constant',
|
|
190
|
+
type: 'constant',
|
|
208
191
|
value: this.resolveNode(node.initializer)?.value
|
|
209
192
|
};
|
|
210
193
|
}
|
|
211
194
|
else if (node.initializer.kind === typescript_1.default.SyntaxKind.PropertyAccessExpression) {
|
|
212
195
|
propertyValue = {
|
|
213
|
-
type: 'object',
|
|
196
|
+
type: 'object',
|
|
214
197
|
className: this.resolveNode(node.initializer.expression)?.value,
|
|
215
198
|
propertyName: this.resolveNode(node.initializer.name)?.value
|
|
216
199
|
};
|
|
@@ -281,7 +264,7 @@ class Analyzer {
|
|
|
281
264
|
}
|
|
282
265
|
});
|
|
283
266
|
});
|
|
284
|
-
return nodeInfo
|
|
267
|
+
return nodeInfo;
|
|
285
268
|
}
|
|
286
269
|
findObjectValueInSourceFile(sourceFile, className, propertyName) {
|
|
287
270
|
let info = new NodeInfo();
|
|
@@ -290,37 +273,36 @@ class Analyzer {
|
|
|
290
273
|
return;
|
|
291
274
|
}
|
|
292
275
|
node.members.forEach(member => {
|
|
293
|
-
// @ts-ignore
|
|
294
276
|
if (member.name?.escapedText.toString() === propertyName) {
|
|
295
277
|
info = this.parseVariableDeclaration(member);
|
|
296
278
|
}
|
|
297
279
|
});
|
|
298
280
|
});
|
|
299
|
-
return info
|
|
281
|
+
return info;
|
|
300
282
|
}
|
|
301
283
|
resolveConstantValue(constantName) {
|
|
302
284
|
const sourceFile = this.getSourceFile(this.resolvePath(constantName));
|
|
303
285
|
if (!sourceFile) {
|
|
304
286
|
return null;
|
|
305
287
|
}
|
|
306
|
-
const
|
|
307
|
-
if (!
|
|
288
|
+
const constantValueStr = this.findConstantValueInSourceFile(sourceFile, constantName).value['value'];
|
|
289
|
+
if (!constantValueStr) {
|
|
308
290
|
Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING, constantName);
|
|
309
291
|
throw new Error('constant value cannot be an empty string');
|
|
310
292
|
}
|
|
311
|
-
return
|
|
293
|
+
return constantValueStr;
|
|
312
294
|
}
|
|
313
295
|
resolveObjectValue(className, propertyName) {
|
|
314
296
|
const sourceFile = this.getSourceFile(this.resolvePath(className));
|
|
315
297
|
if (!sourceFile) {
|
|
316
298
|
return null;
|
|
317
299
|
}
|
|
318
|
-
const
|
|
319
|
-
if (!
|
|
300
|
+
const objectValueStr = this.findObjectValueInSourceFile(sourceFile, className, propertyName).value['value'];
|
|
301
|
+
if (!objectValueStr) {
|
|
320
302
|
Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING, propertyName);
|
|
321
303
|
throw new Error('constant value cannot be an empty string');
|
|
322
304
|
}
|
|
323
|
-
return
|
|
305
|
+
return objectValueStr;
|
|
324
306
|
}
|
|
325
307
|
resolvePath(variableName) {
|
|
326
308
|
let filePath = '';
|
|
@@ -342,10 +324,13 @@ class Analyzer {
|
|
|
342
324
|
parseVariableDeclaration(node) {
|
|
343
325
|
let variableName = this.resolveNode(node.name)?.value;
|
|
344
326
|
let variableValue = this.resolveNode(node.initializer)?.value;
|
|
327
|
+
if (typeof variableValue !== 'string') {
|
|
328
|
+
Logger_1.Logger.error(Logger_1.PluginError.ERR_INVALID_STRING_VALUE, variableName);
|
|
329
|
+
throw new Error('Invalid constant value');
|
|
330
|
+
}
|
|
345
331
|
let info = new NodeInfo();
|
|
346
332
|
info.value = { key: variableName, value: variableValue };
|
|
347
333
|
return info;
|
|
348
334
|
}
|
|
349
335
|
}
|
|
350
336
|
exports.Analyzer = Analyzer;
|
|
351
|
-
//# sourceMappingURL=HMRouterAnalyzer.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HMRouterPluginConfig } from './HMRouterPluginConfig';
|
|
2
|
+
import { RouterInfo } from './common/PluginModel';
|
|
3
|
+
export declare class HMRouterHvigorPlugin {
|
|
4
|
+
config: HMRouterPluginConfig;
|
|
5
|
+
routerMap: RouterInfo[];
|
|
6
|
+
private scanFiles;
|
|
7
|
+
private HMRouterNum;
|
|
8
|
+
constructor(config: HMRouterPluginConfig);
|
|
9
|
+
analyzeAnnotation(): void;
|
|
10
|
+
private pushRouterInfo;
|
|
11
|
+
private generateBuilder;
|
|
12
|
+
generateRouterMap(): void;
|
|
13
|
+
private deepScan;
|
|
14
|
+
private stringToHashCode;
|
|
15
|
+
}
|
|
@@ -1,32 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
4
|
};
|
|
19
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
6
|
exports.HMRouterHvigorPlugin = void 0;
|
|
21
7
|
const fs_1 = __importDefault(require("fs"));
|
|
22
|
-
const path_1 = __importDefault(require("path"));
|
|
23
8
|
const handlebars_1 = __importDefault(require("handlebars"));
|
|
24
9
|
const hvigor_1 = require("@ohos/hvigor");
|
|
25
10
|
const PluginModel_1 = require("./common/PluginModel");
|
|
26
11
|
const HMRouterAnalyzer_1 = require("./HMRouterAnalyzer");
|
|
27
12
|
const Logger_1 = require("./common/Logger");
|
|
28
13
|
const Constant_1 = require("./common/Constant");
|
|
29
|
-
// 定义HMRouterHvigorPlugin类
|
|
30
14
|
class HMRouterHvigorPlugin {
|
|
31
15
|
constructor(config) {
|
|
32
16
|
this.routerMap = [];
|
|
@@ -35,40 +19,33 @@ class HMRouterHvigorPlugin {
|
|
|
35
19
|
this.config = config;
|
|
36
20
|
}
|
|
37
21
|
analyzeAnnotation() {
|
|
38
|
-
this.config.scanDir.forEach(
|
|
39
|
-
const scanPath =
|
|
22
|
+
this.config.scanDir.forEach((dir) => {
|
|
23
|
+
const scanPath = this.config.getScanPath(dir);
|
|
40
24
|
this.deepScan(scanPath, '');
|
|
41
25
|
});
|
|
42
26
|
Logger_1.Logger.info(`Scanned ${this.scanFiles.length} files`, this.scanFiles);
|
|
43
|
-
this.scanFiles.forEach(filePath => {
|
|
27
|
+
this.scanFiles.forEach((filePath) => {
|
|
44
28
|
if (filePath.endsWith(Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX)) {
|
|
45
|
-
// 创建Analyzer对象
|
|
46
29
|
const analyzer = new HMRouterAnalyzer_1.Analyzer(filePath, this.config);
|
|
47
|
-
// 开始分析
|
|
48
30
|
analyzer.start();
|
|
49
|
-
// 遍历分析结果
|
|
50
31
|
for (let analyzeResult of analyzer.analyzeResultSet) {
|
|
51
32
|
analyzeResult.module = this.config.moduleName;
|
|
52
|
-
let pageSourceFile =
|
|
33
|
+
let pageSourceFile = this.config.getRelativeSourcePath(filePath);
|
|
53
34
|
this.pushRouterInfo(analyzeResult, pageSourceFile.replaceAll(Constant_1.HMRouterPluginConstant.FILE_SEPARATOR, Constant_1.HMRouterPluginConstant.DELIMITER));
|
|
54
35
|
}
|
|
55
36
|
this.HMRouterNum = 0;
|
|
56
37
|
}
|
|
57
38
|
});
|
|
58
39
|
}
|
|
59
|
-
// 推送路由信息
|
|
60
40
|
pushRouterInfo(analyzeResult, pageSourceFile) {
|
|
61
|
-
// 判断注解类型
|
|
62
41
|
switch (analyzeResult.annotation) {
|
|
63
42
|
case Constant_1.HMRouterPluginConstant.ROUTER_ANNOTATION:
|
|
64
43
|
this.HMRouterNum++;
|
|
65
|
-
// 判断是否存在多个HMRouter注解
|
|
66
44
|
if (this.HMRouterNum > 1) {
|
|
67
45
|
Logger_1.Logger.error(Logger_1.PluginError.ERR_REPEAT_ANNOTATION, pageSourceFile);
|
|
68
46
|
throw new Error(`文件${pageSourceFile}中存在多个HMRouter注解`);
|
|
69
47
|
}
|
|
70
48
|
let [generatorFilePath, componentName] = this.generateBuilder(analyzeResult, pageSourceFile);
|
|
71
|
-
// window环境下需要替换路径中的反斜杠
|
|
72
49
|
generatorFilePath = generatorFilePath.replaceAll(Constant_1.HMRouterPluginConstant.FILE_SEPARATOR, Constant_1.HMRouterPluginConstant.DELIMITER);
|
|
73
50
|
this.routerMap.push(new PluginModel_1.RouterInfo(analyzeResult.pageUrl, generatorFilePath, `${componentName}Builder`, analyzeResult));
|
|
74
51
|
break;
|
|
@@ -90,38 +67,26 @@ class HMRouterHvigorPlugin {
|
|
|
90
67
|
break;
|
|
91
68
|
}
|
|
92
69
|
}
|
|
93
|
-
// 生成Builder
|
|
94
70
|
generateBuilder(analyzeResult, pageSourceFile) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
.relative(this.config.builderDir, pageSourceFile)
|
|
71
|
+
let importPath = this.config
|
|
72
|
+
.getRelativeBuilderPath(pageSourceFile)
|
|
98
73
|
.replaceAll(Constant_1.HMRouterPluginConstant.FILE_SEPARATOR, Constant_1.HMRouterPluginConstant.DELIMITER)
|
|
99
74
|
.replaceAll(Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX, '');
|
|
100
|
-
// 生成视图名称
|
|
101
75
|
let generatorViewName = Constant_1.HMRouterPluginConstant.VIEW_NAME_PREFIX + analyzeResult.name + this.stringToHashCode(analyzeResult.pageUrl);
|
|
102
|
-
// 创建模板模型
|
|
103
76
|
const templateModel = new PluginModel_1.TemplateModel(analyzeResult.pageUrl, importPath, analyzeResult.name, !!analyzeResult.dialog, generatorViewName);
|
|
104
|
-
|
|
105
|
-
const templateFilePath = hvigor_1.FileUtil.pathResolve(__dirname, Constant_1.HMRouterPluginConstant.PARENT_DELIMITER + this.config.builderTpl);
|
|
106
|
-
// 读取模板文件
|
|
77
|
+
const templateFilePath = this.config.getTplFilePath();
|
|
107
78
|
const tpl = hvigor_1.FileUtil.readFileSync(templateFilePath).toString();
|
|
108
|
-
// 编译模板
|
|
109
79
|
const template = handlebars_1.default.compile(tpl);
|
|
110
|
-
// 渲染模板
|
|
111
80
|
const output = template(templateModel);
|
|
112
|
-
|
|
113
|
-
const generatorFilePath = hvigor_1.FileUtil.pathResolve(this.config.modulePath, this.config.builderDir, templateModel.generatorViewName + Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX);
|
|
81
|
+
const generatorFilePath = this.config.getGeneratedFilePath(templateModel.generatorViewName);
|
|
114
82
|
hvigor_1.FileUtil.ensureFileSync(generatorFilePath);
|
|
115
83
|
hvigor_1.FileUtil.writeFileSync(generatorFilePath, output);
|
|
116
84
|
Logger_1.Logger.info(`Builder ${templateModel.generatorViewName}.ets has been generated in ${generatorFilePath}`);
|
|
117
|
-
|
|
118
|
-
return [path_1.default.join(this.config.builderDir, templateModel.generatorViewName + Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX), templateModel.componentName];
|
|
85
|
+
return [this.config.getBuilderFilePath(templateModel.generatorViewName), templateModel.componentName];
|
|
119
86
|
}
|
|
120
|
-
// 生成路由表文件
|
|
121
87
|
generateRouterMap() {
|
|
122
88
|
let set = new Set();
|
|
123
|
-
this.routerMap.forEach(item => {
|
|
124
|
-
// 判断路由名称是否重复
|
|
89
|
+
this.routerMap.forEach((item) => {
|
|
125
90
|
if (set.has(item.name)) {
|
|
126
91
|
Logger_1.Logger.error(Logger_1.PluginError.ERR_DUPLICATE_NAME, item.name);
|
|
127
92
|
throw new Error(`路由${item.name}重复`);
|
|
@@ -131,28 +96,24 @@ class HMRouterHvigorPlugin {
|
|
|
131
96
|
}
|
|
132
97
|
});
|
|
133
98
|
let routerMap = {
|
|
134
|
-
routerMap: this.routerMap.map(item => {
|
|
135
|
-
// 删除注解
|
|
99
|
+
routerMap: this.routerMap.map((item) => {
|
|
136
100
|
if (item.customData && item.customData.annotation) {
|
|
137
101
|
delete item.customData.annotation;
|
|
138
102
|
}
|
|
139
103
|
return item;
|
|
140
|
-
})
|
|
104
|
+
}),
|
|
141
105
|
};
|
|
142
|
-
// 获取路由映射文件路径
|
|
143
106
|
const routerMapJsonStr = JSON.stringify(routerMap, null, 2);
|
|
144
|
-
const routerMapFilePath =
|
|
145
|
-
// 确保文件存在
|
|
107
|
+
const routerMapFilePath = this.config.getRouterMapDir();
|
|
146
108
|
hvigor_1.FileUtil.ensureFileSync(routerMapFilePath);
|
|
147
109
|
hvigor_1.FileUtil.writeFileSync(routerMapFilePath, routerMapJsonStr);
|
|
148
110
|
Logger_1.Logger.info(`hm_router_map.json has been generated in ${routerMapFilePath}`);
|
|
149
111
|
}
|
|
150
|
-
// 深度扫描文件夹获取需要扫描的文件列表
|
|
151
112
|
deepScan(scanPath, filePath) {
|
|
152
113
|
let resolvePath = hvigor_1.FileUtil.pathResolve(scanPath, filePath);
|
|
153
|
-
if (hvigor_1.FileUtil.isDictionary(resolvePath)) {
|
|
114
|
+
if (hvigor_1.FileUtil.exist(resolvePath) && hvigor_1.FileUtil.isDictionary(resolvePath)) {
|
|
154
115
|
const files = fs_1.default.readdirSync(resolvePath);
|
|
155
|
-
files.forEach(file => {
|
|
116
|
+
files.forEach((file) => {
|
|
156
117
|
this.deepScan(resolvePath, file);
|
|
157
118
|
});
|
|
158
119
|
}
|
|
@@ -160,18 +121,17 @@ class HMRouterHvigorPlugin {
|
|
|
160
121
|
this.scanFiles.push(resolvePath);
|
|
161
122
|
}
|
|
162
123
|
}
|
|
163
|
-
// 字符串转哈希码
|
|
164
124
|
stringToHashCode(str) {
|
|
165
125
|
let hash = 0;
|
|
166
|
-
if (str.length === 0)
|
|
126
|
+
if (str.length === 0) {
|
|
167
127
|
return hash;
|
|
128
|
+
}
|
|
168
129
|
for (let i = 0; i < str.length; i++) {
|
|
169
130
|
const char = str.charCodeAt(i);
|
|
170
131
|
hash = (hash << 5) - hash + char;
|
|
171
|
-
hash |= 0;
|
|
132
|
+
hash |= 0;
|
|
172
133
|
}
|
|
173
134
|
return hash;
|
|
174
135
|
}
|
|
175
136
|
}
|
|
176
137
|
exports.HMRouterHvigorPlugin = HMRouterHvigorPlugin;
|
|
177
|
-
//# sourceMappingURL=HMRouterHvigorPlugin.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare class HMRouterPluginConfig {
|
|
2
|
+
moduleName: string;
|
|
3
|
+
modulePath: string;
|
|
4
|
+
scanDir: string[];
|
|
5
|
+
routerMapDir: string;
|
|
6
|
+
builderDir: string;
|
|
7
|
+
annotation: string[];
|
|
8
|
+
builderTpl: string;
|
|
9
|
+
saveGeneratedFile: boolean;
|
|
10
|
+
constructor(moduleName: string, modulePath: string, param: HMRouterPluginConfigParam);
|
|
11
|
+
getScanPath(dir: string): string;
|
|
12
|
+
getRelativeSourcePath(filePath: string): string;
|
|
13
|
+
getRelativeBuilderPath(filePath: string): string;
|
|
14
|
+
getGeneratedFilePath(generatorViewName: string): string;
|
|
15
|
+
getBuilderDir(): string;
|
|
16
|
+
getBuilderFilePath(generatorViewName: string): string;
|
|
17
|
+
getRouterMapDir(): string;
|
|
18
|
+
getModuleRouterMapFilePath(routerMapFileName: string): string;
|
|
19
|
+
getRawFilePath(): string;
|
|
20
|
+
getTplFilePath(): string;
|
|
21
|
+
}
|
|
22
|
+
export interface HMRouterPluginConfigParam {
|
|
23
|
+
scanDir?: string[];
|
|
24
|
+
routerMapDir?: string;
|
|
25
|
+
builderDir?: string;
|
|
26
|
+
saveGeneratedFile?: boolean;
|
|
27
|
+
builderTpl?: string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HMRouterPluginConfig = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const hvigor_1 = require("@ohos/hvigor");
|
|
9
|
+
const Constant_1 = require("./common/Constant");
|
|
10
|
+
class HMRouterPluginConfig {
|
|
11
|
+
constructor(moduleName, modulePath, param) {
|
|
12
|
+
this.moduleName = moduleName;
|
|
13
|
+
this.modulePath = modulePath;
|
|
14
|
+
this.scanDir = param.scanDir ? [...new Set(param.scanDir)] : ['src/main/ets'];
|
|
15
|
+
this.routerMapDir = param.routerMapDir ? param.routerMapDir : 'src/main/resources/base/profile';
|
|
16
|
+
this.builderDir = param.builderDir ? param.builderDir : 'src/main/ets/generated';
|
|
17
|
+
this.annotation = ['HMRouter', 'HMAnimator', 'HMInterceptor', 'HMLifecycle', 'HMService'];
|
|
18
|
+
this.builderTpl = param.builderTpl ? param.builderTpl : 'viewBuilder.tpl';
|
|
19
|
+
this.saveGeneratedFile = !!param.saveGeneratedFile;
|
|
20
|
+
}
|
|
21
|
+
getScanPath(dir) {
|
|
22
|
+
return hvigor_1.FileUtil.pathResolve(this.modulePath, dir);
|
|
23
|
+
}
|
|
24
|
+
getRelativeSourcePath(filePath) {
|
|
25
|
+
return path_1.default.relative(this.modulePath, filePath);
|
|
26
|
+
}
|
|
27
|
+
getRelativeBuilderPath(filePath) {
|
|
28
|
+
return path_1.default.relative(this.builderDir, filePath);
|
|
29
|
+
}
|
|
30
|
+
getGeneratedFilePath(generatorViewName) {
|
|
31
|
+
return hvigor_1.FileUtil.pathResolve(this.modulePath, this.builderDir, generatorViewName + Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX);
|
|
32
|
+
}
|
|
33
|
+
getBuilderDir() {
|
|
34
|
+
return hvigor_1.FileUtil.pathResolve(this.modulePath, this.builderDir);
|
|
35
|
+
}
|
|
36
|
+
getBuilderFilePath(generatorViewName) {
|
|
37
|
+
return path_1.default.join(this.builderDir, generatorViewName + Constant_1.HMRouterPluginConstant.VIEW_NAME_SUFFIX);
|
|
38
|
+
}
|
|
39
|
+
getRouterMapDir() {
|
|
40
|
+
return hvigor_1.FileUtil.pathResolve(this.modulePath, this.routerMapDir, Constant_1.HMRouterPluginConstant.ROUTER_MAP_NAME);
|
|
41
|
+
}
|
|
42
|
+
getModuleRouterMapFilePath(routerMapFileName) {
|
|
43
|
+
return hvigor_1.FileUtil.pathResolve(this.modulePath, this.routerMapDir, routerMapFileName + Constant_1.HMRouterPluginConstant.JSON_SUFFIX);
|
|
44
|
+
}
|
|
45
|
+
getRawFilePath() {
|
|
46
|
+
return hvigor_1.FileUtil.pathResolve(this.modulePath, Constant_1.HMRouterPluginConstant.RAWFILE_DIR);
|
|
47
|
+
}
|
|
48
|
+
getTplFilePath() {
|
|
49
|
+
return hvigor_1.FileUtil.pathResolve(__dirname, Constant_1.HMRouterPluginConstant.PARENT_DELIMITER + this.builderTpl);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.HMRouterPluginConfig = HMRouterPluginConfig;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { HvigorNode } from '@ohos/hvigor';
|
|
2
|
+
import { OhosHapContext, OhosHarContext, OhosHspContext } from '@ohos/hvigor-ohos-plugin';
|
|
3
|
+
import { HMRouterPluginConfig } from './HMRouterPluginConfig';
|
|
4
|
+
export declare class HMRouterPluginHandle {
|
|
5
|
+
private readonly node;
|
|
6
|
+
private readonly moduleContext;
|
|
7
|
+
readonly config: HMRouterPluginConfig;
|
|
8
|
+
private readonly plugin;
|
|
9
|
+
constructor(node: HvigorNode, moduleContext: OhosHapContext | OhosHarContext | OhosHspContext);
|
|
10
|
+
start(): void;
|
|
11
|
+
private copyRouterMapToRawFileTask;
|
|
12
|
+
private taskExec;
|
|
13
|
+
private updateModuleJsonOpt;
|
|
14
|
+
private updateBuildProfileOpt;
|
|
15
|
+
private pushRouterInfo;
|
|
16
|
+
private readConfig;
|
|
17
|
+
}
|
|
@@ -1,18 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
3
|
exports.HMRouterPluginHandle = void 0;
|
|
18
4
|
const hvigor_1 = require("@ohos/hvigor");
|
|
@@ -20,16 +6,13 @@ const HMRouterPluginConfig_1 = require("./HMRouterPluginConfig");
|
|
|
20
6
|
const HMRouterHvigorPlugin_1 = require("./HMRouterHvigorPlugin");
|
|
21
7
|
const Logger_1 = require("./common/Logger");
|
|
22
8
|
const Constant_1 = require("./common/Constant");
|
|
23
|
-
// HMRouterPluginHandle类,用于处理HMRouter插件
|
|
24
9
|
class HMRouterPluginHandle {
|
|
25
|
-
// 构造函数,初始化节点、模块上下文、配置和插件
|
|
26
10
|
constructor(node, moduleContext) {
|
|
27
11
|
this.node = node;
|
|
28
12
|
this.moduleContext = moduleContext;
|
|
29
13
|
this.config = this.readConfig();
|
|
30
14
|
this.plugin = new HMRouterHvigorPlugin_1.HMRouterHvigorPlugin(this.config);
|
|
31
15
|
}
|
|
32
|
-
// 启动插件
|
|
33
16
|
start() {
|
|
34
17
|
Logger_1.Logger.info(`Exec ${this.moduleContext.getModuleType()}Plugin..., node:${this.node.getNodeName()}, nodePath:${this.node.getNodePath()}`);
|
|
35
18
|
this.moduleContext.targets((target) => {
|
|
@@ -40,7 +23,7 @@ class HMRouterPluginHandle {
|
|
|
40
23
|
this.taskExec();
|
|
41
24
|
},
|
|
42
25
|
dependencies: [`${targetName}@PreBuild`],
|
|
43
|
-
postDependencies: [`${targetName}@MergeProfile`]
|
|
26
|
+
postDependencies: [`${targetName}@MergeProfile`],
|
|
44
27
|
});
|
|
45
28
|
this.node.registerTask({
|
|
46
29
|
name: `${targetName}@CopyRouterMapToRawFileTask`,
|
|
@@ -48,57 +31,40 @@ class HMRouterPluginHandle {
|
|
|
48
31
|
this.copyRouterMapToRawFileTask(target.getBuildTargetOutputPath(), targetName);
|
|
49
32
|
},
|
|
50
33
|
dependencies: [`${targetName}@ProcessRouterMap`],
|
|
51
|
-
postDependencies: [`${targetName}@ProcessResource`]
|
|
34
|
+
postDependencies: [`${targetName}@ProcessResource`],
|
|
52
35
|
});
|
|
53
36
|
});
|
|
54
37
|
}
|
|
55
|
-
// 拷贝routerMap到raw文件
|
|
56
38
|
copyRouterMapToRawFileTask(buildOutputPath, targetName) {
|
|
57
39
|
let routerMapFilePath = hvigor_1.FileUtil.pathResolve(buildOutputPath, Constant_1.HMRouterPluginConstant.TEMP_ROUTER_MAP_PATH, targetName, Constant_1.HMRouterPluginConstant.ROUTER_MAP_NAME);
|
|
58
|
-
let rawFilePath =
|
|
40
|
+
let rawFilePath = this.config.getRawFilePath();
|
|
59
41
|
hvigor_1.FileUtil.ensureFileSync(rawFilePath);
|
|
60
42
|
hvigor_1.FileUtil.copyFileSync(routerMapFilePath, rawFilePath);
|
|
61
43
|
}
|
|
62
|
-
// 执行任务
|
|
63
44
|
taskExec() {
|
|
64
45
|
let startTime = Date.now();
|
|
65
46
|
Logger_1.Logger.info(this.node.getNodeName() + ': HMRouterPluginTask start');
|
|
66
|
-
// 分析注解
|
|
67
47
|
this.plugin.analyzeAnnotation();
|
|
68
|
-
// 更新module.json
|
|
69
48
|
this.updateModuleJsonOpt();
|
|
70
|
-
// 更新profile
|
|
71
49
|
this.updateBuildProfileOpt();
|
|
72
50
|
let endTime = Date.now();
|
|
73
51
|
Logger_1.Logger.info(this.config.moduleName + ': HMRouterPluginTask end');
|
|
74
52
|
Logger_1.Logger.info(this.config.moduleName + ': HMRouterPluginTask cost: ' + (endTime - startTime) + ' ms');
|
|
75
53
|
}
|
|
76
|
-
// 更新module.json
|
|
77
54
|
updateModuleJsonOpt() {
|
|
78
|
-
// 获取模块的json配置
|
|
79
55
|
const moduleJsonOpt = this.moduleContext.getModuleJsonOpt();
|
|
80
|
-
// 如果模块的json配置中有routerMap
|
|
81
56
|
if (moduleJsonOpt.module.routerMap) {
|
|
82
|
-
// 获取routerMap的文件名
|
|
83
57
|
let routerMapFileName = moduleJsonOpt.module.routerMap.split(':')[1];
|
|
84
|
-
|
|
85
|
-
let routerMapFilePath = hvigor_1.FileUtil.pathResolve(this.config.modulePath, this.config.routerMapDir, routerMapFileName + Constant_1.HMRouterPluginConstant.JSON_SUFFIX);
|
|
86
|
-
// 读取routerMap的json文件
|
|
58
|
+
let routerMapFilePath = this.config.getModuleRouterMapFilePath(routerMapFileName);
|
|
87
59
|
let routerMapObj = hvigor_1.FileUtil.readJson5(routerMapFilePath);
|
|
88
|
-
// 将routerMap添加到plugin的routerMap中
|
|
89
60
|
this.plugin.routerMap.unshift(...routerMapObj['routerMap']);
|
|
90
61
|
}
|
|
91
|
-
// 生成routerMap
|
|
92
62
|
this.plugin.generateRouterMap();
|
|
93
|
-
// 将routerMap的名称设置为MODULE_ROUTER_MAP_NAME
|
|
94
63
|
moduleJsonOpt.module.routerMap = Constant_1.HMRouterPluginConstant.MODULE_ROUTER_MAP_NAME;
|
|
95
|
-
// 将修改后的moduleJsonOpt设置到moduleContext中
|
|
96
64
|
this.moduleContext.setModuleJsonOpt(moduleJsonOpt);
|
|
97
65
|
}
|
|
98
66
|
updateBuildProfileOpt() {
|
|
99
|
-
// 获取构建配置选项
|
|
100
67
|
const buildProfileOpt = this.moduleContext.getBuildProfileOpt();
|
|
101
|
-
// 初始化 arkOptions 和 runtimeOnly 配置
|
|
102
68
|
if (!buildProfileOpt.buildOption) {
|
|
103
69
|
buildProfileOpt.buildOption = {};
|
|
104
70
|
}
|
|
@@ -111,12 +77,9 @@ class HMRouterPluginHandle {
|
|
|
111
77
|
if (!buildProfileOpt.buildOption.arkOptions.runtimeOnly.sources) {
|
|
112
78
|
buildProfileOpt.buildOption.arkOptions.runtimeOnly.sources = [];
|
|
113
79
|
}
|
|
114
|
-
// 将路由信息推送到构建配置选项中
|
|
115
80
|
this.pushRouterInfo(buildProfileOpt, this.plugin.routerMap);
|
|
116
|
-
// 将构建配置选项设置到moduleContext中
|
|
117
81
|
this.moduleContext.setBuildProfileOpt(buildProfileOpt);
|
|
118
82
|
}
|
|
119
|
-
// 将路由信息添加到 buildProfileOpt 中
|
|
120
83
|
pushRouterInfo(buildProfileOpt, routerMap) {
|
|
121
84
|
const sources = buildProfileOpt.buildOption.arkOptions.runtimeOnly.sources;
|
|
122
85
|
routerMap.forEach((item) => {
|
|
@@ -129,7 +92,6 @@ class HMRouterPluginHandle {
|
|
|
129
92
|
}
|
|
130
93
|
});
|
|
131
94
|
}
|
|
132
|
-
// 读取配置
|
|
133
95
|
readConfig() {
|
|
134
96
|
let levels = 0;
|
|
135
97
|
let configParam = {};
|
|
@@ -145,4 +107,3 @@ class HMRouterPluginHandle {
|
|
|
145
107
|
}
|
|
146
108
|
}
|
|
147
109
|
exports.HMRouterPluginHandle = HMRouterPluginHandle;
|
|
148
|
-
//# sourceMappingURL=HMRouterPluginHandle.js.map
|