neo-cmp-cli 1.5.5-beta.2 → 1.5.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
CHANGED
|
@@ -37,9 +37,6 @@ neo init -t=react-ts
|
|
|
37
37
|
# 创建自定义组件项目
|
|
38
38
|
neo createProject
|
|
39
39
|
|
|
40
|
-
# 也可以根据模板创建自定义组件项目
|
|
41
|
-
neo init
|
|
42
|
-
|
|
43
40
|
# 在当前项目中创建一个自定义组件
|
|
44
41
|
neo createCmp
|
|
45
42
|
|
|
@@ -82,12 +79,10 @@ npm run pushCmp
|
|
|
82
79
|
|
|
83
80
|
## 常用命令说明
|
|
84
81
|
- **neo init**: 交互式创建自定义组件(支持 -t、--name)。
|
|
85
|
-
- **neo
|
|
86
|
-
- **neo createCmp**: 在当前项目中创建一个自定义组件(支持 --name)。
|
|
87
|
-
- **neo preview**: 本地预览自定义组件内容(支持 --name),默认支持热更新与接口代理。
|
|
82
|
+
- **neo preview**: 本地预览自定义组件内容,默认支持热更新与接口代理。
|
|
88
83
|
- **neo linkDebug**: 外链调试模式,在平台端页面设计器中调试自定义组件。
|
|
89
|
-
- **neo publish2oss**:
|
|
90
|
-
- **neo pushCmp**: 构建并发布到NeoCRM
|
|
84
|
+
- **neo publish2oss**: 构建并上传到对象存储(可自定义配置对象存储)。
|
|
85
|
+
- **neo pushCmp**: 构建并发布到NeoCRM平台(需自行添加授权配置)。
|
|
91
86
|
|
|
92
87
|
## 开发须知
|
|
93
88
|
#### 1)默认自动识别自定义组件
|
package/package.json
CHANGED
package/src/cmpUtils/pushCmp.js
CHANGED
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const AdmZip = require('adm-zip');
|
|
3
4
|
const _ = require('lodash');
|
|
4
5
|
const { catchCurPackageJson } = require('../utils/pathUtils');
|
|
5
6
|
const getConfigObj = require('../utils/getConfigObj');
|
|
6
7
|
const ora = require('ora');
|
|
7
8
|
const NeoService = require('../neo/neoService');
|
|
8
9
|
const { consoleTag } = require('../utils/neoParams');
|
|
9
|
-
const createCmpProjectZip = require('../projectUtils/createCmpProjectZip');
|
|
10
10
|
|
|
11
11
|
// 获取当前项目的package文件
|
|
12
12
|
const currentPackageJsonDir = catchCurPackageJson();
|
|
13
13
|
const currentPackageJson = getConfigObj(currentPackageJsonDir);
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* 将构建产物打包成 zip 文件
|
|
17
|
+
* @param {string} assetsRoot 构建产物的目录
|
|
18
|
+
* @returns {Promise<string>} zip 文件路径
|
|
19
|
+
*/
|
|
20
|
+
const createZipPackage = async (assetsRoot) => {
|
|
21
|
+
if (!fs.existsSync(assetsRoot)) {
|
|
22
|
+
throw new Error(`assetsRoot 不存在: ${assetsRoot}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const files = fs.readdirSync(assetsRoot);
|
|
26
|
+
const zip = new AdmZip();
|
|
27
|
+
|
|
28
|
+
files.forEach((file) => {
|
|
29
|
+
const filePath = path.join(assetsRoot, file);
|
|
30
|
+
const fileStat = fs.statSync(filePath);
|
|
31
|
+
if (fileStat.isFile()) {
|
|
32
|
+
// 只添加 .js 文件
|
|
33
|
+
if (file.endsWith('.js')) {
|
|
34
|
+
zip.addLocalFile(filePath);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const zipPath = path.join(assetsRoot, `${currentPackageJson.name}.zip`);
|
|
40
|
+
zip.writeZip(zipPath);
|
|
41
|
+
console.info(`已创建 zip 文件: ${zipPath}`);
|
|
42
|
+
|
|
43
|
+
return zipPath;
|
|
44
|
+
};
|
|
45
|
+
|
|
15
46
|
/**
|
|
16
47
|
* 获取技术栈标识
|
|
17
48
|
* 目的:兼容用户非标准写法
|
|
@@ -171,22 +202,24 @@ const pushCmp = async (config, cmpType) => {
|
|
|
171
202
|
spinner.text = '发布自定义组件:初始化 NeoService...';
|
|
172
203
|
const neoService = new NeoService(config);
|
|
173
204
|
|
|
174
|
-
// 步骤 2:
|
|
175
|
-
spinner.text = '发布自定义组件:打包源码文件(含单个自定义组件源码)...';
|
|
176
|
-
createCmpProjectZip(cmpType, process.cwd(), config.assetsRoot);
|
|
177
|
-
|
|
178
|
-
// 步骤 3: 上传构建后资源文件
|
|
205
|
+
// 步骤 2: 上传构建后资源文件
|
|
179
206
|
spinner.text = '发布自定义组件:上传自定义组件构建产物到 OSS...';
|
|
180
207
|
const cmpInfo = await neoService.publish2oss(cmpType);
|
|
181
208
|
|
|
182
|
-
|
|
209
|
+
/*
|
|
210
|
+
// 步骤 3: 打包文件(打包单个自定义组件源码)
|
|
211
|
+
spinner.text = '发布自定义组件:打包文件(打包单个自定义组件源码)...';
|
|
212
|
+
const zipPath = await createZipPackage(assetsRoot);
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
// 步骤 4: 构建组件数据
|
|
183
216
|
spinner.text = '发布自定义组件:构建组件数据...';
|
|
184
217
|
const componentInfo = await buildComponentData(config.assetsRoot, cmpInfo);
|
|
185
218
|
if (!componentInfo) {
|
|
186
219
|
throw new Error(`构建组件数据失败,未获取到自定义组件模型信息。(${cmpType})`);
|
|
187
220
|
}
|
|
188
221
|
|
|
189
|
-
// 步骤
|
|
222
|
+
// 步骤 5: 保存组件信息
|
|
190
223
|
spinner.text = '发布自定义组件:保存组件信息...';
|
|
191
224
|
await neoService.updateCustomComponent(componentInfo);
|
|
192
225
|
|
package/src/neo/neoService.js
CHANGED
|
@@ -334,9 +334,9 @@ class NeoService {
|
|
|
334
334
|
* 将构建产物上传到 NeoCRM 平台端
|
|
335
335
|
*
|
|
336
336
|
* @param {object} cmpType 自定义组件名称
|
|
337
|
-
* @param {array} fileExtensions 需要上传的文件类型,默认 ['.js', '.css'
|
|
337
|
+
* @param {array} fileExtensions 需要上传的文件类型,默认 ['.js', '.css']
|
|
338
338
|
*/
|
|
339
|
-
async publish2oss(cmpType, fileExtensions = ['.js', '.css'
|
|
339
|
+
async publish2oss(cmpType, fileExtensions = ['.js', '.css']) {
|
|
340
340
|
if (!cmpType) {
|
|
341
341
|
console.error(`自定义组件名称不能为空: ${cmpType}`);
|
|
342
342
|
return;
|
|
@@ -375,8 +375,6 @@ class NeoService {
|
|
|
375
375
|
curCmpInfo.modelAsset = fileUrl;
|
|
376
376
|
} else if (file.endsWith('.css')) {
|
|
377
377
|
curCmpInfo.cssAsset = fileUrl;
|
|
378
|
-
} else if (file.endsWith('.zip')) {
|
|
379
|
-
curCmpInfo.source = fileUrl;
|
|
380
378
|
} else {
|
|
381
379
|
curCmpInfo.asset = fileUrl;
|
|
382
380
|
}
|
|
@@ -5,10 +5,9 @@ const path = require('path');
|
|
|
5
5
|
* 判断当前是否存在 neo 项目
|
|
6
6
|
* 备注:neo.config.js 和 package.json 必须同时存在才算作 neo 项目
|
|
7
7
|
*/
|
|
8
|
-
module.exports = function (
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const packagePath = path.resolve(projectPath, 'package.json');
|
|
8
|
+
module.exports = function () {
|
|
9
|
+
const neoConfigPath = path.resolve(process.cwd(), 'neo.config.js');
|
|
10
|
+
const packagePath = path.resolve(process.cwd(), 'package.json');
|
|
12
11
|
|
|
13
12
|
if (fs.existsSync(neoConfigPath) && fs.existsSync(packagePath)) {
|
|
14
13
|
return true;
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const AdmZip = require('adm-zip');
|
|
4
|
-
const { consoleTag } = require('../utils/neoParams'); // 输出标记
|
|
5
|
-
const hasNeoProject = require('./hasNeoProject');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 创建自定义组件源码 zip 包
|
|
9
|
-
* @param {*} cmpType 自定义组件名称
|
|
10
|
-
* @returns {string} zip 文件路径
|
|
11
|
-
*/
|
|
12
|
-
module.exports = function (cmpType, _projectPath, assetsRoot) {
|
|
13
|
-
const projectRoot = _projectPath || process.cwd();
|
|
14
|
-
const finalAssetsRoot = assetsRoot || path.join(projectRoot, 'dist');
|
|
15
|
-
|
|
16
|
-
if (!hasNeoProject(_projectPath)) {
|
|
17
|
-
console.error(`${consoleTag}当前目录不是自定义组件项目,请在自定义组件项目目录下执行。`);
|
|
18
|
-
process.exit(1);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!cmpType) {
|
|
22
|
-
console.error(`${consoleTag}自定义组件名称不能为空`);
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const zip = new AdmZip();
|
|
27
|
-
|
|
28
|
-
// 需要排除的目录和文件
|
|
29
|
-
const excludeDirs = ['node_modules', '.neo-cli', 'dist'];
|
|
30
|
-
const excludeFiles = ['.eslintcache', 'auth.config.js'];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 判断文件/目录是否应该被排除
|
|
34
|
-
* @param {string} filePath 文件路径
|
|
35
|
-
* @param {string} relativePath 相对路径
|
|
36
|
-
* @returns {boolean} 是否应该排除
|
|
37
|
-
*/
|
|
38
|
-
const shouldExclude = (filePath, relativePath) => {
|
|
39
|
-
const name = path.basename(filePath);
|
|
40
|
-
const stat = fs.statSync(filePath);
|
|
41
|
-
|
|
42
|
-
// 排除指定的目录
|
|
43
|
-
if (stat.isDirectory() && excludeDirs.includes(name)) {
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// 排除指定的文件
|
|
48
|
-
if (stat.isFile() && excludeFiles.includes(name)) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// 对于 src/components 目录,只包含 cmpType 子目录
|
|
53
|
-
// 处理逻辑:如果路径是 src/components/xxx,且 xxx 不是 cmpType,则排除
|
|
54
|
-
if (relativePath.startsWith('src/components')) {
|
|
55
|
-
const relativeToComponents = path.relative('src/components', relativePath);
|
|
56
|
-
// 如果相对路径不为空,说明已经在 components 的子目录中
|
|
57
|
-
if (relativeToComponents && relativeToComponents !== '.') {
|
|
58
|
-
const firstPart = relativeToComponents.split(path.sep)[0];
|
|
59
|
-
// 如果第一个部分不是 cmpType,则排除
|
|
60
|
-
if (firstPart !== cmpType) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return false;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* 递归遍历目录并添加到 zip
|
|
71
|
-
* @param {string} dirPath 目录路径
|
|
72
|
-
* @param {string} relativePath 相对路径(用于 zip 中的路径)
|
|
73
|
-
*/
|
|
74
|
-
const addDirectoryToZip = (dirPath, relativePath = '') => {
|
|
75
|
-
try {
|
|
76
|
-
const items = fs.readdirSync(dirPath);
|
|
77
|
-
|
|
78
|
-
items.forEach((item) => {
|
|
79
|
-
const itemPath = path.join(dirPath, item);
|
|
80
|
-
const itemRelativePath = relativePath ? path.join(relativePath, item) : item;
|
|
81
|
-
|
|
82
|
-
// 检查是否应该排除
|
|
83
|
-
if (shouldExclude(itemPath, itemRelativePath)) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const stat = fs.statSync(itemPath);
|
|
88
|
-
|
|
89
|
-
if (stat.isDirectory()) {
|
|
90
|
-
// 递归处理子目录
|
|
91
|
-
addDirectoryToZip(itemPath, itemRelativePath);
|
|
92
|
-
} else if (stat.isFile()) {
|
|
93
|
-
// 添加文件到 zip,保持相对路径结构
|
|
94
|
-
const fileContent = fs.readFileSync(itemPath);
|
|
95
|
-
zip.addFile(itemRelativePath, fileContent);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
} catch (error) {
|
|
99
|
-
console.error(`${consoleTag}遍历目录失败 (${dirPath}):`, error.message);
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// 开始遍历项目根目录
|
|
104
|
-
addDirectoryToZip(projectRoot);
|
|
105
|
-
|
|
106
|
-
// 生成 zip 文件名
|
|
107
|
-
const zipFileName = `${cmpType}-source.zip`;
|
|
108
|
-
const zipPath = path.join(finalAssetsRoot, zipFileName);
|
|
109
|
-
|
|
110
|
-
// 如果已存在同名 zip 文件,先删除
|
|
111
|
-
if (fs.existsSync(zipPath)) {
|
|
112
|
-
fs.removeSync(zipPath);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// 写入 zip 文件
|
|
116
|
-
zip.writeZip(zipPath);
|
|
117
|
-
|
|
118
|
-
console.log(`${consoleTag}已创建自定义组件源码 zip 包: ${zipFileName}`);
|
|
119
|
-
|
|
120
|
-
return zipPath;
|
|
121
|
-
};
|
package/test/demo2.js
DELETED