crabatool 1.0.62 → 1.0.65

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/lib/config.js CHANGED
@@ -6,6 +6,9 @@ class Config {
6
6
  constructor() {
7
7
  this.reportHost = "http://crabadoc.ca.com"; // 用于接收检测报告的服务器,可配置的。由于产品没有提供服务,目前统一放到平台的文档服务器
8
8
  this.webhooks = "https://oapi.dingtalk.com/robot/send?access_token=ce27b1b1540881540d44c0bd05ba738d865363758892ede137dc1020bd36bd5a";
9
+ this.crabaHooks = "https://oapi.dingtalk.com/robot/send?access_token=ce27b1b1540881540d44c0bd05ba738d865363758892ede137dc1020bd36bd5a";
10
+ //this.webhooks = "https://oapi.dingtalk.com/robot/send?access_token=37279df60e03ebf25e8eb71230ddb93fe74de99951a8d635d0458e60bfcd44d8";
11
+ this.checkgspx = true; // 检查gspx
9
12
 
10
13
  this.Version = pg.version;
11
14
  this.Debug = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crabatool",
3
- "version": "1.0.62",
3
+ "version": "1.0.65",
4
4
  "description": "crabatool",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -26,7 +26,8 @@
26
26
  "axios": "^0.27.2",
27
27
  "iconv-jschardet": "^2.0.26",
28
28
  "compressing": "^1.6.0",
29
- "@jslint-org/jslint": "^2022.5.20"
29
+ "@jslint-org/jslint": "^2022.5.20",
30
+ "htmlparser2": "^8.0.1"
30
31
  },
31
32
  "repository": {
32
33
  "type": "git",
@@ -0,0 +1,96 @@
1
+ var utils = require('../lib/utils.js');
2
+ var config = require('../lib/config.js');
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+ var htmlparser2 = require('htmlparser2');
6
+ var warnTags = ['VPanel', 'HPanel', 'HiddenColumn', 'Hblock', 'Vblock']; // 'div', 'table', 'tr', 'td', 'br','HiddenField', 'CloseButton', 'CancelButton'];
7
+
8
+ module.exports.getResults = function() {
9
+ var data = {
10
+ count: 0,
11
+ tags: {},
12
+ tagList: [],
13
+ warnList: {},
14
+ errorList: []
15
+ };
16
+ if (!config.checkgspx) return data;
17
+
18
+ var gspxFiles = utils.getFiles({ source: config.webPath, exts: '.gspx' });
19
+ data.count = gspxFiles.length;
20
+
21
+ gspxFiles.forEach(function(filePath) {
22
+ readGspxToJSON(filePath, data);
23
+ });
24
+
25
+ Object.keys(data.tags).forEach((tag, index) => {
26
+ data.tagList.push({ name: tag, count: data.tags[tag] });
27
+ });
28
+ data.tagList.sort(function(item0, item1) {
29
+ return item0.count > item1.count ? -1 : 1;
30
+ });
31
+ return data;
32
+ }
33
+
34
+ function readGspxToJSON(fileName, data) {
35
+ var rootNode;
36
+ var stack = [];
37
+ var node;
38
+ var byte = fs.readFileSync(fileName);
39
+ var gspxXML = utils.toUtf8(byte);
40
+
41
+ fileName = fileName.replace(config.webPath, ''); // 简化文件路径
42
+ function HtmlParser2ToXml(xml) {
43
+ var parser = new htmlparser2.Parser({
44
+ onopentag: function(name, attrs) {
45
+ node = {};
46
+ node.Name = name;
47
+ node.Attributes = attrs;
48
+ stack.push(node);
49
+
50
+ // 标签使用统计
51
+ if (data.tags[name] === undefined) {
52
+ data.tags[name] = 1;
53
+ } else {
54
+ data.tags[name]++;
55
+ }
56
+
57
+ // 建议优化页面汇总
58
+ if (warnTags.includes(name)) {
59
+ if (!data.warnList[fileName]) data.warnList[fileName] = [];
60
+ data.warnList[fileName].push(name);
61
+ }
62
+ },
63
+ ontext: function(text) {
64
+ if (text != null && text.trim() != '') {
65
+ node.Value = text;
66
+ }
67
+ },
68
+ onclosetag: function(tagname) {
69
+ var pNode = stack.pop();
70
+ if (stack.length == 0) {
71
+ rootNode = pNode;
72
+ } else {
73
+ var parentNode = stack[stack.length - 1];
74
+ if (!parentNode.Childs) parentNode.Childs = [];
75
+ parentNode.Childs.push(pNode);
76
+ }
77
+ },
78
+ onerror: function(error) {
79
+ console.log("read " + fileName + " " + error);
80
+
81
+ // 异常文件统计
82
+ data.errorList.push({ fileName: fileName, tag: node.Name, error: error });
83
+ }
84
+ }, {
85
+ lowerCaseTags: false,
86
+ lowerCaseAttributeNames: false,
87
+ xmlMode: true
88
+ });
89
+ parser.write(gspxXML);
90
+ parser.end();
91
+ }
92
+
93
+ HtmlParser2ToXml(gspxXML);
94
+
95
+ return rootNode;
96
+ }
package/tool/checkjs.js CHANGED
@@ -5,23 +5,25 @@ var ProgressBar = require('./progressbar.js');
5
5
  var jschardet = require('iconv-jschardet');
6
6
  var path = require('path');
7
7
  var axios = require('axios');
8
+ var gspx = require('./checkgspx.js');
9
+
10
+ // js超过多少kb给与提示
11
+ var fileSize = 300;
12
+ // 默认忽略大小的文件
13
+ var sizeBlackList = ['craba.min.js', 'crabaEx.min.js', 'crabaNgp.js', 'echarts-all.js', 'echarts.min.js', 'math.min.js'];
14
+ // 语法规则,不能包含这些关键词
15
+ var dangerousJs = ['\\slet\\s', '\\sconst\\s', '\=\>\\s?\\(?\\{', '\\sasync\\s', '\\sawait\\s', '\\.then\\(', '\\sdebugger\\s'];
16
+
8
17
 
9
18
  module.exports.start = function() {
10
19
  var jsFiles = utils.getFiles({ source: config.webPath, exts: '.js', ignores: config.ignoreCheck });
11
20
 
12
- var fileSize = 300;
13
21
  var errList = [];
14
22
  var errRegList = [];
15
23
  var bigList = [];
16
24
  var notUtf8List = [];
17
25
  var utf8List = [];
18
26
 
19
- // 默认忽略大小的文件
20
- var sizeBlackList = ['craba.min.js', 'crabaEx.min.js', 'crabaNgp.js', 'echarts-all.js', 'echarts.min.js', 'math.min.js'];
21
-
22
- // 语法规则,不能包含这些关键词
23
- var dangerousJs = ['\\slet\\s', '\\sconst\\s', '\=\>\\s?\\(?\\{', '\\sasync\\s', '\\sawait\\s', '\\.then\\(', '\\sdebugger\\s'];
24
-
25
27
  // 开始检测
26
28
  var pb = new ProgressBar('检查进度', jsFiles.length);
27
29
  jsFiles.forEach(function(filePath) {
@@ -73,12 +75,17 @@ module.exports.start = function() {
73
75
  });
74
76
  pb.clear('检验完成');
75
77
 
78
+ // 检查gspx
79
+ var gspxData = gspx.getResults();
80
+
76
81
  // 生成检测报告 markdown语法
77
- var status = '健康';
78
- if (errList.length > 0 || notUtf8List.length > 0) {
82
+ var warnPages = Object.keys(gspxData.warnList).length;
83
+ var status = '无异常';
84
+ if (errList.length > 0 || notUtf8List.length > 0 || warnPages > 0 || gspxData.errorList.length > 0) {
79
85
  status = '有异常';
80
86
  }
81
87
 
88
+
82
89
  var modName = getModName();
83
90
  var webhookList = [];
84
91
  var info = [];
@@ -91,10 +98,11 @@ module.exports.start = function() {
91
98
  info.push(`| 生成报告时间 | ${new Date().toString()} |`);
92
99
  info.push(`| 网站路径 | ${config.webPath} |`);
93
100
  info.push(`| 共检查 | ${jsFiles.length}个js文件 |`);
101
+ info.push(`| 共检查 | ${gspxData.count}个gspx文件 |`);
94
102
  info.push(`| 忽略目录和文件 | ${config.ignoreCheck ? config.ignoreCheck.join('、') : '无' + ' |'}`);
95
103
 
96
- info.push("# 异常报表");
97
- info.push("| 异常类型 | 数量 |");
104
+ info.push("# 检测报表");
105
+ info.push("| 类型 | 数量 |");
98
106
  info.push("| ------ | ------ |");
99
107
  info.push(`| 语法异常文件数 | ${errList.length}个 |`);
100
108
  //webhookList.push(`## 自定义规则`);
@@ -109,7 +117,11 @@ module.exports.start = function() {
109
117
  webhookList.push(`1. 超过${fileSize}kb的文件数:${bigList.length}个`);
110
118
  }
111
119
 
112
- //webhookList.push(`## jslint规则`);
120
+ info.push(`| gspx建议优化数 | ${warnPages}个 |`);
121
+ info.push(`| gspx错误数 | ${gspxData.errorList.length}个 |`);
122
+
123
+ webhookList.push(`1. gspx建议优化数:${warnPages}个`);
124
+ webhookList.push(`1. gspx出错数:${gspxData.errorList.length}个`);
113
125
 
114
126
 
115
127
  // 代码质量管理需要格式
@@ -120,7 +132,7 @@ module.exports.start = function() {
120
132
  var detail = [];
121
133
  if (errList.length > 0) {
122
134
  detail.push("");
123
- detail.push('# 语法异常文件清单如下');
135
+ detail.push('# js语法异常文件清单如下');
124
136
  errList.forEach((s, index) => {
125
137
 
126
138
  detail.push(`## ${index + 1}. ${s}`);
@@ -155,6 +167,33 @@ module.exports.start = function() {
155
167
  });
156
168
  }
157
169
 
170
+ if (gspxData.errorList.length > 0) {
171
+ detail.push(`# 出错误页面清单如下`);
172
+ gspxData.errorList.forEach((info, index) => {
173
+ detail.push(`## ${index + 1}. ${info.name}`);
174
+ detail.push(`> 错误标签: ${info.tag}`);
175
+ detail.push(`> 错误描述:${info.error}`);
176
+ });
177
+ }
178
+
179
+ if (warnPages > 0) {
180
+ detail.push(`# 建议优化gspx页面清单如下`);
181
+ Object.keys(gspxData.warnList).forEach((key, index) => {
182
+ var tags = gspxData.warnList[key];
183
+
184
+ detail.push(`## ${index + 1}. ${key}`); 4
185
+ detail.push(`> 此页面建议优化标签明细: ${tags.join('、')}`);
186
+ });
187
+ }
188
+
189
+ detail.push('# 本项目标签使用情况汇总');
190
+ detail.push("| 标签名称 | 使用次数 |");
191
+ detail.push("| ----- | ------ |");
192
+ gspxData.tagList.forEach((item, index) => {
193
+ detail.push(`| ${item.name} | ${item.count} |`);
194
+ });
195
+
196
+
158
197
  // 推送报告到钉钉和文档服务器端
159
198
  var id = modName + '_' + new Date().getTime();
160
199
  var reportUrl = getReportUrl(id);
@@ -162,9 +201,9 @@ module.exports.start = function() {
162
201
  postReport(id, reportUrl, content, sonar);
163
202
 
164
203
  // 推送到钉钉
165
- //if (status != '健康') { // 检查结果检查就不发到钉钉了; ps:健康也发到钉钉,鼓励开发继续保持;
166
- postWebhooks(id, reportUrl, webhookList);
167
- //}
204
+ if (status != '无异常') { // 检查结果检查就不发到钉钉了; ps:健康也发到钉钉,鼓励开发继续保持;
205
+ postWebhooks(id, reportUrl, webhookList);
206
+ }
168
207
  }
169
208
 
170
209
  function getMathReuslts(content, nreg, filterFun) {
@@ -274,4 +313,20 @@ function postWebhooks(id, reportUrl, webhookList) {
274
313
  console.log("推送代码检测失败");
275
314
  console.log(error);
276
315
  });
316
+
317
+ // 如果业务配置的推送地址不是平台群,需要统一推送到平台,汇总一下问题,方便后期统筹
318
+ if (config.webhooks != config.crabaHooks) {
319
+ axios({
320
+ method: 'post',
321
+ url: config.crabaHooks,
322
+ data: data,
323
+ headers: { 'Content-Type': 'application/json' }
324
+ }).then(function(response) {
325
+ console.log("推送代码检测状态");
326
+ console.log(response.data);
327
+ }).catch(function(error) {
328
+ console.log("推送代码检测失败");
329
+ console.log(error);
330
+ });
331
+ }
277
332
  }
package/tool/start.js CHANGED
@@ -24,7 +24,7 @@ class Start {
24
24
  "1. 启动服务。\t\t\t\t主要包含:自动合并打包init.js和biz.js,查看本地平台的版本",
25
25
  "2. 更新当前项目的平台,然后启动服务。\t主要包含:从<内网>拉取环境相关资源,再拷贝到webPath路径下覆盖老文件,替代手工操作,同时解决npm不稳定问题",
26
26
  "3. 查询最新平台版本和日期。\t\t主要包含:从<内网>拉取最新平台版本,开发好及时更新补丁",
27
- "4. 校验当前项目前端所有js语法兼容性。\t主要包含:对本地js语法做一次初步预检避免上线后才发现问题;比如:编码、let、const、=>、async、await、then、缺function",
27
+ "4. 校验当前项目前端js语法和兼容性,以及gspx检查。\t主要包含:对本地js语法做一次初步预检避免上线后才发现问题;比如:编码、let、const、=>、async、await、then、缺function",
28
28
  "5. 打包当前项目前端所有js。\t\t主要包含:前端es6语法的打包和js的统一压缩处理",
29
29
  "6. 安装或更新IDEA环境。\t\t\t主要包含:从<内网>拉取环境相关资源,包括智能语法、新增页面模板、更多新功能",
30
30
  "7. 安装或更新vscode环境。\t\t主要包含:从<内网>拉取环境相关资源,包括智能语法、新增页面模板、ctrl+alt+n、alt+j快捷键",
@@ -83,6 +83,7 @@ class Start {
83
83
  bindConfigByArgv('-childModList', 'array');
84
84
  bindConfigByArgv('-ignoreCompress', 'boolean');
85
85
  bindConfigByArgv('-Debug', 'boolean');
86
+ bindConfigByArgv('-checkgspx', 'boolean');
86
87
 
87
88
  if (!config.webPath) {
88
89
  throw new Error('请检查craba.js,必须告诉工具当前项目的前端路径地址,填绝对路径哦');