@tmsfe/tmskit 0.0.21 → 0.0.24-beta.0

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.
@@ -15,6 +15,7 @@ const { fail, succeed, info } = require('../../utils/log');
15
15
  const generator = require('./generator');
16
16
  const request = require('request');
17
17
  const unzip = require('unzipper');
18
+ const report = require('../../core/report');
18
19
 
19
20
  /**
20
21
  * 如果该目录下面存在文件,换个名字
@@ -71,6 +72,7 @@ async function create(projectName) {
71
72
  const cwd = process.cwd();
72
73
  const targetDir = path.resolve(cwd, projectName);
73
74
  const { projectType } = await inquirer.prompt(CREATE_TEMPLATE_QUESTION);
75
+ report('create-start', { projectType });
74
76
 
75
77
  // 创建项目目录
76
78
  await createProjectDir(targetDir);
@@ -101,7 +103,7 @@ async function create(projectName) {
101
103
  }
102
104
  shelljs.rm('-rf', resolve(projectName, TEMPLATE_TKIT_DIR));
103
105
  }
104
-
106
+ report('create-success', { projectType });
105
107
  succeed('项目创建完成.');
106
108
  })
107
109
  .catch((err) => {
@@ -0,0 +1,74 @@
1
+
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const shellJs = require('shelljs');
5
+ const { ensureDirExist } = require('../../utils/io');
6
+ const { EXTEND_CMD } = require('../../config/constant');
7
+ const { createTask } = require('../../utils/widgets');
8
+ const { info, fail } = require('../../utils/log');
9
+
10
+ /**
11
+ * 下载扩展命令的npm包
12
+ * @param {string} npmName npm包名
13
+ * @param {object} cmd {registry: 'http://mirrors.tencent.com/npm/'} 用户输入执行install-cmd的参数
14
+ */
15
+ async function installCmd(npmName, cmd) {
16
+ try {
17
+ const cmdPackageJson = `${EXTEND_CMD}/package.json`;
18
+ if (!fs.existsSync(cmdPackageJson)) {
19
+ ensureDirExist(EXTEND_CMD);
20
+ fs.writeFileSync(cmdPackageJson, JSON.stringify({ dependencies: {} }, null, 2));
21
+ }
22
+ shellJs.cd(EXTEND_CMD);
23
+ await createTask(npmName => new Promise((resolve, reject) => {
24
+ const registry = cmd.registry ? `--registry=${cmd.registry}` : '';
25
+ shellJs.exec(
26
+ `npm install --save ${npmName} ${registry}`,
27
+ { cwd: EXTEND_CMD, silent: true },
28
+ (code, stdout, stderr) => {
29
+ if (code !== 0) {
30
+ reject(stderr);
31
+ }
32
+ resolve();
33
+ },
34
+ );
35
+ }), `开始下载${npmName}`, `下载${npmName}完成`)(npmName);
36
+ } catch (e) {
37
+ fail('构建出现错误:');
38
+ info(e);
39
+ process.exit(1);
40
+ }
41
+ }
42
+
43
+
44
+ /**
45
+ * 加载扩展命令的npm包
46
+ * @returns
47
+ */
48
+ function loadExtendCmd() {
49
+ const cmdPackageJson = `${EXTEND_CMD}/package.json`;
50
+ const cmdNpmDir = `${EXTEND_CMD}/node_modules`;
51
+ if (fs.existsSync(cmdPackageJson)) {
52
+ const content = fs.readFileSync(cmdPackageJson, 'utf8');
53
+ const json = JSON.parse(content);
54
+ const deps = json.dependencies || {};
55
+
56
+ const cmdConfigs = [];
57
+ Object.keys(deps).forEach((name) => {
58
+ // 检索cmd的npm包
59
+ if (!/^tmskit-cmd-|^@[^/]+\/tmskit-cmd-/.test(name)) return false;
60
+ const cmdConfig = path.join(cmdNpmDir, name, 'tms.config.js');
61
+ if (fs.existsSync(cmdConfig)) {
62
+ cmdConfigs.push(cmdConfig);
63
+ }
64
+ });
65
+ return cmdConfigs;
66
+ }
67
+ return [];
68
+ }
69
+
70
+
71
+ module.exports = {
72
+ installCmd,
73
+ loadExtendCmd,
74
+ };
@@ -1,20 +1,27 @@
1
1
  const shelljs = require('shelljs');
2
2
  const { resolve, filterField } = require('../../../utils/widgets');
3
3
  const init = require('../init/index');
4
+ const { info } = require('../../../utils/log');
4
5
  const compileBuild = require('../../../compile/build');
6
+ const report = require('../../../core/report');
7
+ const { global } = require('../../../utils/global');
5
8
 
6
9
  async function build(tmsConfig, targetModules) {
7
10
  // 开始构建前,清理输出目录
8
11
  await shelljs.rm('-rf', resolve(tmsConfig.outputDir));
9
12
 
10
13
  const { modules: newModules } = await init(tmsConfig, targetModules);
14
+ info('当前build有效模块', newModules.map(item => item.moduleName).sort());
11
15
 
12
16
  const isDev = false;
13
- if (typeof tmsConfig?.hooks?.beforeCompile === 'function') {
14
- await tmsConfig?.hooks?.beforeCompile({
17
+ if (typeof tmsConfig?.hooks?.beforeFirstCompile === 'function') {
18
+ await tmsConfig?.hooks?.beforeFirstCompile({
15
19
  isDev,
16
20
  tmsConfig: filterField(tmsConfig, ['gitAccount']),
17
- modules: newModules });
21
+ modules: newModules,
22
+ cmdOptions: global.getData('cmdOptions'),
23
+ });
24
+ report('hooks:beforeCompile');
18
25
  };
19
26
  compileBuild(tmsConfig, newModules, isDev);
20
27
  }
@@ -5,6 +5,6 @@ module.exports = async (tmsConfig) => {
5
5
  try {
6
6
  await symLink(tmsConfig);
7
7
  } catch (e) {
8
- handleError(`创建软链错误: ${e}`);
8
+ handleError(`创建软链错误: ${e}`, true);
9
9
  }
10
10
  };
@@ -5,7 +5,9 @@ const init = require('../init/index');
5
5
  const { getModulesByMergeDepModules, getSubPackages } = require('../../../core/tmsMpconfig');
6
6
  const { info } = require('../../../utils/log');
7
7
  const { global } = require('../../../utils/global');
8
- const { CACHE_DIR } = require('../../../config/constant');
8
+ const { MODULE_CODE_DIR, NODE_MODULES_DIR } = require('../../../config/constant');
9
+ const report = require('../../../core/report');
10
+ const { recommendVersion } = require('../../../core/recommendVersion');
9
11
 
10
12
 
11
13
  // 用户编译分包时,需要将dist中其他分包(主包不能删除)的内容删除,否则其他分包的内容混入到主包(导致主包的体积超2M)
@@ -26,22 +28,27 @@ function delOtherPackages(tmsConfig, targetSubPackages) {
26
28
  }
27
29
 
28
30
  async function dev(tmsConfig, targetModules) {
29
- const { noCache } = global.getData('cmd');
31
+ const { noCache } = global.getData('cmdOptions');
30
32
  if (noCache) {
31
33
  shelljs.rm('-rf', resolve(tmsConfig.outputDir));
32
- shelljs.rm('-rf', CACHE_DIR);
34
+ shelljs.rm('-rf', MODULE_CODE_DIR);
35
+ shelljs.rm('-rf', NODE_MODULES_DIR);
33
36
  }
37
+ // 推荐tmskit的版本
38
+ await recommendVersion();
34
39
 
35
40
  // 初始化操作
36
41
  const { subPackages, modules: newModules } = await init(tmsConfig, targetModules);
37
42
 
38
43
  info('当前dev启动的有效模块', newModules.map(item => item.moduleName).sort());
39
- if (typeof tmsConfig?.hooks?.beforeCompile === 'function') {
40
- await tmsConfig?.hooks?.beforeCompile({
44
+ if (typeof tmsConfig?.hooks?.beforeFirstCompile === 'function') {
45
+ await tmsConfig?.hooks?.beforeFirstCompile({
41
46
  isDev: true,
42
47
  tmsConfig: filterField(tmsConfig, ['gitAccount']),
43
48
  modules: newModules,
49
+ cmdOptions: global.getData('cmdOptions'),
44
50
  });
51
+ report('hooks:beforeCompile');
45
52
  };
46
53
  delOtherPackages(tmsConfig, subPackages);
47
54
  compileDev(tmsConfig, newModules, true);
@@ -3,9 +3,12 @@ const init = require('./init/index');
3
3
  const dev = require('./dev/index');
4
4
  const build = require('./build/index');
5
5
  const install = require('./install/index');
6
+ const preview = require('./preview/index');
7
+ const upload = require('./upload/index');
6
8
  const cloud = require('./cloud/index');
7
9
  const { fail, info } = require('../../utils/log');
8
10
  const { global } = require('../../utils/global');
11
+ const report = require('../../core/report');
9
12
  const {
10
13
  getTmsConfig,
11
14
  getModulesByMergeDepModules,
@@ -13,10 +16,10 @@ const {
13
16
  getModulesByModuleNames,
14
17
  } = require('../../core/tmsMpconfig');
15
18
 
16
- const handleModuleArg = (cmd) => {
19
+ const handleModuleArg = (cmdOptions) => {
17
20
  // 单模块或多模块开发-用户通过脚手架参数指定的模块
18
- if (typeof cmd.module === 'string') {
19
- return cmd.module.split(',');
21
+ if (typeof cmdOptions.module === 'string') {
22
+ return cmdOptions.module.split(',');
20
23
  }
21
24
  return [];
22
25
  };
@@ -44,34 +47,35 @@ const getSpecificModuleNames = (moduleArg, modules) => {
44
47
  return all.map(item => item.moduleName);
45
48
  };
46
49
 
47
- async function run(commandName, cmd) {
50
+ async function run(commandName, cmdOptions) {
51
+ // 用户本地的配置
52
+ const tmsConfig = getTmsConfig();
48
53
  try {
49
- // 用户本地的配置
50
- const tmsConfig = getTmsConfig();
51
-
52
54
  // 缓存数据
53
55
  global.setData({
54
- cmd,
56
+ cmdOptions,
55
57
  tmsConfig,
56
58
  });
57
59
 
58
60
  if (commandName === 'cloud') {
59
61
  cloud(tmsConfig);
62
+ report('run:cloud', { appName: tmsConfig?.appName });
60
63
  return;
61
64
  }
62
- otherCommands(tmsConfig, commandName, cmd);
65
+ otherCommands(tmsConfig, commandName, cmdOptions);
63
66
  } catch (error) {
64
67
  const errMsg = typeof error === 'object' ? error.message : error;
68
+ report('run', { errMsg, appName: tmsConfig?.appName });
65
69
  fail(`构建出现错误: ${errMsg}`);
66
70
  info('详细错误信息', error);
67
71
  process.exit(1);
68
72
  }
69
73
  }
70
74
 
71
- function otherCommands(tmsConfig, commandName, cmd) {
75
+ function otherCommands(tmsConfig, commandName, cmdOptions) {
72
76
  // 处理module参数
73
77
  const specificModuleNames = getSpecificModuleNames(
74
- handleModuleArg(cmd),
78
+ handleModuleArg(cmdOptions),
75
79
  tmsConfig.modules,
76
80
  );
77
81
 
@@ -87,17 +91,29 @@ function otherCommands(tmsConfig, commandName, cmd) {
87
91
  switch (commandName) {
88
92
  case 'init':
89
93
  init(tmsConfig, newModules);
94
+ report('run:init', { appName: tmsConfig?.appName });
90
95
  return;
91
96
  case 'dev':
92
97
  global.setData('isDev', true);
93
98
  dev(tmsConfig, newModules);
99
+ report('run:dev', { appName: tmsConfig?.appName });
94
100
  return;
95
101
  case 'install':
96
102
  install(tmsConfig, subPackages, false);
103
+ report('run:install', { appName: tmsConfig?.appName });
97
104
  return;
98
105
  case 'build':
99
106
  global.setData('isDev', false);
100
107
  build(tmsConfig, newModules);
108
+ report('run:build', { appName: tmsConfig?.appName });
109
+ return;
110
+ case 'preview':
111
+ preview(tmsConfig, cmdOptions);
112
+ report('run:preview', { appName: tmsConfig?.appName });
113
+ return;
114
+ case 'upload':
115
+ upload(tmsConfig, cmdOptions);
116
+ report('run:upload', { appName: tmsConfig?.appName });
101
117
  return;
102
118
  default:
103
119
  return;
@@ -0,0 +1,36 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { NPM_CACHE_FILE } = require('../../../config/constant');
4
+ const { ensureDirExist } = require('../../../utils/io');
5
+
6
+ function getCache(projectDir, type) {
7
+ const filePath = NPM_CACHE_FILE;
8
+ if (!fs.existsSync(filePath)) {
9
+ return null;
10
+ }
11
+ const content = require(filePath);
12
+ return content?.[projectDir]?.[type];
13
+ }
14
+
15
+
16
+ function setCache(projectDir, type = 'miniprogram_npm', data) {
17
+ const filePath = NPM_CACHE_FILE;
18
+ if (!fs.existsSync(filePath)) {
19
+ const dir = path.dirname(filePath);
20
+ ensureDirExist(dir);
21
+ fs.writeFileSync(filePath, '{}');
22
+ }
23
+ const content = require(filePath);
24
+ if (!content[projectDir]) {
25
+ content[projectDir] = {};
26
+ }
27
+ content[projectDir] = {
28
+ [type]: data,
29
+ };
30
+ fs.writeFileSync(filePath, JSON.stringify(content, null, 2));
31
+ }
32
+
33
+ module.exports = {
34
+ setCache,
35
+ getCache,
36
+ };
@@ -4,8 +4,8 @@ const path = require('path');
4
4
  const io = require('../../../utils/io');
5
5
  const { createTask, resolve, getAbsolutePath } = require('../../../utils/widgets');
6
6
  const { buildMpNpm } = require('../../../core/mpCi');
7
- const { setCache, getCache } = require('../../../core/cache');
8
- const { CACHE_DIR } = require('../../../config/constant');
7
+ const { setCache, getCache } = require('./cache');
8
+ const { NODE_MODULES_DIR } = require('../../../config/constant');
9
9
  const { npmInstallAll } = require('../../../core/npm');
10
10
  const { info } = require('../../../utils/log');
11
11
  const { fileMd5 } = require('../../../utils/md5');
@@ -52,7 +52,7 @@ async function npmInstall(tmsConfig, subPackages, useCache) {
52
52
  if (fs.existsSync(modulePackagePath)) shelljs.cp('-Rf', modulePackagePath, outputModuleDir);
53
53
  });
54
54
 
55
- await npmInstallAll(subPackages, resolve(tmsConfig.outputDir), `${CACHE_DIR}/node_modules`);
55
+ await npmInstallAll(subPackages, resolve(tmsConfig.outputDir), NODE_MODULES_DIR);
56
56
  return { isCache: false };
57
57
  }
58
58
 
@@ -0,0 +1,70 @@
1
+ const mpCi = require('../../../core/mpCi');
2
+ const fs = require('fs');
3
+ const { resolve, createTask, getAbsolutePath, filterField } = require('../../../utils/widgets');
4
+ const { handleError } = require('../../../core/handleError');
5
+ const { info } = require('../../../utils/log');
6
+ const { global } = require('../../../utils/global');
7
+ const { getAllSize, outputInfo, getDefaultDesc } = require('./utils');
8
+ const report = require('../../../core/report');
9
+
10
+
11
+ const handleParams = (tmsConfig, cmdOptions) => {
12
+ const params = {
13
+ ...(tmsConfig.preview ? tmsConfig.preview : {}),
14
+ ...cmdOptions,
15
+ };
16
+ return {
17
+ ...params,
18
+ appId: params.appId || tmsConfig.appId,
19
+ projectPath: resolve(tmsConfig.outputDir),
20
+ privateKey: params.privateKey || tmsConfig.privateKey,
21
+ robot: params.robot || 30,
22
+ desc: params.desc || getDefaultDesc(),
23
+ qrcodeOutputDest: getAbsolutePath(params.qrcodeOutputDest || ''),
24
+ };
25
+ };
26
+
27
+ /**
28
+ * 预览
29
+ * @params {object} tmsConfig
30
+ * @param {object} cmdOptions {qrcodeFormat: 'base64', qrcodeOutputDest: './a.txt', robot: 2, infoOutput: './a.txt' }
31
+ */
32
+ async function preview(tmsConfig, cmdOptions) {
33
+ try {
34
+ const params = handleParams(tmsConfig, cmdOptions);
35
+ if (typeof tmsConfig?.hooks?.beforePreview === 'function') {
36
+ await tmsConfig?.hooks?.beforePreview({
37
+ tmsConfig: filterField(tmsConfig, ['gitAccount']),
38
+ cmdOptions: global.getData('cmdOptions'),
39
+ params,
40
+ });
41
+ report('hooks:beforePreview');
42
+ };
43
+ const previewRes = await createTask(
44
+ mpCi.previewMp,
45
+ '正在构建预览码',
46
+ '构建预览码完成',
47
+ )({
48
+ ...params,
49
+ });
50
+
51
+ const allSize = getAllSize(previewRes);
52
+ if (params.infoOutput) {
53
+ let qrcodeBase64 = '';
54
+ if (params.qrcodeFormat === 'base64' && fs.existsSync(params.qrcodeOutputDest)) {
55
+ qrcodeBase64 = fs.readFileSync(params.qrcodeOutputDest, 'utf8');
56
+ }
57
+ outputInfo(params.infoOutput, {
58
+ sourceCode: params.projectPath,
59
+ qrcodeBase64,
60
+ ...previewRes,
61
+ });
62
+ }
63
+ info('预览包大小:', `${allSize}k`);
64
+ } catch (e) {
65
+ console.log('详细错误:', e);
66
+ handleError(`预览错误: ${e.message}`, true);
67
+ }
68
+ }
69
+
70
+ module.exports = preview;
@@ -0,0 +1,43 @@
1
+ const moment = require('moment');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const { getGitUser, getAbsolutePath } = require('../../../utils/widgets');
5
+ const { ensureDirExist } = require('../../../utils/io');
6
+
7
+ function getAllSize(data = {}) {
8
+ let allSize;
9
+ for (const item of data?.subPackageInfo) {
10
+ if (item.name === '__FULL__') {
11
+ allSize = item.size;
12
+ break;
13
+ }
14
+ }
15
+ return allSize;
16
+ }
17
+
18
+ const getDefaultDesc = () => {
19
+ const user = getGitUser();
20
+ const date = moment().format('YYYY-MM-DD HH:mm:ss');
21
+ return `构建人: ${user}; 构建时间:${date}`;
22
+ };
23
+
24
+ const outputInfo = (infoOutput, data) => {
25
+ const outPath = getAbsolutePath(infoOutput);
26
+ const dir = path.dirname(outPath);
27
+ ensureDirExist(dir);
28
+ fs.writeFileSync(outPath, JSON.stringify(data, null, 2));
29
+ };
30
+
31
+ const getDetaultVersion = () => {
32
+ const version = moment().format('gggg,mm')
33
+ .split(',');
34
+ version.push('0');
35
+ return version.join('.');
36
+ };
37
+
38
+ module.exports = {
39
+ getAllSize,
40
+ getDefaultDesc,
41
+ outputInfo,
42
+ getDetaultVersion,
43
+ };
@@ -0,0 +1,65 @@
1
+ const mpCi = require('../../../core/mpCi');
2
+ const { resolve, createTask, filterField } = require('../../../utils/widgets');
3
+ const { handleError } = require('../../../core/handleError');
4
+ const { info } = require('../../../utils/log');
5
+ const { global } = require('../../../utils/global');
6
+ const { getAllSize, outputInfo, getDefaultDesc } = require('../preview/utils');
7
+ const report = require('../../../core/report');
8
+
9
+ const handleParams = (tmsConfig, cmdOptions) => {
10
+ const params = {
11
+ ...(tmsConfig.upload ? tmsConfig.upload : {}),
12
+ ...cmdOptions,
13
+ };
14
+
15
+ if (!params.version) {
16
+ throw new Error('请指定传入版本号 eg: tmskit run upload -v 2022.28.5');
17
+ }
18
+ return {
19
+ ...params,
20
+ appId: params.appId || tmsConfig.appId,
21
+ projectPath: resolve(tmsConfig.outputDir),
22
+ privateKey: params.privateKey || tmsConfig.privateKey,
23
+ robot: params.robot || 30,
24
+ desc: params.desc || getDefaultDesc(),
25
+ };
26
+ };
27
+
28
+ /**
29
+ * 上传
30
+ * @param {object} tmsConfig
31
+ * @param {object} cmdOptions {version: '2022.28.5', desc: '', robot: 2, infoOutput: './a.txt' }
32
+ */
33
+ async function upload(tmsConfig, cmdOptions) {
34
+ try {
35
+ const params = handleParams(tmsConfig, cmdOptions);
36
+ if (typeof tmsConfig?.hooks?.beforeUpload === 'function') {
37
+ await tmsConfig?.hooks?.beforeUpload({
38
+ tmsConfig: filterField(tmsConfig, ['gitAccount']),
39
+ cmdOptions: global.getData('cmdOptions'),
40
+ params,
41
+ });
42
+ report('hooks:beforeUpload');
43
+ };
44
+ const uploadRes = await createTask(
45
+ mpCi.uploadMp,
46
+ '正在构建预览码',
47
+ '构建预览码完成',
48
+ )({
49
+ ...params,
50
+ });
51
+
52
+ const allSize = getAllSize(uploadRes);
53
+ if (params.infoOutput) {
54
+ outputInfo(params.infoOutput, {
55
+ sourceCode: params.projectPath,
56
+ ...uploadRes,
57
+ });
58
+ }
59
+ info(`上传包大小: ${allSize}k; 上传包版本: ${params.version}`);
60
+ } catch (e) {
61
+ console.log('详细错误:', e);
62
+ handleError(`上传错误: ${e.message}`, true);
63
+ }
64
+ }
65
+ module.exports = upload;
package/src/utils/log.js CHANGED
@@ -40,9 +40,12 @@ const warn = (message) => {
40
40
 
41
41
  const info = (...args) => console.log(`${moment().format('YYYY-MM-DD HH:mm:ss')}`, ...args);
42
42
 
43
+ const infoNoTime = (...args) => console.log(...args);
44
+
43
45
  module.exports = {
44
46
  fail,
45
47
  succeed,
46
48
  warn,
47
49
  info,
50
+ infoNoTime,
48
51
  };
@@ -1,13 +1,10 @@
1
1
 
2
- const program = require('commander');
3
- const leven = require('leven');
4
2
  const ora = require('ora');
5
3
  const path = require('path');
6
4
  const fs = require('fs');
7
5
  const shelljs = require('shelljs');
8
6
  const glob = require('glob-ignore');
9
7
  const { info } = require('./log');
10
- const chalk = require('chalk');
11
8
  const shelljsOptions = { slient: true, async: false };
12
9
 
13
10
  // 获取当前目录
@@ -16,28 +13,6 @@ function resolve(...args) {
16
13
  return path.resolve(cwd, ...args);
17
14
  };
18
15
 
19
-
20
- /**
21
- * 用户输入命令时,进行提示
22
- * @param {String} unknownCommand 非预期的命令
23
- * @returns {Undefined} 无需返回值
24
- */
25
- const suggestCommands = (unknownCommand) => {
26
- const availableCommands = program.commands.map(cmd => cmd._name);
27
-
28
- let suggestion;
29
- availableCommands.forEach((cmd) => {
30
- const isBestMatch = leven(cmd, unknownCommand) < leven(suggestion || '', unknownCommand);
31
- if (leven(cmd, unknownCommand) < 3 && isBestMatch) {
32
- suggestion = cmd;
33
- }
34
- });
35
-
36
- if (suggestion) {
37
- info(` ${chalk.red(`Did you mean ${chalk.yellow(suggestion)}?`)}`);
38
- }
39
- };
40
-
41
16
  /**
42
17
  * 判断变量是否是一个数组
43
18
  * @param { unknown } obj 变量
@@ -109,13 +84,15 @@ function pullRepoForGit(dest, branch) {
109
84
 
110
85
  /**
111
86
  * npm 下载依赖
112
- * @param {*} dir
87
+ * @param {string} dir 下载npm的目录
88
+ * @param {object} npm npm的配置 (见下获取npm源入参)
113
89
  * @returns
114
90
  */
115
- function npmInstall(dir) {
91
+ function npmInstall(dir, npmConfig) {
116
92
  return new Promise((resolve, reject) => {
93
+ const registry = getNpmRegistry(npmConfig);
117
94
  shelljs.exec(
118
- 'npm install --production --registry http://mirrors.tencent.com/npm/',
95
+ `npm install --production ${registry}`,
119
96
  { cwd: dir, silent: true },
120
97
  (code, stdout, stderr) => {
121
98
  if (code !== 0) {
@@ -127,6 +104,28 @@ function npmInstall(dir) {
127
104
  });
128
105
  }
129
106
 
107
+ // 获取npm源
108
+ // 入参:{
109
+ // registry: "https://registry.npmjs.org/",
110
+ // scope: {
111
+ // "@tencent": "http://mirrors.tencent.com/npm/"
112
+ // }
113
+ // }
114
+ // 出参: --@tencent:registry=http://mirrors.tencent.com/npm/ --registry=https://registry.npmjs.org/
115
+ function getNpmRegistry(npmConfig = {}) {
116
+ let resRegistry = '';
117
+ if (npmConfig.registry) {
118
+ resRegistry = ` --registry=${npmConfig.registry}`;
119
+ }
120
+
121
+ if (isObject(npmConfig.scope)) {
122
+ Object.keys(npmConfig.scope).forEach((key) => {
123
+ resRegistry += ` --${key}:registry=${npmConfig.scope[key]}`;
124
+ });
125
+ }
126
+ return resRegistry;
127
+ }
128
+
130
129
  /**
131
130
  * 计算各项任务耗时
132
131
  * @param {Number} start 任务开始时间
@@ -167,11 +166,7 @@ const camelize = str => str.replace(/-(\w)/g, (a, c) => (c ? c.toUpperCase() : '
167
166
 
168
167
  const mergeMap = function (obj, src) {
169
168
  for (const [k, v] of src) {
170
- if (obj.has(k)) {
171
- obj.set(k, obj.get(k) + v);
172
- } else {
173
- obj.set(k, v);
174
- }
169
+ obj.set(k, v);
175
170
  }
176
171
 
177
172
  return obj;
@@ -217,6 +212,30 @@ function getAbsolutePath(pathDir, cwd = '') {
217
212
  return newPath;
218
213
  }
219
214
 
215
+ // 版本比较 => 1(大于), 0(等于), -1(小于)
216
+ function versionCompare(v1, v2) {
217
+ // 将两个版本号拆成数组
218
+ const arr1 = v1.split('.');
219
+ const arr2 = v2.split('.');
220
+ const minLength = Math.min(arr1.length, arr2.length);
221
+ // 依次比较版本号每一位大小
222
+ for (let i = 0; i < minLength; i++) {
223
+ if (parseInt(arr1[i], 10) !== parseInt(arr2[i], 10)) {
224
+ return (parseInt(arr1[i], 10) > parseInt(arr2[i], 10)) ? 1 : -1;
225
+ }
226
+ }
227
+ // 若前几位分隔相同,则按分隔数比较。
228
+ if (arr1.length === arr2.length) {
229
+ return 0;
230
+ }
231
+ return (arr1.length > arr2.length) ? 1 : -1;
232
+ }
233
+
234
+ function getGitUser() {
235
+ const res = shelljs.exec('git config user.name', { async: false, silent: true });
236
+ return res.stdout;
237
+ }
238
+
220
239
  module.exports = {
221
240
  resolve,
222
241
  isObject,
@@ -224,7 +243,6 @@ module.exports = {
224
243
  createTask,
225
244
  downloadRepoForGit,
226
245
  pullRepoForGit,
227
- suggestCommands,
228
246
  camelize,
229
247
  npmInstall,
230
248
  mergeMap,
@@ -232,4 +250,7 @@ module.exports = {
232
250
  filterField,
233
251
  findFiles,
234
252
  getAbsolutePath,
253
+ getNpmRegistry,
254
+ versionCompare,
255
+ getGitUser,
235
256
  };