@tmsfe/tmskit 0.0.24 → 0.0.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmsfe/tmskit",
3
- "version": "0.0.24",
3
+ "version": "0.0.27",
4
4
  "description": "tmskit",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {
@@ -33,6 +33,7 @@
33
33
  "@rollup/plugin-json": "^4.0.3",
34
34
  "rollup": "^2.6.1"
35
35
  },
36
+ "whiteDependencies": {},
36
37
  "dependencies": {
37
38
  "ansi-colors": "1.1.0",
38
39
  "anymatch": "^1.3.0",
@@ -40,7 +41,6 @@
40
41
  "chalk": "^4.1.0",
41
42
  "chokidar": "^3.5.3",
42
43
  "commander": "^8.3.0",
43
- "copy-webpack-plugin": "^9.1.0",
44
44
  "ejs": "^3.1.5",
45
45
  "fancy-log": "1.3.2",
46
46
  "fs-extra": "^10.0.1",
@@ -55,10 +55,10 @@
55
55
  "lodash": "^4.17.21",
56
56
  "metalsmith": "^2.3.0",
57
57
  "minimatch": "^5.1.0",
58
- "miniprogram-ci": "1.4.13",
58
+ "miniprogram-ci": "1.8.25",
59
59
  "moment": "^2.29.2",
60
60
  "object-assign": "^4.0.1",
61
- "ora": "^5.1.0",
61
+ "ora": "^5.4.1",
62
62
  "path-is-absolute": "^1.0.1",
63
63
  "plugin-error": "^1.0.0",
64
64
  "postcss": "^8.4.6",
@@ -66,7 +66,7 @@
66
66
  "readable-stream": "^2.2.2",
67
67
  "replace-ext": "^2.0.0",
68
68
  "request": "^2.88.2",
69
- "shelljs": "^0.8.4",
69
+ "shelljs": "^0.8.5",
70
70
  "slash": "^1.0.0",
71
71
  "strip-comments": "^2.0.1",
72
72
  "through2": "^4.0.2",
@@ -81,4 +81,4 @@
81
81
  "jest": {
82
82
  "testEnvironment": "jest-environment-node"
83
83
  }
84
- }
84
+ }
package/src/.DS_Store ADDED
Binary file
@@ -10,6 +10,7 @@ const compile = require('./compile');
10
10
  const watch = require('./watch');
11
11
  const { info } = require('../utils/log');
12
12
  const report = require('../core/report');
13
+ const { global } = require('../utils/global');
13
14
 
14
15
  const watchEvents = ['add', 'change', 'unlink', 'addDir', 'unlinkDir'];
15
16
 
@@ -118,6 +119,7 @@ module.exports = async (tmsConfig, modules, isDev = true) => {
118
119
  isDev,
119
120
  tmsConfig: filterField(tmsConfig, ['gitAccount']),
120
121
  modules,
122
+ cmdOptions: global.getData('cmdOptions'),
121
123
  });
122
124
  report('hooks:afterCompile');
123
125
  }
@@ -107,6 +107,7 @@ async function updateFileHook(tmsConfig, sourceFile, targetFile, type) {
107
107
  if (typeof tmsConfig?.hooks?.updateFile === 'function') {
108
108
  await tmsConfig.hooks.updateFile({
109
109
  tmsConfig: filterField(tmsConfig, ['gitAccount']),
110
+ cmdOptions: global.getData('cmdOptions'),
110
111
  sourceFile,
111
112
  targetFile,
112
113
  type,
@@ -13,4 +13,31 @@ module.exports = {
13
13
  sourceDir: './',
14
14
  /** 静态资源目录 */
15
15
  static: [],
16
+ /** 上传是的配置 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E7%BC%96%E8%AF%91%E8%AE%BE%E7%BD%AE */
17
+ upload: {
18
+ setting: {
19
+ es6: true,
20
+ es7: true,
21
+ minify: true,
22
+ minifyJS: true,
23
+ minifyWXML: true,
24
+ minifyWXSS: true,
25
+ autoPrefixWXSS: true,
26
+ },
27
+ },
28
+ /** 预览的配置 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E9%A2%84%E8%A7%88 */
29
+ preview: {
30
+ setting: {
31
+ es6: true,
32
+ es7: true,
33
+ minify: true,
34
+ minifyJS: true,
35
+ minifyWXML: true,
36
+ minifyWXSS: true,
37
+ autoPrefixWXSS: true,
38
+ },
39
+ },
40
+ npm: {
41
+ registry: 'https://registry.npmjs.org/',
42
+ },
16
43
  };
@@ -143,6 +143,7 @@ function buildOutputAppJson(tmsConfig, modules) {
143
143
  if (typeof tmsConfig?.hooks?.updateAppJson === 'function') {
144
144
  tmsConfig?.hooks?.updateAppJson({
145
145
  tmsConfig: filterField(tmsConfig, ['gitAccount']),
146
+ cmdOptions: global.getData('cmdOptions'),
146
147
  modules,
147
148
  appJson,
148
149
  isDev: global.getData('isDev'),
@@ -21,7 +21,8 @@ function replaceGitUrlAccount(httpRepoUrl, moduleName) {
21
21
  const tmsConfig = global.getData('tmsConfig');
22
22
 
23
23
  let gitUrl = httpRepoUrl;
24
- const { username = '', pass = '' } = tmsConfig?.gitAccount?.[moduleName] || {};
24
+
25
+ const { username = '', pass = '' } = tmsConfig?.gitAccount?.[moduleName] || tmsConfig?.gitAccount?.[httpRepoUrl] || {};
25
26
 
26
27
  const urlPrefixReg = /http(s)?:\/\//;
27
28
  if (username && pass && urlPrefixReg.test(gitUrl)) {
@@ -150,7 +151,6 @@ function collectDownLoadTasksMap(sourceDir, targetDir, modules) {
150
151
  ]);
151
152
  },
152
153
  };
153
-
154
154
  if (downloadTasksMap.has(sourcePath)) {
155
155
  const task = downloadTasksMap.get(sourcePath);
156
156
  task.callbacks.push(callback);
@@ -159,7 +159,7 @@ function collectDownLoadTasksMap(sourceDir, targetDir, modules) {
159
159
  let promiseTask;
160
160
  if (fs.existsSync(sourcePath) && fs.existsSync(`${sourcePath}/.git`)) {
161
161
  promiseTask = (gitUrl, sourcePath, branch, httpRepoUrl) => {
162
- info(`git pull:${httpRepoUrl}`);
162
+ info(`git pull:${httpRepoUrl} --branch: ${branch}`);
163
163
  return pullRepoForGit(sourcePath, branch);
164
164
  };
165
165
  } else {
package/src/core/mpCi.js CHANGED
@@ -6,8 +6,8 @@ const path = require('path');
6
6
  * @returns {Object} 小程序ci对象
7
7
  */
8
8
  const getMpCi = ({ appId, projectPath, type = 'miniProgram', privateKey = 'TODO' }) => {
9
- const cfgJsonContent = require(path.join(projectPath, 'project.config.json'));
10
- const ignores = cfgJsonContent?.packOptions?.ignore.map(({ value }) => value) || [];
9
+ const projectCg = require(path.join(projectPath, 'project.config.json'));
10
+ const ignores = projectCg?.packOptions?.ignore?.map(({ value }) => value) || [];
11
11
 
12
12
  return new ci.Project({
13
13
  appid: appId,
@@ -18,14 +18,6 @@ const getMpCi = ({ appId, projectPath, type = 'miniProgram', privateKey = 'TODO'
18
18
  });
19
19
  };
20
20
 
21
-
22
- // 用小程序ci工具构建小程序
23
- const packMpProject = async (project) => {
24
- await ci.packNpm(project, {
25
- ignores: ['cloud/**/*'],
26
- });
27
- };
28
-
29
21
  /**
30
22
  * 格式化构建npm结果信息
31
23
  * @param {Array<String>} warning 构建时的告警信息
@@ -43,21 +35,27 @@ const formatPackNpmWarning = (warning) => {
43
35
  };
44
36
 
45
37
  /**
46
- * 构建miniprogram_npm
47
- * @returns {Object} 小程序ci对象
38
+ * 构建miniprogram_npm https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E6%9E%84%E5%BB%BAnpm
39
+ * * @param {object} {
40
+ * appId,
41
+ * peojectPath,
42
+ * privateKey,
43
+ * }
48
44
  */
49
45
  const buildMpNpm = async ({
50
46
  appId,
51
47
  projectPath,
52
48
  privateKey,
53
49
  }) => {
54
- const mpCi = await getMpCi({
50
+ const mpCi = getMpCi({
55
51
  appId,
56
52
  projectPath,
57
53
  privateKey,
58
54
  });
59
55
 
60
- const packNpmWarning = await packMpProject(mpCi);
56
+ const packNpmWarning = await ci.packNpm(mpCi, {
57
+ ignores: ['cloud/**/*'],
58
+ });
61
59
 
62
60
  const packNpmMsg = formatPackNpmWarning(packNpmWarning);
63
61
  if (packNpmMsg) {
@@ -67,7 +65,57 @@ const buildMpNpm = async ({
67
65
  return Promise.resolve();
68
66
  };
69
67
 
68
+ /**
69
+ * 预览小程序码 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E9%A2%84%E8%A7%88
70
+ * @param {object} {
71
+ * appId,
72
+ * peojectPath,
73
+ * privateKey,
74
+ * desc
75
+ * robot
76
+ * }
77
+ */
78
+ const previewMp = async (params = {}) => {
79
+ const { appId, projectPath, privateKey, ...resetParams } = params;
80
+ const mpCi = await getMpCi({
81
+ appId,
82
+ projectPath,
83
+ privateKey,
84
+ });
85
+
86
+ return await ci.preview({
87
+ project: mpCi,
88
+ ...resetParams,
89
+ onProgressUpdate: () => {},
90
+ });
91
+ };
92
+
93
+ /**
94
+ * 上传小程序 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E4%B8%8A%E4%BC%A0
95
+ * @param {object} {
96
+ * appId,
97
+ * peojectPath,
98
+ * privateKey,
99
+ * version,
100
+ * desc
101
+ * }
102
+ */
103
+ const uploadMp = async (params = {}) => {
104
+ const { appId, projectPath, privateKey, ...resetParams } = params;
105
+ const mpCi = await getMpCi({
106
+ appId,
107
+ projectPath,
108
+ privateKey,
109
+ });
110
+ return await ci.upload({
111
+ project: mpCi,
112
+ ...resetParams,
113
+ onProgressUpdate: () => {},
114
+ });
115
+ };
70
116
 
71
117
  module.exports = {
72
118
  buildMpNpm,
119
+ previewMp,
120
+ uploadMp,
73
121
  };
@@ -1,12 +1,7 @@
1
1
  const request = require('request');
2
- const shelljs = require('shelljs');
2
+ const { getGitUser } = require('../utils/widgets');
3
3
  const apiUrl = 'https://tim.map.qq.com/basic/tmskit/upload';
4
4
 
5
- function getGitUser() {
6
- const res = shelljs.exec('git config user.name', { async: false, silent: true });
7
- return res.stdout;
8
- }
9
-
10
5
  const report = (name, attrs = {}) => {
11
6
  try {
12
7
  const param = [];
@@ -19,7 +14,7 @@ const report = (name, attrs = {}) => {
19
14
  if (!param[i]) param[i] = null;
20
15
  };
21
16
 
22
- request.post({ url: apiUrl, json: { param } });
17
+ request.post({ url: apiUrl, json: { param } }, () => {});
23
18
  // (error, response, body) => {
24
19
  // console.log('body:', body);
25
20
  // }
@@ -118,20 +118,8 @@ function adaptMpCgContent(fileContent, appName) {
118
118
  return content;
119
119
  }
120
120
 
121
- const adaptDependencies = function (dependencies, subPackages) {
122
- const newDependencies = dependencies || [];
123
- subPackages.forEach((item) => {
124
- if (item.dependencies) {
125
- dependencies = newDependencies.concat(item.dependencies);
126
- }
127
- });
128
- return newDependencies;
129
- };
130
-
131
121
  const adaptSubPackages = function (moduleConfig, appName) {
132
- const subPackages = isObject(moduleConfig) && moduleConfig.subPackages
133
- ? moduleConfig.subPackages
134
- : isObject(moduleConfig) ? [moduleConfig] : moduleConfig;
122
+ const { subPackages } = moduleConfig;
135
123
  return adaptMpCgContent(subPackages, appName);
136
124
  };
137
125
 
@@ -153,11 +141,9 @@ function getModulesConfig(modules = [], appName) {
153
141
 
154
142
  // 兼容历史逻辑,后续可删除--- start
155
143
  const subPackages = adaptSubPackages(moduleConfig, appName);
156
- const dependencies = adaptDependencies(moduleConfig.dependencies, subPackages);
157
144
  moduleConfig = {
158
145
  ...(isObject(moduleConfig) ? moduleConfig : {}),
159
146
  subPackages,
160
- dependencies,
161
147
  };
162
148
  // 兼容逻辑--- end
163
149
  modulesConfig.push(moduleConfig);
@@ -210,10 +196,6 @@ const getSubPackageSrcPath = function (tmsConfig, module, subPackage) {
210
196
  const checkModuleItem = (tmsConfig, tmsModuleItem, moduleConfig) => {
211
197
  const newModuleItem = { ...tmsModuleItem, ...moduleConfig };
212
198
 
213
- // 兼容逻辑
214
- if (!newModuleItem.moduleName) newModuleItem.moduleName = newModuleItem.name;
215
- delete newModuleItem.name;
216
-
217
199
  // 参数校验-模块源码路径
218
200
  if (!newModuleItem.path) {
219
201
  throw new Error(`${newModuleItem.moduleName}模块没有找到path字段,请检查tms.config.js的modules.all>module>path路径`);
@@ -250,6 +232,9 @@ const getModulesByMergeDepModules = (tmsConfig, modules, errorIsQuit = false) =>
250
232
  const allModules = new Map();
251
233
  function dfs(tmsConfig, modules) {
252
234
  modules.forEach((moduleItem) => {
235
+ if (!moduleItem.path) {
236
+ throw new Error(`${moduleItem.moduleName}模块没有找到path字段,请检查tms.config.js的modules.all>module>path路径`);
237
+ }
253
238
  const moduleConfigPath = resolve(moduleItem.path, MODULE_CONFIG_FILENAME);
254
239
  if (!fs.existsSync(moduleConfigPath)) {
255
240
  if (!allModules.has(moduleItem.moduleName)) {
package/src/entry.js CHANGED
@@ -12,9 +12,9 @@ module.exports = [
12
12
  options: [
13
13
  ['--registry [registry]', 'npm源'],
14
14
  ],
15
- action: (npmName, cmd) => {
15
+ action: (npmName, cmdOptions) => {
16
16
  const res = require('./scripts/extend-cmd');
17
- res.installCmd(npmName, cmd);
17
+ res.installCmd(npmName, cmdOptions);
18
18
  },
19
19
  },
20
20
  {
@@ -29,8 +29,8 @@ module.exports = [
29
29
  ['-m, --module [moduleName]', '模块名称'],
30
30
  ['-e, --env [env]', '环境变量'],
31
31
  ],
32
- action: (cmd) => {
33
- require('./scripts/run/index')('install', cmd);
32
+ action: (cmdOptions) => {
33
+ require('./scripts/run/index')('install', cmdOptions);
34
34
  },
35
35
  },
36
36
  {
@@ -41,32 +41,66 @@ module.exports = [
41
41
  ['-e, --env [env]', '环境变量'],
42
42
  ['-noCache, --noCache', '不使用缓存功能'],
43
43
  ],
44
- action: (cmd) => {
45
- require('./scripts/run/index')('dev', cmd);
44
+ action: (cmdOptions) => {
45
+ require('./scripts/run/index')('dev', cmdOptions);
46
46
  },
47
47
  },
48
48
  {
49
- command: 'cloud',
50
- description: '云函数开发',
49
+ command: 'build',
50
+ description: 'prod 打包编译',
51
51
  options: [
52
52
  ['-m, --module [moduleName]', '模块名称'],
53
53
  ['-e, --env [env]', '环境变量'],
54
54
  ],
55
- action: (cmd) => {
56
- require('./scripts/run/index')('cloud', cmd);
55
+ action: (cmdOptions) => {
56
+ require('./scripts/run/index')('build', cmdOptions);
57
57
  },
58
58
  },
59
59
  {
60
- command: 'build',
61
- description: 'prod 打包编译',
60
+ command: 'preview',
61
+ description: '小程序预览',
62
62
  options: [
63
- ['-m, --module [moduleName]', '模块名称'],
64
- ['-e, --env [env]', '环境变量'],
63
+ ['-f, --qrcodeFormat [qrcodeFormat]', '二维码的格式,选项terminal, image, base64。默认terminal'],
64
+ ['-o, --qrcodeOutputDest [qrcodeOutputDest]', '二维码会被输出到给定路径'],
65
+ ['-i, --info-output [infoOutput]', '相关信息会被输出到给定路径'],
66
+ ],
67
+ action: (cmdOptions) => {
68
+ require('./scripts/run/index')('preview', cmdOptions);
69
+ },
70
+ },
71
+ {
72
+ command: 'upload',
73
+ description: '小程序上传',
74
+ options: [
75
+ ['--version [version]', '上传代码版本,version 指定版本号'],
76
+ ['-d, --desc [desc]', '上传代码时的备注'],
77
+ ['-i, --info-output [infoOutput]', '相关信息会被输出到给定路径'],
78
+ ['-r, --robot [robot]', '指定使用哪一个 ci 机器人,可选值:1 ~ 30'],
79
+ ],
80
+ action: (cmdOptions) => {
81
+ require('./scripts/run/index')('upload', cmdOptions);
82
+ },
83
+ },
84
+ {
85
+ command: 'cloud-dev',
86
+ description: '云函数开发',
87
+ options: [
88
+ ['--cloud [cloud]', '模块名称'],
65
89
  ],
66
- action: (cmd) => {
67
- require('./scripts/run/index')('build', cmd);
90
+ action: (cmdOptions) => {
91
+ require('./scripts/run/index')('cloud-dev', cmdOptions);
68
92
  },
69
93
  },
94
+ // {
95
+ // command: 'cloud-link',
96
+ // description: '云函数开发',
97
+ // options: [
98
+ // ['--cloud [cloud]', '模块名称'],
99
+ // ],
100
+ // action: (cmdOptions) => {
101
+ // require('./scripts/run/index')('cloud-link', cmdOptions);
102
+ // },
103
+ // },
70
104
  ],
71
105
  },
72
106
  ];
Binary file
@@ -1,21 +1,26 @@
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');
5
6
  const report = require('../../../core/report');
7
+ const { global } = require('../../../utils/global');
6
8
 
7
9
  async function build(tmsConfig, targetModules) {
8
10
  // 开始构建前,清理输出目录
9
11
  await shelljs.rm('-rf', resolve(tmsConfig.outputDir));
10
12
 
11
13
  const { modules: newModules } = await init(tmsConfig, targetModules);
14
+ info('当前build有效模块', newModules.map(item => item.moduleName).sort());
12
15
 
13
16
  const isDev = false;
14
17
  if (typeof tmsConfig?.hooks?.beforeFirstCompile === 'function') {
15
18
  await tmsConfig?.hooks?.beforeFirstCompile({
16
19
  isDev,
17
20
  tmsConfig: filterField(tmsConfig, ['gitAccount']),
18
- modules: newModules });
21
+ modules: newModules,
22
+ cmdOptions: global.getData('cmdOptions'),
23
+ });
19
24
  report('hooks:beforeCompile');
20
25
  };
21
26
  compileBuild(tmsConfig, newModules, isDev);
@@ -0,0 +1,34 @@
1
+ const fs = require('fs');
2
+
3
+ /**
4
+ * 检查云函数的配置项
5
+ * @param {*} tmsConfig
6
+ */
7
+ function checkCloudConfig(tmsConfig) {
8
+ if (!tmsConfig.cloudModules) {
9
+ return '你没有在tms.config.js的cloudModules注册云函数';
10
+ }
11
+ if (!tmsConfig.cloudDir) {
12
+ return '你没有在tms.config.js配置云函数编译目录cloudDir';
13
+ }
14
+ return;
15
+ }
16
+
17
+ /**
18
+ * 检查云函数源码目录是否存在
19
+ * @param {Array} clouds [{name: '', sourcePath: '', targetPath: ''}]
20
+ */
21
+ function checkSrcPathIsExist(clouds) {
22
+ for (const item of clouds) {
23
+ if (!fs.existsSync(item.sourcePath)) {
24
+ return `${item.name}云函数的${item.sourcePath}目录不存在, 请检查tms.config.js>cloudModules>all云函数的配置目录`;
25
+ }
26
+ }
27
+ return;
28
+ }
29
+
30
+
31
+ module.exports = {
32
+ checkCloudConfig,
33
+ checkSrcPathIsExist,
34
+ };
@@ -0,0 +1,146 @@
1
+ const shellJs = require('shelljs');
2
+ const ora = require('ora');
3
+ const path = require('path');
4
+ const chalk = require('chalk');
5
+ const { resolve, createTask } = require('../../../utils/widgets');
6
+ const { handleError } = require('../../../core/handleError');
7
+ const { ensureDirExist } = require('../../../utils/io');
8
+ const { src, dest, parallel, series } = require('gulp');
9
+ const watch = require('../../../compile/plugins/gulp-watch');
10
+ const { info, fail } = require('../../../utils/log');
11
+ const getCloudsOfListen = require('./getClouds');
12
+ const { checkCloudConfig, checkSrcPathIsExist } = require('./check');
13
+ const { runInstall } = require('./install');
14
+
15
+ /**
16
+ * 获取云函数的编译任务
17
+ * @param {array} clouds [{name: '', sourcePath: '', targetPath: ''}]
18
+ * @param {object} srcOption gulp.src的参数
19
+ * @returns Map {'${sourcePath}': {taskFn: () => {}, targetPath: 'xxx'}}
20
+ */
21
+ const getCompileTasks = (clouds, srcOption) => {
22
+ const compileTasksMap = new Map();
23
+ clouds.forEach((item) => {
24
+ compileTasksMap.set(item.sourcePath, {
25
+ targetPath: item.targetPath,
26
+ taskFn: (sourceFile, targetPath) => {
27
+ const newGlobValue = Array.isArray(sourceFile) ? sourceFile : `${item.sourcePath}/**/*`;
28
+ const newDestPath = targetPath ? targetPath : item.targetPath;
29
+
30
+ const srcPipe = src(newGlobValue, srcOption);
31
+ return srcPipe
32
+ .pipe(dest(newDestPath))
33
+ .on('error', (err) => {
34
+ fail(`监听报错${err}`);
35
+ });
36
+ },
37
+ });
38
+ });
39
+ return compileTasksMap;
40
+ };
41
+
42
+ const getTargetFile = (sourceFile, sourcePath, targetPath) => {
43
+ const sourceFileRelativeModule = path.relative(sourcePath, sourceFile);
44
+ const targetFile = resolve(targetPath, sourceFileRelativeModule);
45
+ return targetFile;
46
+ };
47
+
48
+ /**
49
+ * 开始启动编译
50
+ * @param {Map} compileTasksMap {'${sourcePath}': {taskFn: () => {}, targetPath: 'xxx'}}
51
+ */
52
+ const runCompile = (compileTasksMap, callback) => {
53
+ async function end(next) {
54
+ // 监听其他文件
55
+ compileTasksMap.forEach(({ taskFn, targetPath }, sourcePath) => {
56
+ runWatch(
57
+ sourcePath,
58
+ { ignoreInitial: true, events: ['add', 'change', 'unlink', 'addDir', 'unlinkDir'] },
59
+ taskFn,
60
+ targetPath,
61
+ );
62
+ });
63
+ callback && callback();
64
+ next();
65
+ }
66
+
67
+ const compileTasksArr = [];
68
+ compileTasksMap.forEach(({ taskFn }) => {
69
+ compileTasksArr.push(taskFn);
70
+ });
71
+ // 一次性完成编译任务(编译完成后再添加watch任务-封装到end函数里面)
72
+ series(parallel(...compileTasksArr), end)();
73
+ };
74
+
75
+ /**
76
+ * 监听文件变动
77
+ * @param {*} sourcePath 云函数的源码目录
78
+ * @param {*} watchOptions gulp-watch的参数
79
+ * @param {*} callback 监听到变动的回调
80
+ * @param {*} targetPath 云函数的编译目录
81
+ */
82
+ const runWatch = (sourcePath, watchOptions, callback, targetPath) => {
83
+ watch(sourcePath, {
84
+ ...watchOptions,
85
+ }, (vinyl) => {
86
+ const sourceFile = vinyl.history[0];
87
+ const sourceFileDirArr = sourceFile.replace(/\\/g, '/').split('/');
88
+ const sourceFileName = sourceFileDirArr.slice(sourceFileDirArr.length - 2).join('/');
89
+
90
+ const targetFile = getTargetFile(sourceFile, sourcePath, targetPath);
91
+ if (vinyl.event === 'unlink' || vinyl.event === 'unlinkDir') {
92
+ info(`删除${sourceFileName}`);
93
+ shellJs.rm('-rf', targetFile);
94
+ return;
95
+ }
96
+ info(`${sourceFileName}有更新`);
97
+ return callback([sourceFile], path.dirname(targetFile));
98
+ });
99
+ };
100
+
101
+
102
+ module.exports = async (tmsConfig, cmdOptions) => {
103
+ try {
104
+ const sTime = new Date().getTime();
105
+ const spinner = ora();
106
+ spinner.start();
107
+
108
+ // 检查云函数的配置项
109
+ const configErrMsg = checkCloudConfig(tmsConfig);
110
+ if (configErrMsg) {
111
+ throw new Error(configErrMsg);
112
+ }
113
+
114
+ // 确保云函数的编译目录存在
115
+ ensureDirExist(resolve(tmsConfig.cloudDir));
116
+
117
+ // 获取需要监听的云函数列表
118
+ const clouds = getCloudsOfListen(tmsConfig, cmdOptions);
119
+ // 检查云函数源码目录是否存在
120
+ const srcNotExistErrMsg = checkSrcPathIsExist(clouds);
121
+ if (srcNotExistErrMsg) {
122
+ throw new Error(srcNotExistErrMsg);
123
+ }
124
+
125
+ // 打印启动云函数列表
126
+ info('当前启动云函数列表:', clouds.map(item => item.name).sort());
127
+
128
+ // npm install
129
+ await createTask(
130
+ runInstall,
131
+ '开始npm install',
132
+ 'npm install完成',
133
+ )(clouds, tmsConfig);
134
+
135
+ // 获取云函数列表的编译任务
136
+ const compileTasksMap = getCompileTasks(clouds, { allowEmpty: true });
137
+ runCompile(compileTasksMap, () => {
138
+ const eTime = new Date().getTime() - sTime;
139
+ spinner.succeed(chalk.green(`首次编译完成, 耗时${eTime / 1000}s, 微信开发者工具打开项目即可预览。`));
140
+ spinner.stop();
141
+ });
142
+ } catch (e) {
143
+ info('编译出现详细错误', e);
144
+ handleError(`编译出现错误: ${e}`, true);
145
+ }
146
+ };