@tmsfe/tmskit 0.0.18 → 0.0.21
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/CHANGELOG.md +7 -1
- package/dist/index.cjs.js +1440 -1045
- package/package.json +10 -8
- package/src/{init.js → check.js} +2 -3
- package/src/compile/build.js +2 -2
- package/src/compile/dev.js +32 -33
- package/src/compile/watch.js +31 -12
- package/src/config/constant.js +29 -3
- package/src/core/buildAppJson.js +14 -21
- package/src/core/cache.js +36 -0
- package/src/core/checkDependencies.js +38 -21
- package/src/core/cloneModules.js +5 -7
- package/src/core/handleError.js +7 -1
- package/src/core/npm.js +12 -9
- package/src/core/symbolicLink.js +17 -19
- package/src/core/tmsMpconfig.js +183 -94
- package/src/entry.js +4 -4
- package/src/index.js +18 -4
- package/src/scripts/create/generator.js +1 -2
- package/src/scripts/create/index.js +73 -32
- package/src/scripts/run/build/index.js +5 -4
- package/src/scripts/run/cloud/index.js +0 -2
- package/src/scripts/run/dev/index.js +15 -14
- package/src/scripts/run/index.js +43 -59
- package/src/scripts/run/init/index.js +13 -36
- package/src/scripts/run/install/index.js +113 -23
- package/src/utils/md5.js +25 -0
- package/src/utils/widgets.js +23 -0
- package/src/core/isInIt.js +0 -65
package/src/core/symbolicLink.js
CHANGED
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const { resolve } = require('../utils/widgets');
|
|
3
|
-
const { handleError } = require('./handleError');
|
|
4
3
|
const { ensureDirExist } = require('../utils/io');
|
|
5
|
-
const { warn } = require('../utils/log');
|
|
4
|
+
const { warn, succeed } = require('../utils/log');
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* 根据相关配置创建软链接
|
|
9
8
|
* @param { object } tmsConfig
|
|
10
9
|
*/
|
|
11
10
|
const symLink = (tmsConfig) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const targetPath = resolve(tmsConfig.cloudDir, item.name);
|
|
11
|
+
ensureDirExist(resolve(tmsConfig.cloudDir));
|
|
12
|
+
if (tmsConfig.cloudModules) {
|
|
13
|
+
tmsConfig.cloudModules.forEach((item) => {
|
|
14
|
+
const sourcePath = resolve(item.path);
|
|
15
|
+
const targetPath = resolve(tmsConfig.cloudDir, item.name);
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
17
|
+
if (!fs.existsSync(sourcePath)) {
|
|
18
|
+
warn(`云函数${sourcePath}不存在`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!fs.existsSync(targetPath)) {
|
|
22
|
+
fs.symlinkSync(sourcePath, targetPath);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
succeed('云函数创建软链成功');
|
|
26
|
+
} else {
|
|
27
|
+
warn('你没有在tms.config.js的cloudModules注册云函数');
|
|
30
28
|
}
|
|
31
29
|
};
|
|
32
30
|
|
package/src/core/tmsMpconfig.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 用来读取处理tms.config.js与module.config.json字段
|
|
3
3
|
*/
|
|
4
|
+
/* eslint-disable no-param-reassign, no-nested-ternary */
|
|
4
5
|
const loadash = require('lodash');
|
|
5
6
|
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
6
8
|
const { TMS_CONFIG_FILENAME, MODULE_CONFIG_FILENAME, TMS_PRIVATE_FILENAME } = require('../config/constant');
|
|
7
|
-
const { resolve, isObject, isArray } = require('../utils/widgets');
|
|
9
|
+
const { resolve, isObject, isArray, getAbsolutePath } = require('../utils/widgets');
|
|
8
10
|
const defaultTmsConfig = require('../config/defaultTmsConfig');
|
|
9
11
|
const { fail } = require('../utils/log');
|
|
10
12
|
|
|
@@ -12,20 +14,17 @@ const { fail } = require('../utils/log');
|
|
|
12
14
|
* 读取tms.config.js
|
|
13
15
|
* @param env {string} 环境变量
|
|
14
16
|
*/
|
|
15
|
-
const readTmsConfig = function (
|
|
17
|
+
const readTmsConfig = function () {
|
|
16
18
|
const tmsConfigPath = resolve(TMS_CONFIG_FILENAME);
|
|
17
19
|
if (!fs.existsSync(tmsConfigPath)) {
|
|
18
20
|
fail('当前执行目录没有tms.config.js的配置项,请进行配置');
|
|
19
21
|
process.exit(1);
|
|
20
22
|
}
|
|
21
23
|
const tmsConfigFn = require(tmsConfigPath);
|
|
22
|
-
const tmsConfig = tmsConfigFn(
|
|
23
|
-
env,
|
|
24
|
-
});
|
|
25
|
-
// 合并默认值
|
|
26
|
-
loadash.mergeWith(tmsConfig, defaultTmsConfig);
|
|
24
|
+
const tmsConfig = typeof tmsConfigFn === 'function' ? tmsConfigFn() : tmsConfigFn;
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
// 合并默认值
|
|
27
|
+
return loadash.mergeWith(defaultTmsConfig, tmsConfig);
|
|
29
28
|
};
|
|
30
29
|
|
|
31
30
|
|
|
@@ -36,30 +35,53 @@ const readTmsPrivateCf = function () {
|
|
|
36
35
|
let tmsPrivateCf = {};
|
|
37
36
|
const tmsPrivatePath = resolve(TMS_PRIVATE_FILENAME);
|
|
38
37
|
if (fs.existsSync(tmsPrivatePath)) {
|
|
39
|
-
|
|
38
|
+
const tmsPrivateFn = require(tmsPrivatePath);
|
|
39
|
+
tmsPrivateCf = typeof tmsPrivateFn === 'function' ? tmsPrivateFn() : tmsPrivateFn;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
return tmsPrivateCf;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* 获取tms.config.js, tms.private.config.js的配置项
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
const getTmsConfig = () => {
|
|
50
|
+
const tmsPrivateCf = readTmsPrivateCf();
|
|
51
|
+
const tmsConfig = readTmsConfig();
|
|
52
|
+
|
|
53
|
+
const modules = {};
|
|
54
|
+
if (Array.isArray(tmsConfig.modules)) {
|
|
55
|
+
modules.all = tmsConfig.modules;
|
|
56
|
+
tmsConfig.modules = modules;
|
|
57
|
+
}
|
|
58
|
+
// 合并默认值
|
|
59
|
+
const res = loadash.mergeWith(tmsConfig, tmsPrivateCf, (objValue, srcValue) => {
|
|
60
|
+
if (loadash.isArray(objValue) && objValue[0] && loadash.isObject(objValue[0])) {
|
|
61
|
+
return objValue.concat(srcValue);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return res;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 根据moduleNames获取modules
|
|
47
70
|
* @param { object } tmsConfig
|
|
48
|
-
* @param { array }
|
|
71
|
+
* @param { array } moduleNames
|
|
72
|
+
* @param {boolean} errorIsQuit 找不到配置文件是否退出
|
|
49
73
|
* @returns
|
|
50
74
|
*/
|
|
51
|
-
const
|
|
75
|
+
const getModulesByModuleNames = function (tmsConfig, moduleNames = []) {
|
|
52
76
|
const targetModules = [];
|
|
53
|
-
|
|
54
|
-
const module = tmsConfig.modules.all.find(module => module.
|
|
55
|
-
|
|
77
|
+
moduleNames.forEach((moduleName) => {
|
|
78
|
+
const module = tmsConfig.modules.all.find(module => module.moduleName === moduleName);
|
|
79
|
+
if (!module) {
|
|
80
|
+
throw new Error(`你启动的模块${moduleName}在tms.config.js的modules.all中没有注册`);
|
|
81
|
+
}
|
|
82
|
+
targetModules.push(module);
|
|
56
83
|
});
|
|
57
84
|
|
|
58
|
-
if (targetModules.length === 0) {
|
|
59
|
-
fail(`你启动的模块无效${modules.join(',')}无效,请检查tms.config.json>modules>${modules.join(',')}
|
|
60
|
-
>name字段与module.config.json的name字段是否一致`);
|
|
61
|
-
isQuit && process.exit(1);
|
|
62
|
-
}
|
|
63
85
|
return targetModules;
|
|
64
86
|
};
|
|
65
87
|
|
|
@@ -80,7 +102,7 @@ function adaptMpCgContent(fileContent, appName) {
|
|
|
80
102
|
return res;
|
|
81
103
|
};
|
|
82
104
|
|
|
83
|
-
let content =
|
|
105
|
+
let content = fileContent;
|
|
84
106
|
|
|
85
107
|
if (isArray(content)) {
|
|
86
108
|
let i = content.length - 1;
|
|
@@ -94,108 +116,175 @@ function adaptMpCgContent(fileContent, appName) {
|
|
|
94
116
|
return content;
|
|
95
117
|
}
|
|
96
118
|
|
|
119
|
+
const adaptDependencies = function (dependencies, subPackages) {
|
|
120
|
+
const newDependencies = dependencies || [];
|
|
121
|
+
subPackages.forEach((item) => {
|
|
122
|
+
if (item.dependencies) {
|
|
123
|
+
dependencies = newDependencies.concat(item.dependencies);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return newDependencies;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const adaptSubPackages = function (moduleConfig, appName) {
|
|
130
|
+
const subPackages = isObject(moduleConfig) && moduleConfig.subPackages
|
|
131
|
+
? moduleConfig.subPackages
|
|
132
|
+
: isObject(moduleConfig) ? [moduleConfig] : moduleConfig;
|
|
133
|
+
return adaptMpCgContent(subPackages, appName);
|
|
134
|
+
};
|
|
135
|
+
|
|
97
136
|
/**
|
|
98
|
-
*
|
|
137
|
+
* 获取模块module.config.json中的配置信息
|
|
99
138
|
* @param {array} modules 用户要编译的模块列表
|
|
100
139
|
* @param { string } appName 小程序的名称
|
|
101
|
-
* @param { string } moduleConfigFilename moduleConfig的文件名
|
|
102
140
|
*/
|
|
103
|
-
function
|
|
104
|
-
const modulesConfig =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
141
|
+
function getModulesConfig(modules = [], appName) {
|
|
142
|
+
const modulesConfig = [];
|
|
143
|
+
modules.forEach((moduleItem) => {
|
|
144
|
+
const moduleConfigPath = resolve(moduleItem.path, MODULE_CONFIG_FILENAME);
|
|
145
|
+
let moduleConfig;
|
|
146
|
+
try {
|
|
147
|
+
moduleConfig = JSON.parse(fs.readFileSync(moduleConfigPath, 'utf-8'));
|
|
148
|
+
} catch (e) {
|
|
149
|
+
throw new Error(`${moduleConfigPath}json解析报错: ${e}`);
|
|
111
150
|
}
|
|
151
|
+
|
|
152
|
+
// 兼容历史逻辑,后续可删除--- start
|
|
153
|
+
const subPackages = adaptSubPackages(moduleConfig, appName);
|
|
154
|
+
const dependencies = adaptDependencies(moduleConfig.dependencies, subPackages);
|
|
155
|
+
moduleConfig = {
|
|
156
|
+
...(isObject(moduleConfig) ? moduleConfig : {}),
|
|
157
|
+
subPackages,
|
|
158
|
+
dependencies,
|
|
159
|
+
};
|
|
160
|
+
// 兼容逻辑--- end
|
|
161
|
+
modulesConfig.push(moduleConfig);
|
|
112
162
|
});
|
|
113
163
|
|
|
114
164
|
return modulesConfig;
|
|
115
165
|
}
|
|
116
166
|
|
|
117
167
|
/**
|
|
118
|
-
*
|
|
168
|
+
* 获取分包内容 (读取module.config.json的配置项)
|
|
119
169
|
* @param {array} modules
|
|
120
|
-
* @param {string} appName
|
|
121
|
-
* @param {string} moduleDir
|
|
122
170
|
* @returns
|
|
123
171
|
*/
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
modules.forEach((
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
let findModule = false;
|
|
131
|
-
let moduleConfigContent = fs.readFileSync(moduleConfigPath, 'utf-8');
|
|
132
|
-
moduleConfigContent = adaptMpCgContent(moduleConfigContent, appName);
|
|
133
|
-
const moduleContentArr = isObject(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
|
|
134
|
-
moduleContentArr.forEach(({ name }, moduleContentArrIndex) => {
|
|
135
|
-
if (name === moduleName) {
|
|
136
|
-
findModule = true;
|
|
137
|
-
newModules.push({
|
|
138
|
-
...modules[moduleIndex],
|
|
139
|
-
...moduleContentArr[moduleContentArrIndex],
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
if (!findModule) {
|
|
144
|
-
fail(`启动模块${moduleName}在${moduleConfigPath}没有找到,请检查配置`);
|
|
145
|
-
process.exit(1);
|
|
146
|
-
}
|
|
147
|
-
} catch (e) {
|
|
148
|
-
fail(`${moduleConfigPath}配置错误: ${e}`);
|
|
149
|
-
newModules.push({
|
|
150
|
-
...modules[moduleIndex],
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
newModules.push({
|
|
155
|
-
...modules[moduleIndex],
|
|
172
|
+
const getSubPackages = (modules) => {
|
|
173
|
+
const newSubPackages = [];
|
|
174
|
+
modules.forEach((module) => {
|
|
175
|
+
(module.subPackages || []).forEach((subPackage) => {
|
|
176
|
+
newSubPackages.push({
|
|
177
|
+
...subPackage,
|
|
156
178
|
});
|
|
157
|
-
}
|
|
179
|
+
});
|
|
158
180
|
});
|
|
159
|
-
return
|
|
181
|
+
return newSubPackages;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* 获取分包的root字段
|
|
186
|
+
* @param {*} modulePath 模块的编译路径
|
|
187
|
+
* @param {*} root 分包的root字段
|
|
188
|
+
* @returns
|
|
189
|
+
*/
|
|
190
|
+
const getSubPackageRoot = function (modulePath, root) {
|
|
191
|
+
return root.startsWith(modulePath) ? root : `${modulePath}/${root}`;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// 获取分包的源码路径
|
|
195
|
+
const getSubPackageSrcPath = function (tmsConfig, module, subPackage) {
|
|
196
|
+
const srcModulePath = getAbsolutePath(module.path);
|
|
197
|
+
const buildModulePath = resolve(tmsConfig.outputDir, module.modulePath);
|
|
198
|
+
|
|
199
|
+
const subPackageRoot = getSubPackageRoot(module.modulePath, subPackage.root);
|
|
200
|
+
const buildSubPackagePath = resolve(tmsConfig.outputDir, subPackageRoot);
|
|
201
|
+
|
|
202
|
+
const subPackageRelativeModule = path.relative(buildModulePath, buildSubPackagePath);
|
|
203
|
+
const srcSubPackagePath = path.join(srcModulePath, subPackageRelativeModule);
|
|
204
|
+
|
|
205
|
+
return srcSubPackagePath;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const checkModuleItem = (tmsConfig, tmsModuleItem, moduleConfig) => {
|
|
209
|
+
const newModuleItem = { ...tmsModuleItem, ...moduleConfig };
|
|
210
|
+
|
|
211
|
+
// 兼容逻辑
|
|
212
|
+
if (!newModuleItem.moduleName) newModuleItem.moduleName = newModuleItem.name;
|
|
213
|
+
delete newModuleItem.name;
|
|
214
|
+
|
|
215
|
+
// 参数校验-模块源码路径
|
|
216
|
+
if (!newModuleItem.path) {
|
|
217
|
+
throw new Error(`${newModuleItem.moduleName}模块没有找到path字段,请检查tms.config.js的modules.all>module>path路径`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// 参数校验-模块编译路径
|
|
221
|
+
if (!newModuleItem.modulePath) {
|
|
222
|
+
throw new Error(`${newModuleItem.moduleName}模块的module.config.json中没有找到modulePath字段`);
|
|
223
|
+
}
|
|
224
|
+
// 参数校验-分包校验
|
|
225
|
+
for (const subPackage of newModuleItem.subPackages) {
|
|
226
|
+
if (!subPackage.root) {
|
|
227
|
+
throw new Error(`${newModuleItem.moduleName}模块的module.config.json中没有找到${subPackage.name}分包的root字段`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// 参数校验-判断分包源码目录是否存在
|
|
231
|
+
const subPackageSrcPath = getSubPackageSrcPath(tmsConfig, newModuleItem, subPackage);
|
|
232
|
+
if (!subPackageSrcPath || !fs.existsSync(subPackageSrcPath)) {
|
|
233
|
+
throw new Error(`没有找到${newModuleItem.moduleName}模块的${subPackage.name}分包源码:${subPackageSrcPath}`);
|
|
234
|
+
}
|
|
235
|
+
subPackage.path = subPackageSrcPath;
|
|
236
|
+
}
|
|
237
|
+
return newModuleItem;
|
|
160
238
|
};
|
|
161
239
|
|
|
162
240
|
/**
|
|
163
|
-
*
|
|
241
|
+
* 获取所有的模块,合并模块的依赖模块
|
|
164
242
|
* @param { object } tmsConfig
|
|
165
243
|
* @param {array} modules
|
|
166
|
-
* @param {
|
|
244
|
+
* @param {boolean} errorIsQuit 找不到配置文件是否退出
|
|
167
245
|
* @returns
|
|
168
246
|
*/
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
247
|
+
const getModulesByMergeDepModules = (tmsConfig, modules, errorIsQuit = false) => {
|
|
248
|
+
const allModules = new Map();
|
|
249
|
+
function dfs(tmsConfig, modules) {
|
|
250
|
+
modules.forEach((moduleItem) => {
|
|
251
|
+
const moduleConfigPath = resolve(moduleItem.path, MODULE_CONFIG_FILENAME);
|
|
252
|
+
if (!fs.existsSync(moduleConfigPath)) {
|
|
253
|
+
if (!allModules.has(moduleItem.moduleName)) {
|
|
254
|
+
allModules.set(moduleItem.moduleName, moduleItem);
|
|
255
|
+
}
|
|
256
|
+
if (errorIsQuit) {
|
|
257
|
+
throw new Error(`${moduleItem.moduleName}模块的配置文件module.config.json在${moduleItem.path}目录下没有找到`);
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const [moduleConfig = {}] = getModulesConfig([moduleItem], tmsConfig.appName);
|
|
262
|
+
|
|
263
|
+
if (!allModules.has(moduleItem.moduleName)) {
|
|
264
|
+
allModules.set(moduleItem.moduleName, checkModuleItem(tmsConfig, moduleItem, moduleConfig));
|
|
265
|
+
|
|
266
|
+
const dependenciesModules = getModulesByModuleNames(tmsConfig, moduleConfig?.dependencies);
|
|
267
|
+
if (dependenciesModules.length) {
|
|
268
|
+
dfs(tmsConfig, dependenciesModules);
|
|
187
269
|
}
|
|
188
270
|
}
|
|
189
271
|
});
|
|
190
|
-
}
|
|
191
|
-
|
|
272
|
+
}
|
|
273
|
+
dfs(tmsConfig, modules);
|
|
274
|
+
|
|
275
|
+
const modulesArr = [];
|
|
276
|
+
for (const module of allModules.values()) {
|
|
277
|
+
modulesArr.push(module);
|
|
278
|
+
}
|
|
279
|
+
return modulesArr;
|
|
192
280
|
};
|
|
193
281
|
|
|
194
282
|
module.exports = {
|
|
195
283
|
readTmsConfig,
|
|
196
284
|
readTmsPrivateCf,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
285
|
+
getModulesConfig,
|
|
286
|
+
getModulesByModuleNames,
|
|
287
|
+
getSubPackages,
|
|
288
|
+
getModulesByMergeDepModules,
|
|
289
|
+
getTmsConfig,
|
|
201
290
|
};
|
package/src/entry.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module.exports = [
|
|
2
2
|
{
|
|
3
|
-
command: 'create <
|
|
4
|
-
description: '
|
|
5
|
-
action: (
|
|
6
|
-
require('./scripts/create')(
|
|
3
|
+
command: 'create <project-name>',
|
|
4
|
+
description: '创建项目',
|
|
5
|
+
action: (projectName) => {
|
|
6
|
+
require('./scripts/create')(projectName);
|
|
7
7
|
},
|
|
8
8
|
},
|
|
9
9
|
{
|
package/src/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
2
|
const commander = require('commander');
|
|
3
|
-
const { suggestCommands } = require('./utils/widgets');
|
|
3
|
+
const { suggestCommands, resolve } = require('./utils/widgets');
|
|
4
4
|
const { info } = require('./utils/log');
|
|
5
|
+
const { getTmsConfig } = require('../src/core/tmsMpconfig');
|
|
5
6
|
const { TMS_NAME } = require('./config/constant.js');
|
|
6
7
|
const commands = require('./entry');
|
|
7
|
-
const
|
|
8
|
+
const check = require('./check');
|
|
9
|
+
const fs = require('fs');
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
check();
|
|
10
12
|
|
|
11
13
|
const program = new commander.Command(TMS_NAME);
|
|
12
14
|
|
|
@@ -36,7 +38,19 @@ function registerCommand(program, commands) {
|
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
function register() {
|
|
42
|
+
// 注册脚手架内部命令
|
|
43
|
+
registerCommand(program, commands);
|
|
44
|
+
|
|
45
|
+
// 注册扩展命令
|
|
46
|
+
if (fs.existsSync(resolve('tms.config.js'))) {
|
|
47
|
+
const tmsConfig = getTmsConfig();
|
|
48
|
+
if (Array.isArray(tmsConfig?.commands)) {
|
|
49
|
+
registerCommand(program, tmsConfig.commands);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
register();
|
|
40
54
|
|
|
41
55
|
program.on('--help', () => {
|
|
42
56
|
info(` Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
|
|
@@ -3,8 +3,7 @@ const render = require('./render');
|
|
|
3
3
|
const ask = require('./ask');
|
|
4
4
|
const FILES_TO_IGNORE = require('./ignoreFiles');
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
const generator = (buildDir, distDir, preMetadata) => new Promise((resolve, reject) => {
|
|
6
|
+
const generator = (buildDir, distDir, preMetadata = {}) => new Promise((resolve, reject) => {
|
|
8
7
|
Metalsmith(buildDir)
|
|
9
8
|
.metadata(preMetadata)
|
|
10
9
|
.ignore(FILES_TO_IGNORE)
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const shelljs = require('shelljs');
|
|
4
|
-
const
|
|
5
|
-
const {
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
const {
|
|
6
|
+
TEMPLATE_DIR,
|
|
7
|
+
TEMPLATE_URL,
|
|
8
|
+
TEMPLATE_NAME,
|
|
9
|
+
TEMPLATE_TKIT_DIR,
|
|
10
|
+
CREATE_TEMPLATE_QUESTION,
|
|
11
|
+
} = require('../../config/constant.js');
|
|
12
|
+
const { resolve } = require('../../utils/widgets');
|
|
6
13
|
const io = require('../../utils/io');
|
|
7
14
|
const { fail, succeed, info } = require('../../utils/log');
|
|
8
15
|
const generator = require('./generator');
|
|
16
|
+
const request = require('request');
|
|
17
|
+
const unzip = require('unzipper');
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
20
|
* 如果该目录下面存在文件,换个名字
|
|
12
21
|
* @param { string } targetDir 当前文件夹
|
|
13
22
|
* @returns { undefined }
|
|
14
23
|
*/
|
|
15
|
-
async function
|
|
24
|
+
async function createProjectDir(targetDir) {
|
|
16
25
|
// 如果目录非空或者已经存在,提示用户,做选择
|
|
17
26
|
if (fs.existsSync(targetDir)) {
|
|
18
27
|
if (!await io.isDirEmpty(targetDir)) {
|
|
@@ -24,43 +33,75 @@ async function createAppDir(targetDir) {
|
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
35
|
|
|
36
|
+
/**
|
|
37
|
+
* 下载和解压远程的小程序模板
|
|
38
|
+
* @param {string} templateDir
|
|
39
|
+
* @param {string} templateUrl
|
|
40
|
+
* @param {string} templateName
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
function downloadAndUnZipTemplate(templateDir, templateUrl, templateName) {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const localZipPath = `${templateDir}/${templateName}.zip`;
|
|
46
|
+
const stream = fs.createWriteStream(localZipPath);
|
|
47
|
+
request(`${templateUrl}?v=${new Date().getTime()}`).pipe(stream)
|
|
48
|
+
.on('close', (err) => {
|
|
49
|
+
if (err) {
|
|
50
|
+
reject(err);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
fs.createReadStream(localZipPath).pipe(unzip.Extract({ path: templateDir }))
|
|
54
|
+
.on('close', (err) => {
|
|
55
|
+
if (err) {
|
|
56
|
+
reject(err);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
resolve();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
27
65
|
/**
|
|
28
66
|
* 创建本地小程序运行环境
|
|
29
|
-
* @param { string }
|
|
30
|
-
* @param { string }
|
|
67
|
+
* @param { string } projectType 项目类型
|
|
68
|
+
* @param { string } projectName 项目名称
|
|
31
69
|
*/
|
|
32
|
-
async function create(
|
|
70
|
+
async function create(projectName) {
|
|
33
71
|
const cwd = process.cwd();
|
|
34
|
-
const targetDir = path.resolve(cwd,
|
|
35
|
-
const
|
|
36
|
-
await createAppDir(targetDir);
|
|
72
|
+
const targetDir = path.resolve(cwd, projectName);
|
|
73
|
+
const { projectType } = await inquirer.prompt(CREATE_TEMPLATE_QUESTION);
|
|
37
74
|
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
TEMPLATE_DIR
|
|
44
|
-
|
|
45
|
-
);
|
|
75
|
+
// 创建项目目录
|
|
76
|
+
await createProjectDir(targetDir);
|
|
77
|
+
|
|
78
|
+
// 新创建缓存目录
|
|
79
|
+
if (fs.existsSync(TEMPLATE_DIR)) {
|
|
80
|
+
shelljs.rm('-rf', TEMPLATE_DIR);
|
|
81
|
+
}
|
|
82
|
+
fs.mkdirSync(TEMPLATE_DIR, { recursive: true });
|
|
83
|
+
|
|
84
|
+
// 下载和解压模板
|
|
85
|
+
await downloadAndUnZipTemplate(TEMPLATE_DIR, TEMPLATE_URL, TEMPLATE_NAME);
|
|
46
86
|
|
|
47
87
|
// 生成模板(1. 询问问题, 2. ejs生成模板 3.生成到目标目录)
|
|
48
|
-
generator(path.join(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
}
|
|
88
|
+
generator(path.join(TEMPLATE_DIR, TEMPLATE_NAME, projectType), targetDir).then(() => {
|
|
89
|
+
shelljs.cd(projectName);
|
|
90
|
+
const hookFilePath = resolve(projectName, TEMPLATE_TKIT_DIR, 'hooks.js');
|
|
91
|
+
if (fs.existsSync(hookFilePath)) {
|
|
92
|
+
const hooks = require(hookFilePath);
|
|
93
|
+
if (hooks.afterCreate) {
|
|
94
|
+
hooks.afterCreate.forEach((item) => {
|
|
95
|
+
if (typeof item === 'function') {
|
|
96
|
+
item.call(null, shelljs, { projectName });
|
|
97
|
+
} else {
|
|
98
|
+
shelljs.exec(item);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
shelljs.rm('-rf', resolve(projectName, TEMPLATE_TKIT_DIR));
|
|
62
103
|
}
|
|
63
|
-
|
|
104
|
+
|
|
64
105
|
succeed('项目创建完成.');
|
|
65
106
|
})
|
|
66
107
|
.catch((err) => {
|
|
@@ -3,19 +3,20 @@ const { resolve, filterField } = require('../../../utils/widgets');
|
|
|
3
3
|
const init = require('../init/index');
|
|
4
4
|
const compileBuild = require('../../../compile/build');
|
|
5
5
|
|
|
6
|
-
async function build(tmsConfig, targetModules
|
|
6
|
+
async function build(tmsConfig, targetModules) {
|
|
7
7
|
// 开始构建前,清理输出目录
|
|
8
8
|
await shelljs.rm('-rf', resolve(tmsConfig.outputDir));
|
|
9
9
|
|
|
10
|
-
const {
|
|
10
|
+
const { modules: newModules } = await init(tmsConfig, targetModules);
|
|
11
11
|
|
|
12
|
+
const isDev = false;
|
|
12
13
|
if (typeof tmsConfig?.hooks?.beforeCompile === 'function') {
|
|
13
14
|
await tmsConfig?.hooks?.beforeCompile({
|
|
14
|
-
isDev
|
|
15
|
+
isDev,
|
|
15
16
|
tmsConfig: filterField(tmsConfig, ['gitAccount']),
|
|
16
17
|
modules: newModules });
|
|
17
18
|
};
|
|
18
|
-
compileBuild(tmsConfig, newModules,
|
|
19
|
+
compileBuild(tmsConfig, newModules, isDev);
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
module.exports = build;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
const { symLink } = require('../../../core/symbolicLink');
|
|
2
2
|
const { handleError } = require('../../../core/handleError');
|
|
3
|
-
const { succeed } = require('../../../utils/log');
|
|
4
3
|
|
|
5
4
|
module.exports = async (tmsConfig) => {
|
|
6
5
|
try {
|
|
7
6
|
await symLink(tmsConfig);
|
|
8
|
-
succeed('云函数创建软链成功');
|
|
9
7
|
} catch (e) {
|
|
10
8
|
handleError(`创建软链错误: ${e}`);
|
|
11
9
|
}
|