@tmsfe/tmskit 0.0.6 → 0.0.7

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.
Files changed (42) hide show
  1. package/README.md +27 -27
  2. package/dist/index.cjs.js +332 -407
  3. package/main.js +3 -3
  4. package/package.json +75 -75
  5. package/src/config/constant.js +71 -71
  6. package/src/config/defaultTmsConfig.js +16 -16
  7. package/src/entry.js +60 -60
  8. package/src/gulp/build.js +5 -5
  9. package/src/gulp/compile.js +81 -87
  10. package/src/gulp/dev.js +102 -102
  11. package/src/gulp/plugins/less.js +116 -116
  12. package/src/gulp/plugins/mpCommonDep.js +131 -131
  13. package/src/gulp/plugins/mpJsonDep.js +108 -108
  14. package/src/gulp/plugins/mpWxmlDep.js +194 -194
  15. package/src/gulp/plugins/postcss-font-base64.js +72 -72
  16. package/src/gulp/plugins/replaceEnv.js +29 -29
  17. package/src/gulp/plugins/utils/pluginError.js +25 -25
  18. package/src/index.js +62 -62
  19. package/src/init.js +33 -33
  20. package/src/scripts/create/ask.js +63 -63
  21. package/src/scripts/create/generator.js +25 -25
  22. package/src/scripts/create/ignoreFiles.js +7 -7
  23. package/src/scripts/create/index.js +72 -72
  24. package/src/scripts/create/render.js +19 -19
  25. package/src/scripts/run/build/index.js +17 -17
  26. package/src/scripts/run/dev/index.js +84 -84
  27. package/src/scripts/run/index.js +68 -68
  28. package/src/scripts/run/init/index.js +87 -87
  29. package/src/scripts/run/install/index.js +29 -29
  30. package/src/utils/buildAppJson.js +221 -221
  31. package/src/utils/checkDependencies.js +77 -77
  32. package/src/utils/cliUtils.js +35 -35
  33. package/src/utils/cloneModules.js +116 -116
  34. package/src/utils/findCssImport.js +30 -30
  35. package/src/utils/global.js +36 -36
  36. package/src/utils/handleError.js +16 -16
  37. package/src/utils/io.js +106 -106
  38. package/src/utils/log.js +44 -44
  39. package/src/utils/mpCiUtils.js +73 -73
  40. package/src/utils/npmUtils.js +166 -166
  41. package/src/utils/tkitUtils.js +158 -158
  42. package/src/utils/widgets.js +167 -167
@@ -1,158 +1,158 @@
1
- const loadash = require('lodash');
2
- const fs = require('fs');
3
- const { TMS_NAME, TMS_CONFIG_FILENAME, MODULE_CONFIG_FILENAME, TMS_PRIVATE_FILENAME } = require('../config/constant');
4
- const { resolve, isObject } = require('./widgets');
5
- const { setModuleConfig, getValidModules } = require('./buildAppJson');
6
- const defaultTmsConfig = require('../config/defaultTmsConfig');
7
- const { fail } = require('./log');
8
- const path = require('path');
9
-
10
- /**
11
- * 读取tms.config.js
12
- * @param env {string} 环境变量
13
- */
14
- const readTmsConfig = function (env) {
15
- const tmsConfigPath = resolve(TMS_CONFIG_FILENAME);
16
- if (!fs.existsSync(tmsConfigPath)) {
17
- fail('当前执行目录没有tms.config.js的配置项,请进行配置');
18
- process.exit(1);
19
- }
20
- const tmsConfigFn = require(tmsConfigPath);
21
- const tmsConfig = tmsConfigFn({
22
- env,
23
- });
24
- // 合并默认值
25
- loadash.mergeWith(tmsConfig, defaultTmsConfig);
26
- // modules兼容处理
27
- tmsConfig.modules = convertModules(tmsConfig.modules);
28
- return tmsConfig;
29
- };
30
-
31
- // convertModules 处理默认值
32
- const convertModules = (modules) => {
33
- const newModules = [];
34
- modules.forEach((module, index) => {
35
- const newModule = {};
36
- if (typeof module === 'string') {
37
- // 路径字符串
38
- Object.assign(newModule, {
39
- name: path.basename(module),
40
- path: module,
41
- });
42
- } else if (typeof module === 'object') {
43
- Object.assign(newModule, module);
44
- if (module.name === undefined) {
45
- newModule.name = path.basename(module.path);
46
- }
47
- }
48
- newModules.push(newModule);
49
- });
50
- return newModules;
51
- };
52
-
53
- /**
54
- * 读取tms.private.js
55
- */
56
- const readTmsPrivateCf = function () {
57
- let tmsPrivateCg;
58
- const tmsPrivatePath = resolve(TMS_PRIVATE_FILENAME);
59
- if (fs.existsSync(tmsPrivatePath)) {
60
- tmsPrivateCg = require(tmsPrivatePath);
61
- }
62
- return tmsPrivateCg;
63
- };
64
-
65
- /**
66
- * 从tms.config.json中检索用户传入的有效modules
67
- * @param { object } tmsConfig
68
- * @param { array } modules
69
- * @returns
70
- */
71
- const checkModules = function (tmsConfig, modules) {
72
- const targetModules = [];
73
- modules.forEach((moduleName) => {
74
- const module = tmsConfig.modules.find(module => module.name === moduleName);
75
- module && targetModules.push(module);
76
- });
77
- if (targetModules.length === 0) {
78
- fail(`你启动的模块无效,尝试 ${TMS_NAME} -m moduleName`);
79
- process.exit(1);
80
- }
81
- return targetModules;
82
- };
83
-
84
- /**
85
- * tms.config.js的modules 合并 module.config.json的配置项
86
- * @param {array} modules
87
- * @param {string} appName
88
- * @param {string} moduleDir
89
- * @returns
90
- */
91
- const tmsModulesMergeLocalModuleCfg = (modules, appName) => {
92
- const newModules = [];
93
- modules.forEach(({ path: relativePath, name: moduleName }, moduleIndex) => {
94
- const moduleConfigPath = resolve(relativePath, MODULE_CONFIG_FILENAME);
95
- if (fs.existsSync(moduleConfigPath)) {
96
- try {
97
- let moduleConfigContent = fs.readFileSync(moduleConfigPath, 'utf-8');
98
- moduleConfigContent = setModuleConfig(moduleConfigContent, appName);
99
- const moduleContentArr = isObject(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
100
- getValidModules(moduleContentArr).forEach(({ name }, moduleContentArrIndex) => {
101
- if (name === moduleName) {
102
- newModules.push({
103
- ...modules[moduleIndex],
104
- ...moduleContentArr[moduleContentArrIndex],
105
- });
106
- }
107
- });
108
- } catch (e) {
109
- fail(`${moduleConfigPath}配置错误: ${e}`);
110
- newModules.push({
111
- ...modules[moduleIndex],
112
- });
113
- }
114
- } else {
115
- newModules.push({
116
- ...modules[moduleIndex],
117
- });
118
- }
119
- });
120
- return newModules;
121
- };
122
-
123
- /**
124
- * 分包依赖了分包的模块 合并所依赖的modules
125
- * @param { object } tmsConfig
126
- * @param {array} modules
127
- * @param {string} moduleDir
128
- * @returns
129
- */
130
- const subModulesMergeDepModules = (tmsConfig, modules) => {
131
- const moduleNames = [];
132
- modules.forEach(({ name: moduleName }) => {
133
- moduleNames.push(moduleName);
134
- });
135
- let mergeModules = modules;
136
- let isOver = true;
137
- modules.forEach(({ dependencies: dependencyModules }) => {
138
- dependencyModules?.forEach((item) => {
139
- // 如果所有模块的dep都在moduleNames内,则所有依赖都齐了
140
- // 否则递归处理,根据name找到相关配置加到modules里
141
- if (moduleNames.indexOf(item) === -1) {
142
- isOver = false;
143
- const tmpModules = checkModules(tmsConfig, [...new Set([item])]);
144
- mergeModules = [...mergeModules, ...tmpModules];
145
- mergeModules = tmsModulesMergeLocalModuleCfg(mergeModules, tmsConfig.appName);
146
- }
147
- });
148
- });
149
- return isOver ? mergeModules : subModulesMergeDepModules(tmsConfig, mergeModules);
150
- };
151
-
152
- module.exports = {
153
- readTmsConfig,
154
- readTmsPrivateCf,
155
- checkModules,
156
- tmsModulesMergeLocalModuleCfg,
157
- subModulesMergeDepModules,
158
- };
1
+ const loadash = require('lodash');
2
+ const fs = require('fs');
3
+ const { TMS_NAME, TMS_CONFIG_FILENAME, MODULE_CONFIG_FILENAME, TMS_PRIVATE_FILENAME } = require('../config/constant');
4
+ const { resolve, isObject } = require('./widgets');
5
+ const { setModuleConfig, getValidModules } = require('./buildAppJson');
6
+ const defaultTmsConfig = require('../config/defaultTmsConfig');
7
+ const { fail } = require('./log');
8
+ const path = require('path');
9
+
10
+ /**
11
+ * 读取tms.config.js
12
+ * @param env {string} 环境变量
13
+ */
14
+ const readTmsConfig = function (env) {
15
+ const tmsConfigPath = resolve(TMS_CONFIG_FILENAME);
16
+ if (!fs.existsSync(tmsConfigPath)) {
17
+ fail('当前执行目录没有tms.config.js的配置项,请进行配置');
18
+ process.exit(1);
19
+ }
20
+ const tmsConfigFn = require(tmsConfigPath);
21
+ const tmsConfig = tmsConfigFn({
22
+ env,
23
+ });
24
+ // 合并默认值
25
+ loadash.mergeWith(tmsConfig, defaultTmsConfig);
26
+ // modules兼容处理
27
+ tmsConfig.modules = convertModules(tmsConfig.modules);
28
+ return tmsConfig;
29
+ };
30
+
31
+ // convertModules 处理默认值
32
+ const convertModules = (modules) => {
33
+ const newModules = [];
34
+ modules.forEach((module, index) => {
35
+ const newModule = {};
36
+ if (typeof module === 'string') {
37
+ // 路径字符串
38
+ Object.assign(newModule, {
39
+ name: path.basename(module),
40
+ path: module,
41
+ });
42
+ } else if (typeof module === 'object') {
43
+ Object.assign(newModule, module);
44
+ if (module.name === undefined) {
45
+ newModule.name = path.basename(module.path);
46
+ }
47
+ }
48
+ newModules.push(newModule);
49
+ });
50
+ return newModules;
51
+ };
52
+
53
+ /**
54
+ * 读取tms.private.js
55
+ */
56
+ const readTmsPrivateCf = function () {
57
+ let tmsPrivateCg;
58
+ const tmsPrivatePath = resolve(TMS_PRIVATE_FILENAME);
59
+ if (fs.existsSync(tmsPrivatePath)) {
60
+ tmsPrivateCg = require(tmsPrivatePath);
61
+ }
62
+ return tmsPrivateCg;
63
+ };
64
+
65
+ /**
66
+ * 从tms.config.json中检索用户传入的有效modules
67
+ * @param { object } tmsConfig
68
+ * @param { array } modules
69
+ * @returns
70
+ */
71
+ const checkModules = function (tmsConfig, modules) {
72
+ const targetModules = [];
73
+ modules.forEach((moduleName) => {
74
+ const module = tmsConfig.modules.find(module => module.name === moduleName);
75
+ module && targetModules.push(module);
76
+ });
77
+ if (targetModules.length === 0) {
78
+ fail(`你启动的模块无效,尝试 ${TMS_NAME} -m moduleName`);
79
+ process.exit(1);
80
+ }
81
+ return targetModules;
82
+ };
83
+
84
+ /**
85
+ * tms.config.js的modules 合并 module.config.json的配置项
86
+ * @param {array} modules
87
+ * @param {string} appName
88
+ * @param {string} moduleDir
89
+ * @returns
90
+ */
91
+ const tmsModulesMergeLocalModuleCfg = (modules, appName) => {
92
+ const newModules = [];
93
+ modules.forEach(({ path: relativePath, name: moduleName }, moduleIndex) => {
94
+ const moduleConfigPath = resolve(relativePath, MODULE_CONFIG_FILENAME);
95
+ if (fs.existsSync(moduleConfigPath)) {
96
+ try {
97
+ let moduleConfigContent = fs.readFileSync(moduleConfigPath, 'utf-8');
98
+ moduleConfigContent = setModuleConfig(moduleConfigContent, appName);
99
+ const moduleContentArr = isObject(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
100
+ getValidModules(moduleContentArr).forEach(({ name }, moduleContentArrIndex) => {
101
+ if (name === moduleName) {
102
+ newModules.push({
103
+ ...modules[moduleIndex],
104
+ ...moduleContentArr[moduleContentArrIndex],
105
+ });
106
+ }
107
+ });
108
+ } catch (e) {
109
+ fail(`${moduleConfigPath}配置错误: ${e}`);
110
+ newModules.push({
111
+ ...modules[moduleIndex],
112
+ });
113
+ }
114
+ } else {
115
+ newModules.push({
116
+ ...modules[moduleIndex],
117
+ });
118
+ }
119
+ });
120
+ return newModules;
121
+ };
122
+
123
+ /**
124
+ * 分包依赖了分包的模块 合并所依赖的modules
125
+ * @param { object } tmsConfig
126
+ * @param {array} modules
127
+ * @param {string} moduleDir
128
+ * @returns
129
+ */
130
+ const subModulesMergeDepModules = (tmsConfig, modules) => {
131
+ const moduleNames = [];
132
+ modules.forEach(({ name: moduleName }) => {
133
+ moduleNames.push(moduleName);
134
+ });
135
+ let mergeModules = modules;
136
+ let isOver = true;
137
+ modules.forEach(({ dependencies: dependencyModules }) => {
138
+ dependencyModules?.forEach((item) => {
139
+ // 如果所有模块的dep都在moduleNames内,则所有依赖都齐了
140
+ // 否则递归处理,根据name找到相关配置加到modules里
141
+ if (moduleNames.indexOf(item) === -1) {
142
+ isOver = false;
143
+ const tmpModules = checkModules(tmsConfig, [...new Set([item])]);
144
+ mergeModules = [...mergeModules, ...tmpModules];
145
+ mergeModules = tmsModulesMergeLocalModuleCfg(mergeModules, tmsConfig.appName);
146
+ }
147
+ });
148
+ });
149
+ return isOver ? mergeModules : subModulesMergeDepModules(tmsConfig, mergeModules);
150
+ };
151
+
152
+ module.exports = {
153
+ readTmsConfig,
154
+ readTmsPrivateCf,
155
+ checkModules,
156
+ tmsModulesMergeLocalModuleCfg,
157
+ subModulesMergeDepModules,
158
+ };
@@ -1,167 +1,167 @@
1
-
2
- const program = require('commander');
3
- const leven = require('leven');
4
- const ora = require('ora');
5
- const path = require('path');
6
- const fs = require('fs');
7
- const shelljs = require('shelljs');
8
- const download = require('download-git-repo');
9
- const chalk = require('chalk');
10
- const shelljsOptions = { slient: true };
11
-
12
- // 获取当前目录
13
- const cwd = process.cwd();
14
- function resolve(...args) {
15
- return path.resolve(cwd, ...args);
16
- };
17
-
18
- /**
19
- * 封装logs
20
- * @returns {Undefined} 无需返回值
21
- */
22
- const log = (...args) => console.log(...args);
23
-
24
- /**
25
- * 用户输入命令时,进行提示
26
- * @param {String} unknownCommand 非预期的命令
27
- * @returns {Undefined} 无需返回值
28
- */
29
- const suggestCommands = (unknownCommand) => {
30
- const availableCommands = program.commands.map(cmd => cmd._name);
31
-
32
- let suggestion;
33
- availableCommands.forEach((cmd) => {
34
- const isBestMatch = leven(cmd, unknownCommand) < leven(suggestion || '', unknownCommand);
35
- if (leven(cmd, unknownCommand) < 3 && isBestMatch) {
36
- suggestion = cmd;
37
- }
38
- });
39
-
40
- if (suggestion) {
41
- log(` ${chalk.red(`Did you mean ${chalk.yellow(suggestion)}?`)}`);
42
- }
43
- };
44
-
45
- /**
46
- * 判断变量是否是一个数组
47
- * @param { unknown } obj 变量
48
- * @returns { boolean } 是否是一个数组
49
- */
50
- function isObject(obj) {
51
- return Object.prototype.toString.call(obj) === '[object Object]';
52
- }
53
-
54
- /**
55
- * 判断变量是否是一个对象
56
- * @param { unknown } obj 变量
57
- * @returns { boolean } 是否是一个对象
58
- */
59
- function isArray(obj) {
60
- return Object.prototype.toString.call(obj) === '[object Array]';
61
- }
62
-
63
- /**
64
- * 下载模块到目标目录
65
- * @param { string } dest 目标地址
66
- * @param { object } downloadOptions 模块下载配置 { repoUrl-仓库地址, gitUrl-git地址, branch-分支或者tag }
67
- * @returns { undefined } no return
68
- */
69
- function downloadRepo(dest, downloadOptions = { repoUrl: '', gitUrl: '', branch: '' }) {
70
- const { repoUrl, gitUrl, branch } = downloadOptions;
71
-
72
- if (fs.existsSync(dest)) {
73
- shelljs.rm('-rf', dest);
74
- }
75
-
76
- shelljs.mkdir('-p', dest);
77
- return new Promise((resolve) => {
78
- download(`${repoUrl}#${branch}`, dest, { clone: true }, async (e) => {
79
- if (e) {
80
- console.log(e) // eslint-disable-line
81
- await downloadRepoForGit(gitUrl, dest, branch);
82
- }
83
-
84
- resolve();
85
- });
86
- });
87
- }
88
-
89
- /**
90
- * 下载模块到目标目录备用方案
91
- * @param { string } url 模块地址
92
- * @param { string } dest 目标地址
93
- * @param { string } branch 分支名
94
- * @returns { undefined } no return
95
- */
96
- function downloadRepoForGit(url, dest, branch) {
97
- const cwd = process.cwd();
98
-
99
- return new Promise((resolve, reject) => {
100
- // 如果目标目录不存在
101
- if (fs.existsSync(dest)) {
102
- shelljs.rm('-rf', path.join(dest));
103
- }
104
-
105
- shelljs.mkdir('-p', dest);
106
- shelljs.cd(dest);
107
-
108
- const gitCloneRes = shelljs.exec(`git clone ${url} ${dest} --branch ${branch} --depth 1`, shelljsOptions);
109
- if (gitCloneRes.code !== 0) {
110
- reject(gitCloneRes.stderr);
111
- }
112
-
113
- shelljs.cd(cwd);
114
- resolve();
115
- });
116
- }
117
-
118
- /**
119
- * 计算各项任务耗时
120
- * @param {Number} start 任务开始时间
121
- * @returns {Undefined} 无需返回值
122
- */
123
- const cost = start => Date.now() - start;
124
-
125
- /**
126
- * 创建构建子任务
127
- * @param {Function} task 子任务执行函数
128
- * @param {String} startText 任务开始前提示语
129
- * @param {String} endText 任务结束后提示语
130
- * @returns {Undefined} 无需返回值
131
- */
132
- function createTask(task, startText, endText) {
133
- return async (...args) => {
134
- const start = Date.now();
135
-
136
- const spinner = ora(startText);
137
-
138
- spinner.start();
139
- console.log('\n');
140
-
141
- const result = await task(...args);
142
-
143
- endText && spinner.succeed(`${endText}, ${cost(start)}ms`);
144
- spinner.stop();
145
-
146
- return result;
147
- };
148
- };
149
-
150
- /**
151
- * 字符串驼峰化处理
152
- * @param {String} str 需要处理的字符串
153
- * @returns {String} 经过驼峰处理的字符串
154
- */
155
- const camelize = str => str.replace(/-(\w)/g, (a, c) => (c ? c.toUpperCase() : ''));
156
-
157
- module.exports = {
158
- resolve,
159
- log,
160
- isObject,
161
- isArray,
162
- createTask,
163
- downloadRepo,
164
- downloadRepoForGit,
165
- suggestCommands,
166
- camelize,
167
- };
1
+
2
+ const program = require('commander');
3
+ const leven = require('leven');
4
+ const ora = require('ora');
5
+ const path = require('path');
6
+ const fs = require('fs');
7
+ const shelljs = require('shelljs');
8
+ const download = require('download-git-repo');
9
+ const chalk = require('chalk');
10
+ const shelljsOptions = { slient: true };
11
+
12
+ // 获取当前目录
13
+ const cwd = process.cwd();
14
+ function resolve(...args) {
15
+ return path.resolve(cwd, ...args);
16
+ };
17
+
18
+ /**
19
+ * 封装logs
20
+ * @returns {Undefined} 无需返回值
21
+ */
22
+ const log = (...args) => console.log(...args);
23
+
24
+ /**
25
+ * 用户输入命令时,进行提示
26
+ * @param {String} unknownCommand 非预期的命令
27
+ * @returns {Undefined} 无需返回值
28
+ */
29
+ const suggestCommands = (unknownCommand) => {
30
+ const availableCommands = program.commands.map(cmd => cmd._name);
31
+
32
+ let suggestion;
33
+ availableCommands.forEach((cmd) => {
34
+ const isBestMatch = leven(cmd, unknownCommand) < leven(suggestion || '', unknownCommand);
35
+ if (leven(cmd, unknownCommand) < 3 && isBestMatch) {
36
+ suggestion = cmd;
37
+ }
38
+ });
39
+
40
+ if (suggestion) {
41
+ log(` ${chalk.red(`Did you mean ${chalk.yellow(suggestion)}?`)}`);
42
+ }
43
+ };
44
+
45
+ /**
46
+ * 判断变量是否是一个数组
47
+ * @param { unknown } obj 变量
48
+ * @returns { boolean } 是否是一个数组
49
+ */
50
+ function isObject(obj) {
51
+ return Object.prototype.toString.call(obj) === '[object Object]';
52
+ }
53
+
54
+ /**
55
+ * 判断变量是否是一个对象
56
+ * @param { unknown } obj 变量
57
+ * @returns { boolean } 是否是一个对象
58
+ */
59
+ function isArray(obj) {
60
+ return Object.prototype.toString.call(obj) === '[object Array]';
61
+ }
62
+
63
+ /**
64
+ * 下载模块到目标目录
65
+ * @param { string } dest 目标地址
66
+ * @param { object } downloadOptions 模块下载配置 { repoUrl-仓库地址, gitUrl-git地址, branch-分支或者tag }
67
+ * @returns { undefined } no return
68
+ */
69
+ function downloadRepo(dest, downloadOptions = { repoUrl: '', gitUrl: '', branch: '' }) {
70
+ const { repoUrl, gitUrl, branch } = downloadOptions;
71
+
72
+ if (fs.existsSync(dest)) {
73
+ shelljs.rm('-rf', dest);
74
+ }
75
+
76
+ shelljs.mkdir('-p', dest);
77
+ return new Promise((resolve) => {
78
+ download(`${repoUrl}#${branch}`, dest, { clone: true }, async (e) => {
79
+ if (e) {
80
+ console.log(e) // eslint-disable-line
81
+ await downloadRepoForGit(gitUrl, dest, branch);
82
+ }
83
+
84
+ resolve();
85
+ });
86
+ });
87
+ }
88
+
89
+ /**
90
+ * 下载模块到目标目录备用方案
91
+ * @param { string } url 模块地址
92
+ * @param { string } dest 目标地址
93
+ * @param { string } branch 分支名
94
+ * @returns { undefined } no return
95
+ */
96
+ function downloadRepoForGit(url, dest, branch) {
97
+ const cwd = process.cwd();
98
+
99
+ return new Promise((resolve, reject) => {
100
+ // 如果目标目录不存在
101
+ if (fs.existsSync(dest)) {
102
+ shelljs.rm('-rf', path.join(dest));
103
+ }
104
+
105
+ shelljs.mkdir('-p', dest);
106
+ shelljs.cd(dest);
107
+
108
+ const gitCloneRes = shelljs.exec(`git clone ${url} ${dest} --branch ${branch} --depth 1`, shelljsOptions);
109
+ if (gitCloneRes.code !== 0) {
110
+ reject(gitCloneRes.stderr);
111
+ }
112
+
113
+ shelljs.cd(cwd);
114
+ resolve();
115
+ });
116
+ }
117
+
118
+ /**
119
+ * 计算各项任务耗时
120
+ * @param {Number} start 任务开始时间
121
+ * @returns {Undefined} 无需返回值
122
+ */
123
+ const cost = start => Date.now() - start;
124
+
125
+ /**
126
+ * 创建构建子任务
127
+ * @param {Function} task 子任务执行函数
128
+ * @param {String} startText 任务开始前提示语
129
+ * @param {String} endText 任务结束后提示语
130
+ * @returns {Undefined} 无需返回值
131
+ */
132
+ function createTask(task, startText, endText) {
133
+ return async (...args) => {
134
+ const start = Date.now();
135
+
136
+ const spinner = ora(startText);
137
+
138
+ spinner.start();
139
+ console.log('\n');
140
+
141
+ const result = await task(...args);
142
+
143
+ endText && spinner.succeed(`${endText}, ${cost(start)}ms`);
144
+ spinner.stop();
145
+
146
+ return result;
147
+ };
148
+ };
149
+
150
+ /**
151
+ * 字符串驼峰化处理
152
+ * @param {String} str 需要处理的字符串
153
+ * @returns {String} 经过驼峰处理的字符串
154
+ */
155
+ const camelize = str => str.replace(/-(\w)/g, (a, c) => (c ? c.toUpperCase() : ''));
156
+
157
+ module.exports = {
158
+ resolve,
159
+ log,
160
+ isObject,
161
+ isArray,
162
+ createTask,
163
+ downloadRepo,
164
+ downloadRepoForGit,
165
+ suggestCommands,
166
+ camelize,
167
+ };