@tmsfe/tmskit 0.0.7 → 0.0.9-beta.1

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 (46) hide show
  1. package/README.md +27 -27
  2. package/dist/index.cjs.js +1284 -983
  3. package/main.js +3 -3
  4. package/package.json +73 -75
  5. package/src/{gulp → compile}/build.js +5 -5
  6. package/src/{gulp → compile}/compile.js +90 -81
  7. package/src/{gulp → compile}/dev.js +129 -102
  8. package/src/{gulp → compile}/plugins/less.js +116 -116
  9. package/src/{gulp → compile}/plugins/mpCommonDep.js +131 -131
  10. package/src/{gulp → compile}/plugins/mpJsonDep.js +112 -108
  11. package/src/{gulp → compile}/plugins/mpWxmlDep.js +194 -194
  12. package/src/{gulp → compile}/plugins/postcss-font-base64.js +72 -72
  13. package/src/{gulp → compile}/plugins/replaceEnv.js +29 -29
  14. package/src/{gulp → compile}/plugins/utils/pluginError.js +25 -25
  15. package/src/config/constant.js +69 -71
  16. package/src/config/defaultTmsConfig.js +16 -16
  17. package/src/{utils → core}/buildAppJson.js +166 -221
  18. package/src/{utils → core}/checkDependencies.js +77 -77
  19. package/src/core/cloneModules.js +203 -0
  20. package/src/{utils → core}/handleError.js +18 -16
  21. package/src/core/isInIt.js +69 -0
  22. package/src/{utils/mpCiUtils.js → core/mpCi.js} +73 -73
  23. package/src/core/npm.js +218 -0
  24. package/src/core/symbolicLink.js +24 -0
  25. package/src/{utils/tkitUtils.js → core/tmsMpconfig.js} +234 -158
  26. package/src/entry.js +62 -60
  27. package/src/index.js +63 -62
  28. package/src/init.js +33 -33
  29. package/src/scripts/create/ask.js +63 -63
  30. package/src/scripts/create/generator.js +25 -25
  31. package/src/scripts/create/ignoreFiles.js +7 -7
  32. package/src/scripts/create/index.js +72 -72
  33. package/src/scripts/create/render.js +19 -19
  34. package/src/scripts/run/build/index.js +16 -17
  35. package/src/scripts/run/dev/index.js +42 -84
  36. package/src/scripts/run/index.js +97 -68
  37. package/src/scripts/run/init/index.js +95 -87
  38. package/src/scripts/run/install/index.js +31 -29
  39. package/src/utils/findCssImport.js +30 -30
  40. package/src/utils/global.js +22 -36
  41. package/src/utils/io.js +107 -106
  42. package/src/utils/log.js +47 -44
  43. package/src/utils/widgets.js +178 -167
  44. package/src/utils/cliUtils.js +0 -35
  45. package/src/utils/cloneModules.js +0 -116
  46. package/src/utils/npmUtils.js +0 -166
package/src/utils/io.js CHANGED
@@ -1,106 +1,107 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- /**
4
- * 判断目录是否为空
5
- * @param {string} dirname 目录名
6
- * @returns
7
- */
8
- const isDirEmpty = dirname => fs.promises.readdir(dirname).then(files => files.length === 0);
9
-
10
- // 判断是否是文件
11
- const isFile = (pathName) => {
12
- try {
13
- const stat = fs.lstatSync(pathName);
14
- return stat.isFile();
15
- } catch {
16
- return false;
17
- }
18
- };
19
-
20
- /**
21
- * 确保目录存在,不存在就创建一个
22
- * @param {*} dirname 目录名
23
- */
24
- const ensureDirExist = (dirname) => {
25
- if (!fs.existsSync(dirname)) {
26
- fs.mkdirSync(dirname, { recursive: true });
27
- }
28
- };
29
-
30
- // 复制文件
31
- const copyFile = function (src, dest) {
32
- if (fs.existsSync(dest)) {
33
- fs.unlinkSync(dest);
34
- }
35
- const dir = path.dirname(dest);
36
- ensureDirExist(dir);
37
- fs.copyFileSync(src, dest);
38
- };
39
-
40
- // 判断文件内容是否一致,不一致再进行拷贝
41
- function diffContentCopyFile(originFile, destFile) {
42
- if (fs.existsSync(destFile)) {
43
- const depDestContent = fs.readFileSync(destFile, 'utf8');
44
- const depOriginContent = fs.readFileSync(originFile, 'utf8');
45
- if (depDestContent !== depOriginContent) {
46
- console.log(`拷贝${originFile}内容到${destFile}`);
47
- copyFile(originFile, destFile);
48
- }
49
- } else {
50
- console.log(`拷贝${originFile}内容到${destFile}`);
51
- copyFile(originFile, destFile);
52
- }
53
- }
54
-
55
- // 添加后缀
56
- function ext(filePath, extensions) {
57
- let newFilePath = filePath;
58
- let extPath = '';
59
- // try catch需要包裹:用来处理'./lib/timer'没有后缀的情况
60
- try {
61
- const stat = fs.lstatSync(newFilePath);
62
- if (stat.isDirectory()) {
63
- extPath = newFilePath[newFilePath.length - 1] === '/' ? 'index' : '/index';
64
- newFilePath += extPath;
65
- }
66
- } catch (e) {}
67
-
68
- for (const ext of extensions) {
69
- const file = newFilePath.endsWith(ext) ? newFilePath : newFilePath + ext;
70
- if (fs.existsSync(file)) {
71
- return {
72
- ext,
73
- extPath: extPath + ext,
74
- file,
75
- };
76
- }
77
- }
78
- return {
79
- ext: '',
80
- extPath,
81
- file: filePath,
82
- };
83
- }
84
-
85
- // 判断文件是否在某个目录
86
- const fileInDir = (dir, file) => {
87
- if (!fs.existsSync(dir) || !fs.existsSync(file)) {
88
- return false;
89
- }
90
- const relativePath = path.relative(dir, file);
91
- if (relativePath.startsWith('..')) {
92
- return false;
93
- }
94
- return true;
95
- };
96
-
97
-
98
- module.exports = {
99
- isDirEmpty,
100
- copyFile,
101
- diffContentCopyFile,
102
- ensureDirExist,
103
- ext,
104
- fileInDir,
105
- isFile,
106
- };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { info } = require('../utils/log');
4
+ /**
5
+ * 判断目录是否为空
6
+ * @param {string} dirname 目录名
7
+ * @returns
8
+ */
9
+ const isDirEmpty = dirname => fs.promises.readdir(dirname).then(files => files.length === 0);
10
+
11
+ // 判断是否是文件
12
+ const isFile = (pathName) => {
13
+ try {
14
+ const stat = fs.lstatSync(pathName);
15
+ return stat.isFile();
16
+ } catch {
17
+ return false;
18
+ }
19
+ };
20
+
21
+ /**
22
+ * 确保目录存在,不存在就创建一个
23
+ * @param {*} dirname 目录名
24
+ */
25
+ const ensureDirExist = (dirname) => {
26
+ if (!fs.existsSync(dirname)) {
27
+ fs.mkdirSync(dirname, { recursive: true });
28
+ }
29
+ };
30
+
31
+ // 复制文件
32
+ const copyFile = function (src, dest) {
33
+ if (fs.existsSync(dest)) {
34
+ fs.unlinkSync(dest);
35
+ }
36
+ const dir = path.dirname(dest);
37
+ ensureDirExist(dir);
38
+ fs.copyFileSync(src, dest);
39
+ };
40
+
41
+ // 判断文件内容是否一致,不一致再进行拷贝
42
+ function diffContentCopyFile(originFile, destFile) {
43
+ if (fs.existsSync(destFile)) {
44
+ const depDestContent = fs.readFileSync(destFile, 'utf8');
45
+ const depOriginContent = fs.readFileSync(originFile, 'utf8');
46
+ if (depDestContent !== depOriginContent) {
47
+ info(`拷贝${originFile}内容到${destFile}`);
48
+ copyFile(originFile, destFile);
49
+ }
50
+ } else {
51
+ info(`拷贝${originFile}内容到${destFile}`);
52
+ copyFile(originFile, destFile);
53
+ }
54
+ }
55
+
56
+ // 添加后缀
57
+ function ext(filePath, extensions) {
58
+ let newFilePath = filePath;
59
+ let extPath = '';
60
+ // try catch需要包裹:用来处理'./lib/timer'没有后缀的情况
61
+ try {
62
+ const stat = fs.lstatSync(newFilePath);
63
+ if (stat.isDirectory()) {
64
+ extPath = newFilePath[newFilePath.length - 1] === '/' ? 'index' : '/index';
65
+ newFilePath += extPath;
66
+ }
67
+ } catch (e) {}
68
+
69
+ for (const ext of extensions) {
70
+ const file = newFilePath.endsWith(ext) ? newFilePath : newFilePath + ext;
71
+ if (fs.existsSync(file)) {
72
+ return {
73
+ ext,
74
+ extPath: extPath + ext,
75
+ file,
76
+ };
77
+ }
78
+ }
79
+ return {
80
+ ext: '',
81
+ extPath,
82
+ file: filePath,
83
+ };
84
+ }
85
+
86
+ // 判断文件是否在某个目录
87
+ const fileInDir = (dir, file) => {
88
+ if (!fs.existsSync(dir) || !fs.existsSync(file)) {
89
+ return false;
90
+ }
91
+ const relativePath = path.relative(dir, file);
92
+ if (relativePath.startsWith('..')) {
93
+ return false;
94
+ }
95
+ return true;
96
+ };
97
+
98
+
99
+ module.exports = {
100
+ isDirEmpty,
101
+ copyFile,
102
+ diffContentCopyFile,
103
+ ensureDirExist,
104
+ ext,
105
+ fileInDir,
106
+ isFile,
107
+ };
package/src/utils/log.js CHANGED
@@ -1,44 +1,47 @@
1
- const chalk = require('chalk');
2
-
3
- /**
4
- * 本文件提供无依赖的在终端打印彩色文字的方法。
5
- */
6
- const resetCfg = decodeURIComponent('%1B%5B0m'); // \033[0m转义后的字符按,用来还原属性
7
-
8
- /**
9
- * 打印红底黑字格式的文字
10
- * @param {String} message 需要打印的文字信息
11
- * @returns {undefined} 无
12
- */
13
- const fail = (message = '') => {
14
- const redStyleConfig = decodeURIComponent('%1B%5B41%3B30m'); // \033[41;30m转义后的字符按,console时输出红色文字
15
- const greenFontStyleConfig = decodeURIComponent('%1B%5B41%3B37m'); // \033[41;30m转义后的字符按,console时输出红底白色文字
16
- console.log(`${redStyleConfig} ERROR ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
17
- };
18
-
19
- /**
20
- * 打印绿底黑字格式的文字
21
- * @param {String} message 需要打印的文字信息
22
- * @returns {undefined} 无
23
- */
24
- const succeed = (message = '') => {
25
- const greenStyleConfig = decodeURIComponent('%1B%5B42%3B30m'); // \033[42;30m转义后的字符按,console时输出绿色文字
26
- const greenFontStyleConfig = decodeURIComponent('%1B%5B40%3B32m'); // \033[40;32m转义后的字符按,console时输出绿色文字
27
- console.log(`${greenStyleConfig} Success ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
28
- };
29
-
30
-
31
- /**
32
- * 打印warn提示
33
- * @param {String} message 需要打印的文字信息
34
- * @returns {undefined} 无
35
- */
36
- const warn = (message) => {
37
- console.log(chalk.yellow(message));
38
- };
39
-
40
- module.exports = {
41
- fail,
42
- succeed,
43
- warn,
44
- };
1
+ const chalk = require('chalk');
2
+
3
+ /**
4
+ * 本文件提供无依赖的在终端打印彩色文字的方法。
5
+ */
6
+ const resetCfg = decodeURIComponent('%1B%5B0m'); // \033[0m转义后的字符按,用来还原属性
7
+
8
+ /**
9
+ * 打印红底黑字格式的文字
10
+ * @param {String} message 需要打印的文字信息
11
+ * @returns {undefined} 无
12
+ */
13
+ const fail = (message = '') => {
14
+ const redStyleConfig = decodeURIComponent('%1B%5B41%3B30m'); // \033[41;30m转义后的字符按,console时输出红色文字
15
+ const greenFontStyleConfig = decodeURIComponent('%1B%5B41%3B37m'); // \033[41;30m转义后的字符按,console时输出红底白色文字
16
+ console.log(`${redStyleConfig} ERROR ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
17
+ };
18
+
19
+ /**
20
+ * 打印绿底黑字格式的文字
21
+ * @param {String} message 需要打印的文字信息
22
+ * @returns {undefined} 无
23
+ */
24
+ const succeed = (message = '') => {
25
+ const greenStyleConfig = decodeURIComponent('%1B%5B42%3B30m'); // \033[42;30m转义后的字符按,console时输出绿色文字
26
+ const greenFontStyleConfig = decodeURIComponent('%1B%5B40%3B32m'); // \033[40;32m转义后的字符按,console时输出绿色文字
27
+ console.log(`${greenStyleConfig} Success ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
28
+ };
29
+
30
+
31
+ /**
32
+ * 打印warn提示
33
+ * @param {String} message 需要打印的文字信息
34
+ * @returns {undefined} 无
35
+ */
36
+ const warn = (message) => {
37
+ console.log(chalk.yellow(message));
38
+ };
39
+
40
+ const info = (...args) => console.log(...args);
41
+
42
+ module.exports = {
43
+ fail,
44
+ succeed,
45
+ warn,
46
+ info,
47
+ };
@@ -1,167 +1,178 @@
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 { info } = require('./log');
9
+ const chalk = require('chalk');
10
+ const shelljsOptions = { slient: true, async: false };
11
+
12
+ // 获取当前目录
13
+ const cwd = process.cwd();
14
+ function resolve(...args) {
15
+ return path.resolve(cwd, ...args);
16
+ };
17
+
18
+
19
+ /**
20
+ * 用户输入命令时,进行提示
21
+ * @param {String} unknownCommand 非预期的命令
22
+ * @returns {Undefined} 无需返回值
23
+ */
24
+ const suggestCommands = (unknownCommand) => {
25
+ const availableCommands = program.commands.map(cmd => cmd._name);
26
+
27
+ let suggestion;
28
+ availableCommands.forEach((cmd) => {
29
+ const isBestMatch = leven(cmd, unknownCommand) < leven(suggestion || '', unknownCommand);
30
+ if (leven(cmd, unknownCommand) < 3 && isBestMatch) {
31
+ suggestion = cmd;
32
+ }
33
+ });
34
+
35
+ if (suggestion) {
36
+ info(` ${chalk.red(`Did you mean ${chalk.yellow(suggestion)}?`)}`);
37
+ }
38
+ };
39
+
40
+ /**
41
+ * 判断变量是否是一个数组
42
+ * @param { unknown } obj 变量
43
+ * @returns { boolean } 是否是一个数组
44
+ */
45
+ function isObject(obj) {
46
+ return Object.prototype.toString.call(obj) === '[object Object]';
47
+ }
48
+
49
+ /**
50
+ * 判断变量是否是一个对象
51
+ * @param { unknown } obj 变量
52
+ * @returns { boolean } 是否是一个对象
53
+ */
54
+ function isArray(obj) {
55
+ return Object.prototype.toString.call(obj) === '[object Array]';
56
+ }
57
+
58
+
59
+ /**
60
+ * 下载模块代码
61
+ * @param { string } url 模块地址
62
+ * @param { string } dest 目标地址
63
+ * @param { string } branch 分支名
64
+ * @returns { undefined } no return
65
+ */
66
+ function downloadRepoForGit(url, dest, branch) {
67
+ const cwd = process.cwd();
68
+ return new Promise((resolve, reject) => {
69
+ // 如果目标目录不存在
70
+ if (fs.existsSync(dest)) {
71
+ shelljs.rm('-rf', path.join(dest));
72
+ }
73
+
74
+ shelljs.mkdir('-p', dest);
75
+ shelljs.cd(dest);
76
+
77
+ shelljs.exec(`git clone ${url} ${dest} --branch ${branch} --depth 1`, { silent: true }, (code, stdout, stderr) => {
78
+ if (code !== 0) {
79
+ reject(stderr);
80
+ }
81
+ shelljs.cd(cwd);
82
+ resolve();
83
+ });
84
+ });
85
+ }
86
+
87
+
88
+ /**
89
+ * pull模块代码
90
+ * @param { string } dest 下载代码的路径
91
+ * @param { string } branch 分支名
92
+ * @returns { undefined } no return
93
+ */
94
+ function pullRepoForGit(dest, branch) {
95
+ const cwd = process.cwd();
96
+ return new Promise((resolve, reject) => {
97
+ shelljs.cd(dest);
98
+ shelljs.exec('git config pull.rebase false', shelljsOptions);
99
+ shelljs.exec(`git pull origin ${branch}`, { silent: true }, (code, stdout, stderr) => {
100
+ if (code !== 0) {
101
+ reject(stderr);
102
+ }
103
+ shelljs.cd(cwd);
104
+ resolve();
105
+ });
106
+ });
107
+ }
108
+
109
+ /**
110
+ * npm 下载依赖
111
+ * @param {*} dir
112
+ * @returns
113
+ */
114
+ function npmInstall(dir) {
115
+ return new Promise((resolve, reject) => {
116
+ shelljs.exec(
117
+ 'npx yarn --production --registry http://mirrors.tencent.com/npm/',
118
+ { cwd: dir, silent: true },
119
+ (code, stdout, stderr) => {
120
+ if (code !== 0) {
121
+ reject(stderr);
122
+ }
123
+ resolve();
124
+ },
125
+ );
126
+ });
127
+ }
128
+
129
+ /**
130
+ * 计算各项任务耗时
131
+ * @param {Number} start 任务开始时间
132
+ * @returns {Undefined} 无需返回值
133
+ */
134
+ const cost = start => Date.now() - start;
135
+
136
+ /**
137
+ * 创建构建子任务
138
+ * @param {Function} task 子任务执行函数
139
+ * @param {String} startText 任务开始前提示语
140
+ * @param {String} endText 任务结束后提示语
141
+ * @returns {Undefined} 无需返回值
142
+ */
143
+ function createTask(task, startText, endText) {
144
+ return async (...args) => {
145
+ const start = Date.now();
146
+
147
+ const spinner = ora(startText);
148
+
149
+ spinner.start();
150
+ info('\n');
151
+
152
+ const result = await task(...args);
153
+
154
+ endText && spinner.succeed(`${endText}, ${cost(start)}ms`);
155
+ spinner.stop();
156
+
157
+ return result;
158
+ };
159
+ };
160
+
161
+ /**
162
+ * 字符串驼峰化处理
163
+ * @param {String} str 需要处理的字符串
164
+ * @returns {String} 经过驼峰处理的字符串
165
+ */
166
+ const camelize = str => str.replace(/-(\w)/g, (a, c) => (c ? c.toUpperCase() : ''));
167
+
168
+ module.exports = {
169
+ resolve,
170
+ isObject,
171
+ isArray,
172
+ createTask,
173
+ downloadRepoForGit,
174
+ pullRepoForGit,
175
+ suggestCommands,
176
+ camelize,
177
+ npmInstall,
178
+ };