@tmsfe/tmskit 0.0.5 → 0.0.8

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 (53) hide show
  1. package/README.md +18 -2
  2. package/dist/index.cjs.js +2286 -1258
  3. package/package.json +24 -8
  4. package/src/compile/build.js +5 -0
  5. package/src/compile/compile.js +90 -0
  6. package/src/compile/dev.js +129 -0
  7. package/src/compile/plugins/less.js +116 -0
  8. package/src/compile/plugins/mpCommonDep.js +131 -0
  9. package/src/compile/plugins/mpJsonDep.js +112 -0
  10. package/src/compile/plugins/mpWxmlDep.js +194 -0
  11. package/src/compile/plugins/postcss-font-base64.js +72 -0
  12. package/src/compile/plugins/replaceEnv.js +29 -0
  13. package/src/compile/plugins/utils/pluginError.js +25 -0
  14. package/src/config/constant.js +11 -10
  15. package/src/config/defaultTmsConfig.js +9 -10
  16. package/src/core/buildAppJson.js +166 -0
  17. package/src/{utils → core}/checkDependencies.js +6 -6
  18. package/src/core/cloneModules.js +203 -0
  19. package/src/core/handleError.js +18 -0
  20. package/src/core/isInIt.js +69 -0
  21. package/src/{utils/mpCiUtils.js → core/mpCi.js} +0 -1
  22. package/src/core/npm.js +218 -0
  23. package/src/core/symbolicLink.js +24 -0
  24. package/src/core/tmsMpconfig.js +234 -0
  25. package/src/entry.js +50 -8
  26. package/src/index.js +31 -15
  27. package/src/init.js +2 -7
  28. package/src/scripts/create/index.js +2 -2
  29. package/src/scripts/run/build/index.js +3 -3
  30. package/src/scripts/run/dev/index.js +27 -52
  31. package/src/scripts/run/index.js +70 -36
  32. package/src/scripts/run/init/index.js +40 -42
  33. package/src/scripts/run/install/index.js +21 -29
  34. package/src/utils/findCssImport.js +30 -0
  35. package/src/utils/global.js +19 -33
  36. package/src/utils/io.js +86 -0
  37. package/src/utils/log.js +3 -0
  38. package/src/utils/widgets.js +59 -51
  39. package/CHANGELOG.md +0 -0
  40. package/main.js +0 -3
  41. package/rollup.config.js +0 -179
  42. package/src/utils/buildAppJson.js +0 -144
  43. package/src/utils/cliUtils.js +0 -35
  44. package/src/utils/cloneModules.js +0 -90
  45. package/src/utils/npmUtils.js +0 -126
  46. package/src/utils/tkitUtils.js +0 -84
  47. package/src/webpack/base.js +0 -65
  48. package/src/webpack/build.js +0 -21
  49. package/src/webpack/buildServer.js +0 -34
  50. package/src/webpack/dev.js +0 -31
  51. package/src/webpack/devServer.js +0 -37
  52. package/src/webpack/plugins/entryExtractPlugin/index.js +0 -28
  53. package/src/webpack/utils.js +0 -244
package/dist/index.cjs.js CHANGED
@@ -1,50 +1,58 @@
1
1
  'use strict';
2
2
 
3
- var require$$0 = require('commander');
3
+ var require$$0 = require('chalk');
4
+ var require$$0$1 = require('commander');
4
5
  var require$$1 = require('leven');
5
6
  var require$$2 = require('ora');
6
- var require$$1$1 = require('path');
7
- var require$$0$1 = require('fs');
8
- var require$$0$2 = require('shelljs');
9
- var require$$6$1 = require('download-git-repo');
10
- var require$$0$3 = require('chalk');
7
+ var require$$3 = require('path');
8
+ var require$$0$2 = require('fs');
9
+ var require$$0$3 = require('shelljs');
11
10
  var require$$0$4 = require('async');
12
- var require$$1$2 = require('ejs');
13
- var require$$1$3 = require('inquirer');
11
+ var require$$1$1 = require('ejs');
12
+ var require$$1$2 = require('inquirer');
14
13
  var require$$0$5 = require('metalsmith');
15
- var require$$0$6 = require('miniprogram-ci');
16
- var require$$0$7 = require('lodash');
17
- var require$$7 = require('replace-ext');
18
- var require$$0$8 = require('webpack-chain');
19
- var require$$0$9 = require('webpack');
20
- var require$$0$a = require('webpack/lib/SingleEntryPlugin');
21
- var require$$3$1 = require('copy-webpack-plugin');
22
- var require$$1$4 = require('semver');
23
- var require$$3$2 = require('glob-ignore');
14
+ var require$$0$6 = require('lodash');
15
+ var require$$1$3 = require('crypto');
16
+ var require$$0$7 = require('miniprogram-ci');
17
+ var require$$5 = require('glob-ignore');
18
+ var require$$1$4 = require('fs-extra');
19
+ var require$$9 = require('console');
20
+ var require$$0$8 = require('strip-comments');
21
+ var require$$0$9 = require('through2');
22
+ var require$$1$5 = require('precinct');
23
+ var require$$1$6 = require('htmlparser2');
24
+ var require$$0$a = require('gulp');
25
+ var require$$1$7 = require('gulp-px-to-rpx');
26
+ var require$$2$1 = require('gulp-watch');
27
+ var require$$1$8 = require('semver');
24
28
 
25
29
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
26
30
 
27
31
  var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
32
+ var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
28
33
  var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
29
34
  var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
30
- var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
31
- var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
35
+ var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
32
36
  var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
33
- var require$$6__default = /*#__PURE__*/_interopDefaultLegacy(require$$6$1);
34
37
  var require$$0__default$3 = /*#__PURE__*/_interopDefaultLegacy(require$$0$3);
35
38
  var require$$0__default$4 = /*#__PURE__*/_interopDefaultLegacy(require$$0$4);
39
+ var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
36
40
  var require$$1__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$1$2);
37
- var require$$1__default$3 = /*#__PURE__*/_interopDefaultLegacy(require$$1$3);
38
41
  var require$$0__default$5 = /*#__PURE__*/_interopDefaultLegacy(require$$0$5);
39
42
  var require$$0__default$6 = /*#__PURE__*/_interopDefaultLegacy(require$$0$6);
43
+ var require$$1__default$3 = /*#__PURE__*/_interopDefaultLegacy(require$$1$3);
40
44
  var require$$0__default$7 = /*#__PURE__*/_interopDefaultLegacy(require$$0$7);
41
- var require$$7__default = /*#__PURE__*/_interopDefaultLegacy(require$$7);
45
+ var require$$5__default = /*#__PURE__*/_interopDefaultLegacy(require$$5);
46
+ var require$$1__default$4 = /*#__PURE__*/_interopDefaultLegacy(require$$1$4);
47
+ var require$$9__default = /*#__PURE__*/_interopDefaultLegacy(require$$9);
42
48
  var require$$0__default$8 = /*#__PURE__*/_interopDefaultLegacy(require$$0$8);
43
49
  var require$$0__default$9 = /*#__PURE__*/_interopDefaultLegacy(require$$0$9);
50
+ var require$$1__default$5 = /*#__PURE__*/_interopDefaultLegacy(require$$1$5);
51
+ var require$$1__default$6 = /*#__PURE__*/_interopDefaultLegacy(require$$1$6);
44
52
  var require$$0__default$a = /*#__PURE__*/_interopDefaultLegacy(require$$0$a);
45
- var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3$1);
46
- var require$$1__default$4 = /*#__PURE__*/_interopDefaultLegacy(require$$1$4);
47
- var require$$3__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$3$2);
53
+ var require$$1__default$7 = /*#__PURE__*/_interopDefaultLegacy(require$$1$7);
54
+ var require$$2__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$2$1);
55
+ var require$$1__default$8 = /*#__PURE__*/_interopDefaultLegacy(require$$1$8);
48
56
 
49
57
  function getAugmentedNamespace(n) {
50
58
  if (n.__esModule) return n;
@@ -61,38 +69,88 @@ function getAugmentedNamespace(n) {
61
69
  return a;
62
70
  }
63
71
 
64
- var src$1 = {};
72
+ var src$2 = {};
73
+
74
+ const chalk$3 = require$$0__default;
75
+ /**
76
+ * 本文件提供无依赖的在终端打印彩色文字的方法。
77
+ */
78
+
79
+ const resetCfg = decodeURIComponent('%1B%5B0m'); // \033[0m转义后的字符按,用来还原属性
80
+
81
+ /**
82
+ * 打印红底黑字格式的文字
83
+ * @param {String} message 需要打印的文字信息
84
+ * @returns {undefined} 无
85
+ */
86
+
87
+ const fail$9 = (message = '') => {
88
+ const redStyleConfig = decodeURIComponent('%1B%5B41%3B30m'); // \033[41;30m转义后的字符按,console时输出红色文字
89
+
90
+ const greenFontStyleConfig = decodeURIComponent('%1B%5B41%3B37m'); // \033[41;30m转义后的字符按,console时输出红底白色文字
91
+
92
+ console.log(`${redStyleConfig} ERROR ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
93
+ };
94
+ /**
95
+ * 打印绿底黑字格式的文字
96
+ * @param {String} message 需要打印的文字信息
97
+ * @returns {undefined} 无
98
+ */
99
+
100
+
101
+ const succeed$1 = (message = '') => {
102
+ const greenStyleConfig = decodeURIComponent('%1B%5B42%3B30m'); // \033[42;30m转义后的字符按,console时输出绿色文字
103
+
104
+ const greenFontStyleConfig = decodeURIComponent('%1B%5B40%3B32m'); // \033[40;32m转义后的字符按,console时输出绿色文字
105
+
106
+ console.log(`${greenStyleConfig} Success ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
107
+ };
108
+ /**
109
+ * 打印warn提示
110
+ * @param {String} message 需要打印的文字信息
111
+ * @returns {undefined} 无
112
+ */
113
+
114
+
115
+ const warn = message => {
116
+ console.log(chalk$3.yellow(message));
117
+ };
118
+
119
+ const info$9 = (...args) => console.log(...args);
120
+
121
+ var log$1 = {
122
+ fail: fail$9,
123
+ succeed: succeed$1,
124
+ warn,
125
+ info: info$9
126
+ };
65
127
 
66
- const program$1 = require$$0__default;
128
+ const program$1 = require$$0__default$1;
67
129
  const leven = require$$1__default;
68
130
  const ora = require$$2__default;
69
- const path$7 = require$$1__default$1;
70
- const fs$b = require$$0__default$1;
71
- const shelljs$6 = require$$0__default$2;
72
- const download = require$$6__default;
73
- const chalk$3 = require$$0__default$3;
74
- const shelljsOptons = {
75
- slient: true
131
+ const path$a = require$$3__default;
132
+ const fs$e = require$$0__default$2;
133
+ const shelljs$6 = require$$0__default$3;
134
+ const {
135
+ info: info$8
136
+ } = log$1;
137
+ const chalk$2 = require$$0__default;
138
+ const shelljsOptions = {
139
+ slient: true,
140
+ async: false
76
141
  }; // 获取当前目录
77
142
 
78
143
  const cwd = process.cwd();
79
144
 
80
- function resolve$c(...args) {
81
- return path$7.resolve(cwd, ...args);
145
+ function resolve$f(...args) {
146
+ return path$a.resolve(cwd, ...args);
82
147
  }
83
- /**
84
- * 封装logs
85
- * @returns {Undefined} 无需返回值
86
- */
87
-
88
- const log$3 = (...args) => console.log(...args);
89
148
  /**
90
149
  * 用户输入命令时,进行提示
91
150
  * @param {String} unknownCommand 非预期的命令
92
151
  * @returns {Undefined} 无需返回值
93
152
  */
94
153
 
95
-
96
154
  const suggestCommands$1 = unknownCommand => {
97
155
  const availableCommands = program$1.commands.map(cmd => cmd._name);
98
156
  let suggestion;
@@ -105,7 +163,7 @@ const suggestCommands$1 = unknownCommand => {
105
163
  });
106
164
 
107
165
  if (suggestion) {
108
- log$3(` ${chalk$3.red(`Did you mean ${chalk$3.yellow(suggestion)}?`)}`);
166
+ info$8(` ${chalk$2.red(`Did you mean ${chalk$2.yellow(suggestion)}?`)}`);
109
167
  }
110
168
  };
111
169
  /**
@@ -129,65 +187,80 @@ function isArray$1(obj) {
129
187
  return Object.prototype.toString.call(obj) === '[object Array]';
130
188
  }
131
189
  /**
132
- * 下载模块到目标目录
190
+ * 下载模块代码
191
+ * @param { string } url 模块地址
133
192
  * @param { string } dest 目标地址
134
- * @param { object } downloadOptions 模块下载配置 { repoUrl-仓库地址, gitUrl-git地址, branch-分支或者tag }
193
+ * @param { string } branch 分支名
135
194
  * @returns { undefined } no return
136
195
  */
137
196
 
138
197
 
139
- function downloadRepo(dest, downloadOptions = {
140
- repoUrl: '',
141
- gitUrl: '',
142
- branch: ''
143
- }) {
144
- const {
145
- repoUrl,
146
- gitUrl,
147
- branch
148
- } = downloadOptions;
149
-
150
- if (fs$b.existsSync(dest)) {
151
- shelljs$6.rm('-rf', dest);
152
- }
153
-
154
- shelljs$6.mkdir('-p', dest);
155
- return new Promise(resolve => {
156
- download(`${repoUrl}#${branch}`, dest, {
157
- clone: true
158
- }, async e => {
159
- if (e) {
160
- console.log(e); // eslint-disable-line
198
+ function downloadRepoForGit$2(url, dest, branch) {
199
+ const cwd = process.cwd();
200
+ return new Promise((resolve, reject) => {
201
+ // 如果目标目录不存在
202
+ if (fs$e.existsSync(dest)) {
203
+ shelljs$6.rm('-rf', path$a.join(dest));
204
+ }
161
205
 
162
- await downloadRepoForGit$2(gitUrl, dest, branch);
206
+ shelljs$6.mkdir('-p', dest);
207
+ shelljs$6.cd(dest);
208
+ shelljs$6.exec(`git clone ${url} ${dest} --branch ${branch} --depth 1`, {
209
+ silent: true
210
+ }, (code, stdout, stderr) => {
211
+ if (code !== 0) {
212
+ reject(stderr);
163
213
  }
164
214
 
215
+ shelljs$6.cd(cwd);
165
216
  resolve();
166
217
  });
167
218
  });
168
219
  }
169
220
  /**
170
- * 下载模块到目标目录备用方案
171
- * @param { string } url 模块地址
172
- * @param { string } dest 目标地址
221
+ * pull模块代码
222
+ * @param { string } dest 下载代码的路径
173
223
  * @param { string } branch 分支名
174
224
  * @returns { undefined } no return
175
225
  */
176
226
 
177
227
 
178
- function downloadRepoForGit$2(url, dest, branch) {
228
+ function pullRepoForGit$1(dest, branch) {
179
229
  const cwd = process.cwd();
180
- return new Promise(resolve => {
181
- // 如果目标目录不存在
182
- if (fs$b.existsSync(dest)) {
183
- shelljs$6.rm('-rf', path$7.join(dest));
184
- }
185
-
186
- shelljs$6.mkdir('-p', dest);
230
+ return new Promise((resolve, reject) => {
187
231
  shelljs$6.cd(dest);
188
- shelljs$6.exec(`git clone ${url} ${dest} --branch ${branch} --depth 1`, shelljsOptons);
189
- shelljs$6.cd(cwd);
190
- resolve();
232
+ shelljs$6.exec('git config pull.rebase false', shelljsOptions);
233
+ shelljs$6.exec(`git pull origin ${branch}`, {
234
+ silent: true
235
+ }, (code, stdout, stderr) => {
236
+ if (code !== 0) {
237
+ reject(stderr);
238
+ }
239
+
240
+ shelljs$6.cd(cwd);
241
+ resolve();
242
+ });
243
+ });
244
+ }
245
+ /**
246
+ * npm 下载依赖
247
+ * @param {*} dir
248
+ * @returns
249
+ */
250
+
251
+
252
+ function npmInstall$1(dir) {
253
+ return new Promise((resolve, reject) => {
254
+ shelljs$6.exec('npx yarn --production --registry http://mirrors.tencent.com/npm/', {
255
+ cwd: dir,
256
+ silent: true
257
+ }, (code, stdout, stderr) => {
258
+ if (code !== 0) {
259
+ reject(stderr);
260
+ }
261
+
262
+ resolve();
263
+ });
191
264
  });
192
265
  }
193
266
  /**
@@ -207,24 +280,15 @@ const cost = start => Date.now() - start;
207
280
  */
208
281
 
209
282
 
210
- function createTask$5(task, startText, endText) {
283
+ function createTask$3(task, startText, endText) {
211
284
  return async (...args) => {
212
285
  const start = Date.now();
213
- let result;
214
286
  const spinner = ora(startText);
215
287
  spinner.start();
216
-
217
- try {
218
- result = await task(...args);
219
- } catch (e) {
220
- result = e;
221
- console.log(chalk$3.red(e));
222
- process.exit(-1);
223
- } finally {
224
- endText && spinner.succeed(`${endText}, ${cost(start)}ms`);
225
- spinner.stop();
226
- }
227
-
288
+ info$8('\n');
289
+ const result = await task(...args);
290
+ endText && spinner.succeed(`${endText}, ${cost(start)}ms`);
291
+ spinner.stop();
228
292
  return result;
229
293
  };
230
294
  }
@@ -237,54 +301,54 @@ function createTask$5(task, startText, endText) {
237
301
  const camelize = str => str.replace(/-(\w)/g, (a, c) => c ? c.toUpperCase() : '');
238
302
 
239
303
  var widgets = {
240
- resolve: resolve$c,
241
- log: log$3,
304
+ resolve: resolve$f,
242
305
  isObject: isObject$2,
243
306
  isArray: isArray$1,
244
- createTask: createTask$5,
245
- downloadRepo,
307
+ createTask: createTask$3,
246
308
  downloadRepoForGit: downloadRepoForGit$2,
309
+ pullRepoForGit: pullRepoForGit$1,
247
310
  suggestCommands: suggestCommands$1,
248
- camelize
311
+ camelize,
312
+ npmInstall: npmInstall$1
249
313
  };
250
314
 
251
- const path$6 = require('path'); // 用户目录
315
+ const path$9 = require('path');
316
+
317
+ const os = require('os'); // 用户目录
252
318
 
253
319
 
254
- const HOME_DIR = process.env.HOME; // 所有文件的缓存目录
320
+ const HOME_DIR = os.homedir(); // 所有文件的缓存目录
255
321
 
256
- const CACHE_DIR$1 = path$6.resolve(HOME_DIR, '.tmskit'); // 脚手架模板代码所在目录
322
+ const CACHE_DIR$1 = path$9.resolve(HOME_DIR, '.tmskit'); // 脚手架模板代码所在目录
257
323
 
258
- const TEMPLATE_DIR$1 = path$6.resolve(CACHE_DIR$1, 'template'); // 第三方模块源码存放的临时缓存目录
324
+ const TEMPLATE_DIR$1 = path$9.resolve(CACHE_DIR$1, 'template'); // 第三方模块源码存放的临时缓存目录
259
325
 
260
- const MODULE_CODE_DIR$1 = path$6.resolve(CACHE_DIR$1, 'modules_code'); // 脚手架模板代码的具体路径
326
+ const MODULE_CODE_DIR$2 = path$9.resolve(CACHE_DIR$1, 'modules_code'); // 脚手架模板代码的具体路径
261
327
 
262
- const TEMPLATE_PATH$1 = path$6.resolve(TEMPLATE_DIR$1, 'tools/tms-cli-template'); // 脚手架的名称
328
+ const TEMPLATE_PATH$1 = path$9.resolve(TEMPLATE_DIR$1, 'tools/tms-cli-template'); // 脚手架的名称
263
329
 
264
330
  const TMS_NAME$2 = 'tmskit'; // 脚手架的配置名称
265
331
 
266
- const TMS_CONFIG_FILENAME$1 = 'tms.config.js'; // 模块代码的默认在modules子目录
332
+ const TMS_CONFIG_FILENAME$1 = 'tms.config.js';
333
+ const TMS_PRIVATE_FILENAME$1 = 'tms.private.config.js'; // 模块代码的默认在modules子目录
267
334
 
268
- const DEFAULT_MODULE_DIR$5 = 'modules'; // 模块的配置文件的名称
335
+ const DEFAULT_MODULE_DIR = 'modules'; // 模块代码的默认在modules子目录
269
336
 
270
- const MODULE_CONFIG_FILENAME$2 = 'module.config.json'; // 默认的webpack entry
337
+ const DEFAULT_CLOUD_MODULE_DIR$1 = './cloud'; // 模块的配置文件的名称
271
338
 
272
- const DEFAULT_WEBPACK_ENTRY$2 = {
273
- app: path$6.resolve(process.cwd(), 'app')
274
- }; // 默认从源码拷贝到编译后的配置
339
+ const MODULE_CONFIG_FILENAME$3 = 'module.config.json'; // 默认的webpack entry
275
340
 
276
- const DEFAULT_COPY_CONFIG$3 = ['package.json', 'app.js', 'app.ts', 'app.less', 'app.wxss', 'sitemap.json']; // 开发模式
341
+ const DEFAULT_WEBPACK_ENTRY = {
342
+ app: path$9.resolve(process.cwd(), 'app')
343
+ }; // 默认从源码拷贝到编译后的配置
277
344
 
278
- const MODE$1 = {
279
- main: 'tkitmain',
280
- all: 'all',
281
- multi: 'multi'
282
- };
345
+ const DEFAULT_COPY_CONFIG$1 = ['package.json', 'sitemap.json'];
283
346
  const ENV = {
284
347
  dev: 'development',
285
348
  prod: 'production'
286
349
  };
287
350
  const TEMPLATE_TKIT_DIR$2 = '_tmskit';
351
+ const MODULE_CONFIG_INVALID_KEY$1 = ['entranceDeclare', 'entryPagePath'];
288
352
 
289
353
  var constant = /*#__PURE__*/Object.freeze({
290
354
  __proto__: null,
@@ -294,26 +358,42 @@ var constant = /*#__PURE__*/Object.freeze({
294
358
  TEMPLATE_PATH: TEMPLATE_PATH$1,
295
359
  TMS_NAME: TMS_NAME$2,
296
360
  TMS_CONFIG_FILENAME: TMS_CONFIG_FILENAME$1,
297
- DEFAULT_MODULE_DIR: DEFAULT_MODULE_DIR$5,
298
- MODULE_CONFIG_FILENAME: MODULE_CONFIG_FILENAME$2,
299
- DEFAULT_WEBPACK_ENTRY: DEFAULT_WEBPACK_ENTRY$2,
300
- DEFAULT_COPY_CONFIG: DEFAULT_COPY_CONFIG$3,
301
- MODULE_CODE_DIR: MODULE_CODE_DIR$1,
302
- MODE: MODE$1,
361
+ TMS_PRIVATE_FILENAME: TMS_PRIVATE_FILENAME$1,
362
+ DEFAULT_MODULE_DIR: DEFAULT_MODULE_DIR,
363
+ MODULE_CONFIG_FILENAME: MODULE_CONFIG_FILENAME$3,
364
+ DEFAULT_WEBPACK_ENTRY: DEFAULT_WEBPACK_ENTRY,
365
+ DEFAULT_COPY_CONFIG: DEFAULT_COPY_CONFIG$1,
366
+ MODULE_CODE_DIR: MODULE_CODE_DIR$2,
303
367
  ENV: ENV,
304
- TEMPLATE_TKIT_DIR: TEMPLATE_TKIT_DIR$2
368
+ TEMPLATE_TKIT_DIR: TEMPLATE_TKIT_DIR$2,
369
+ MODULE_CONFIG_INVALID_KEY: MODULE_CONFIG_INVALID_KEY$1,
370
+ DEFAULT_CLOUD_MODULE_DIR: DEFAULT_CLOUD_MODULE_DIR$1
305
371
  });
306
372
 
307
- var require$$3 = /*@__PURE__*/getAugmentedNamespace(constant);
373
+ var require$$4 = /*@__PURE__*/getAugmentedNamespace(constant);
308
374
 
309
- const fs$a = require$$0__default$1;
375
+ const fs$d = require$$0__default$2;
376
+ const path$8 = require$$3__default;
377
+ const {
378
+ info: info$7
379
+ } = log$1;
310
380
  /**
311
381
  * 判断目录是否为空
312
382
  * @param {string} dirname 目录名
313
383
  * @returns
314
384
  */
315
385
 
316
- const isDirEmpty = dirname => fs$a.promises.readdir(dirname).then(files => files.length === 0);
386
+ const isDirEmpty = dirname => fs$d.promises.readdir(dirname).then(files => files.length === 0); // 判断是否是文件
387
+
388
+
389
+ const isFile = pathName => {
390
+ try {
391
+ const stat = fs$d.lstatSync(pathName);
392
+ return stat.isFile();
393
+ } catch {
394
+ return false;
395
+ }
396
+ };
317
397
  /**
318
398
  * 确保目录存在,不存在就创建一个
319
399
  * @param {*} dirname 目录名
@@ -321,71 +401,100 @@ const isDirEmpty = dirname => fs$a.promises.readdir(dirname).then(files => files
321
401
 
322
402
 
323
403
  const ensureDirExist = dirname => {
324
- if (!fs$a.existsSync(dirname)) {
325
- fs$a.mkdirSync(dirname, {
404
+ if (!fs$d.existsSync(dirname)) {
405
+ fs$d.mkdirSync(dirname, {
326
406
  recursive: true
327
407
  });
328
408
  }
329
- };
409
+ }; // 复制文件
330
410
 
331
- var io$2 = {
332
- isDirEmpty,
333
- ensureDirExist
334
- };
335
411
 
336
- const chalk$2 = require$$0__default$3;
337
- /**
338
- * 本文件提供无依赖的在终端打印彩色文字的方法。
339
- */
412
+ const copyFile = function (src, dest) {
413
+ if (fs$d.existsSync(dest)) {
414
+ fs$d.unlinkSync(dest);
415
+ }
340
416
 
341
- const resetCfg = decodeURIComponent('%1B%5B0m'); // \033[0m转义后的字符按,用来还原属性
417
+ const dir = path$8.dirname(dest);
418
+ ensureDirExist(dir);
419
+ fs$d.copyFileSync(src, dest);
420
+ }; // 判断文件内容是否一致,不一致再进行拷贝
342
421
 
343
- /**
344
- * 打印红底黑字格式的文字
345
- * @param {String} message 需要打印的文字信息
346
- * @returns {undefined} 无
347
- */
348
422
 
349
- const fail$a = (message = '') => {
350
- const redStyleConfig = decodeURIComponent('%1B%5B41%3B30m'); // \033[41;30m转义后的字符按,console时输出红色文字
423
+ function diffContentCopyFile$3(originFile, destFile) {
424
+ if (fs$d.existsSync(destFile)) {
425
+ const depDestContent = fs$d.readFileSync(destFile, 'utf8');
426
+ const depOriginContent = fs$d.readFileSync(originFile, 'utf8');
351
427
 
352
- const greenFontStyleConfig = decodeURIComponent('%1B%5B41%3B37m'); // \033[41;30m转义后的字符按,console时输出红底白色文字
428
+ if (depDestContent !== depOriginContent) {
429
+ info$7(`拷贝${originFile}内容到${destFile}`);
430
+ copyFile(originFile, destFile);
431
+ }
432
+ } else {
433
+ info$7(`拷贝${originFile}内容到${destFile}`);
434
+ copyFile(originFile, destFile);
435
+ }
436
+ } // 添加后缀
353
437
 
354
- console.log(`${redStyleConfig} ERROR ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
355
- };
356
- /**
357
- * 打印绿底黑字格式的文字
358
- * @param {String} message 需要打印的文字信息
359
- * @returns {undefined} 无
360
- */
361
438
 
439
+ function ext$3(filePath, extensions) {
440
+ let newFilePath = filePath;
441
+ let extPath = ''; // try catch需要包裹:用来处理'./lib/timer'没有后缀的情况
362
442
 
363
- const succeed$1 = (message = '') => {
364
- const greenStyleConfig = decodeURIComponent('%1B%5B42%3B30m'); // \033[42;30m转义后的字符按,console时输出绿色文字
443
+ try {
444
+ const stat = fs$d.lstatSync(newFilePath);
365
445
 
366
- const greenFontStyleConfig = decodeURIComponent('%1B%5B40%3B32m'); // \033[40;32m转义后的字符按,console时输出绿色文字
446
+ if (stat.isDirectory()) {
447
+ extPath = newFilePath[newFilePath.length - 1] === '/' ? 'index' : '/index';
448
+ newFilePath += extPath;
449
+ }
450
+ } catch (e) {}
367
451
 
368
- console.log(`${greenStyleConfig} Success ${greenFontStyleConfig} ${message}${resetCfg}`); // eslint-disable-line no-console
369
- };
370
- /**
371
- * 打印warn提示
372
- * @param {String} message 需要打印的文字信息
373
- * @returns {undefined} 无
374
- */
452
+ for (const ext of extensions) {
453
+ const file = newFilePath.endsWith(ext) ? newFilePath : newFilePath + ext;
375
454
 
455
+ if (fs$d.existsSync(file)) {
456
+ return {
457
+ ext,
458
+ extPath: extPath + ext,
459
+ file
460
+ };
461
+ }
462
+ }
376
463
 
377
- const warn = message => {
378
- console.log(chalk$2.yellow(message));
464
+ return {
465
+ ext: '',
466
+ extPath,
467
+ file: filePath
468
+ };
469
+ } // 判断文件是否在某个目录
470
+
471
+
472
+ const fileInDir$3 = (dir, file) => {
473
+ if (!fs$d.existsSync(dir) || !fs$d.existsSync(file)) {
474
+ return false;
475
+ }
476
+
477
+ const relativePath = path$8.relative(dir, file);
478
+
479
+ if (relativePath.startsWith('..')) {
480
+ return false;
481
+ }
482
+
483
+ return true;
379
484
  };
380
485
 
381
- var log$2 = {
382
- fail: fail$a,
383
- succeed: succeed$1,
384
- warn
486
+ var io$2 = {
487
+ isDirEmpty,
488
+ copyFile,
489
+ diffContentCopyFile: diffContentCopyFile$3,
490
+ ensureDirExist,
491
+ ext: ext$3,
492
+ fileInDir: fileInDir$3,
493
+ isFile
385
494
  };
386
495
 
387
496
  const async = require$$0__default$4;
388
- const ejs = require$$1__default$2;
497
+ const ejs = require$$1__default$1;
389
498
 
390
499
  const render$1 = (files, metalsmith, next) => {
391
500
  const keys = Object.keys(files);
@@ -404,14 +513,14 @@ const render$1 = (files, metalsmith, next) => {
404
513
 
405
514
  var render_1 = render$1;
406
515
 
407
- const fs$9 = require$$0__default$1;
408
- const inquirer = require$$1__default$3;
516
+ const fs$c = require$$0__default$2;
517
+ const inquirer = require$$1__default$2;
409
518
  const {
410
- resolve: resolve$b
519
+ resolve: resolve$e
411
520
  } = widgets;
412
521
  const {
413
522
  TEMPLATE_TKIT_DIR: TEMPLATE_TKIT_DIR$1
414
- } = require$$3;
523
+ } = require$$4;
415
524
  /**
416
525
  * 获取模板内的问题
417
526
  * @param {string} dir questions.json所在的目录
@@ -421,12 +530,12 @@ const {
421
530
  const parseTemplateQuestions = dir => {
422
531
  let prompts = [];
423
532
 
424
- if (!fs$9.existsSync(`${dir}/questions.json`)) {
533
+ if (!fs$c.existsSync(`${dir}/questions.json`)) {
425
534
  return prompts;
426
535
  }
427
536
 
428
537
  try {
429
- const json = JSON.parse(fs$9.readFileSync(`${dir}/questions.json`));
538
+ const json = JSON.parse(fs$c.readFileSync(`${dir}/questions.json`));
430
539
 
431
540
  if (Array.isArray(json) && json.length > 0) {
432
541
  json.forEach((item, index) => {
@@ -459,7 +568,7 @@ const isQuestionType = result => {
459
568
  };
460
569
 
461
570
  const ask$1 = templateDir => (files, metalsmith, next) => {
462
- const prompts = parseTemplateQuestions(resolve$b(templateDir, TEMPLATE_TKIT_DIR$1));
571
+ const prompts = parseTemplateQuestions(resolve$e(templateDir, TEMPLATE_TKIT_DIR$1));
463
572
  const metadata = metalsmith.metadata();
464
573
  const filteredPrompts = prompts.filter(prompt => {
465
574
  if (metadata[prompt.name] && `${metadata[prompt.name]}`.trim() !== '') {
@@ -501,24 +610,25 @@ const generator$1 = (buildDir, distDir, preMetadata) => new Promise((resolve, re
501
610
 
502
611
  var generator_1 = generator$1;
503
612
 
504
- const path$5 = require$$1__default$1;
505
- const fs$8 = require$$0__default$1;
506
- const shelljs$5 = require$$0__default$2;
613
+ const path$7 = require$$3__default;
614
+ const fs$b = require$$0__default$2;
615
+ const shelljs$5 = require$$0__default$3;
507
616
  const {
508
617
  TEMPLATE_DIR,
509
618
  TEMPLATE_PATH,
510
619
  TEMPLATE_TKIT_DIR
511
- } = require$$3;
620
+ } = require$$4;
512
621
  const {
513
622
  downloadRepoForGit: downloadRepoForGit$1,
514
- createTask: createTask$4,
515
- resolve: resolve$a
623
+ createTask: createTask$2,
624
+ resolve: resolve$d
516
625
  } = widgets;
517
626
  const io$1 = io$2;
518
627
  const {
519
- fail: fail$9,
520
- succeed
521
- } = log$2;
628
+ fail: fail$8,
629
+ succeed,
630
+ info: info$6
631
+ } = log$1;
522
632
  const generator = generator_1;
523
633
  /**
524
634
  * 如果该目录下面存在文件,换个名字
@@ -528,9 +638,9 @@ const generator = generator_1;
528
638
 
529
639
  async function createAppDir(targetDir) {
530
640
  // 如果目录非空或者已经存在,提示用户,做选择
531
- if (fs$8.existsSync(targetDir)) {
641
+ if (fs$b.existsSync(targetDir)) {
532
642
  if (!(await io$1.isDirEmpty(targetDir))) {
533
- fail$9('该目录名已经存在,换个项目名字吧~');
643
+ fail$8('该目录名已经存在,换个项目名字吧~');
534
644
  process.exit(1);
535
645
  }
536
646
  } else {
@@ -546,21 +656,21 @@ async function createAppDir(targetDir) {
546
656
 
547
657
  async function create(appName) {
548
658
  const cwd = process.cwd();
549
- const targetDir = path$5.resolve(cwd, appName);
659
+ const targetDir = path$7.resolve(cwd, appName);
550
660
  const appType = 'mp';
551
661
  await createAppDir(targetDir); // 创建缓存目录
552
662
 
553
663
  io$1.ensureDirExist(TEMPLATE_DIR); // 拉取git模板
554
664
 
555
- await createTask$4(downloadRepoForGit$1, '拉取模板仓库', '拉取模板仓库完成')('https://git.woa.com/tmsfe/tms-frontend.git', TEMPLATE_DIR, 'master'); // 生成模板(1. 询问问题, 2. ejs生成模板 3.生成到目标目录)
665
+ await createTask$2(downloadRepoForGit$1, '拉取模板仓库', '拉取模板仓库完成')('https://git.woa.com/tmsfe/tms-frontend.git', TEMPLATE_DIR, 'master'); // 生成模板(1. 询问问题, 2. ejs生成模板 3.生成到目标目录)
556
666
 
557
- generator(path$5.join(TEMPLATE_PATH, appType), targetDir, {
667
+ generator(path$7.join(TEMPLATE_PATH, appType), targetDir, {
558
668
  appName,
559
669
  appType
560
670
  }).then(() => {
561
671
  shelljs$5.cd(appName);
562
672
 
563
- const hooks = require(resolve$a(appName, TEMPLATE_TKIT_DIR, 'hooks.js'));
673
+ const hooks = require(resolve$d(appName, TEMPLATE_TKIT_DIR, 'hooks.js'));
564
674
 
565
675
  if (hooks.afterCreate) {
566
676
  hooks.afterCreate.forEach(item => {
@@ -574,103 +684,398 @@ async function create(appName) {
574
684
  });
575
685
  }
576
686
 
577
- shelljs$5.rm('-rf', resolve$a(appName, TEMPLATE_TKIT_DIR));
687
+ shelljs$5.rm('-rf', resolve$d(appName, TEMPLATE_TKIT_DIR));
578
688
  succeed('项目创建完成.');
579
689
  }).catch(err => {
580
- fail$9(err.message);
581
- console.log('详细的错误信息:', err);
690
+ fail$8(err.message);
691
+ info$6('详细的错误信息:', err);
582
692
  });
583
693
  }
584
694
 
585
695
  var create_1 = create;
586
696
 
587
- const fs$7 = require$$0__default$1;
588
- const {
589
- DEFAULT_MODULE_DIR: DEFAULT_MODULE_DIR$4,
590
- MODULE_CONFIG_FILENAME: MODULE_CONFIG_FILENAME$1
591
- } = require$$3;
697
+ var defaultTmsConfig$1 = {
698
+ // 全局的环境配置项
699
+ envData: {},
700
+ // 模块配置信息
701
+ modules: [],
702
+ cloudDir: 'cloud',
703
+ // 第三方依赖代码需要拷贝到本项目的
704
+ dependencies: {},
705
+
706
+ /** 编译输出文件夹位置 */
707
+ outputDir: 'dist',
708
+
709
+ /** 源码监听路径 */
710
+ sourceDir: './',
711
+
712
+ /** 静态资源目录 */
713
+ static: []
714
+ };
715
+
716
+ /**
717
+ * 用来读取处理tms.config.js与module.config.json字段
718
+ */
719
+ const loadash = require$$0__default$6;
720
+ const fs$a = require$$0__default$2;
592
721
  const {
593
- fail: fail$8
594
- } = log$2;
722
+ TMS_NAME: TMS_NAME$1,
723
+ TMS_CONFIG_FILENAME,
724
+ MODULE_CONFIG_FILENAME: MODULE_CONFIG_FILENAME$2,
725
+ TMS_PRIVATE_FILENAME
726
+ } = require$$4;
595
727
  const {
596
- resolve: resolve$9,
728
+ resolve: resolve$c,
597
729
  isObject: isObject$1,
598
730
  isArray
599
731
  } = widgets;
732
+ const defaultTmsConfig = defaultTmsConfig$1;
733
+ const {
734
+ fail: fail$7
735
+ } = log$1;
736
+ const path$6 = require$$3__default;
600
737
  /**
601
- * 获取每个模块下面的信息,并且收集,后续更新到appJson里面
602
- * @param { object } file 操作目录下面所有的文件
603
- * @param { string } appName 小程序的名称
738
+ * 读取tms.config.js
739
+ * @param env {string} 环境变量
604
740
  */
605
741
 
606
- function setModuleConfig$1(file, appName, moduleDir) {
607
- const content = file.contents ? JSON.parse(file.contents.toString()) : JSON.parse(file);
742
+ const readTmsConfig$1 = function (env) {
743
+ const tmsConfigPath = resolve$c(TMS_CONFIG_FILENAME);
608
744
 
609
- if (isObject$1(content)) {
610
- content.root = content.root.indexOf(moduleDir) > -1 ? content.root : `${moduleDir}/${content.root}`;
745
+ if (!fs$a.existsSync(tmsConfigPath)) {
746
+ fail$7('当前执行目录没有tms.config.js的配置项,请进行配置');
747
+ process.exit(1);
611
748
  }
612
749
 
613
- if (isArray(content)) {
614
- let i = content.length - 1;
615
-
616
- while (i >= 0) {
617
- let current = content[i];
618
- current.root = current.root.indexOf(moduleDir) > -1 ? current.root : `${moduleDir}/${current.root}`;
750
+ const tmsConfigFn = require(tmsConfigPath);
619
751
 
620
- if (appName && current.mpConfig && current.mpConfig[appName]) {
621
- current = { ...current,
622
- ...current.mpConfig[appName]
623
- };
624
- }
752
+ const tmsConfig = tmsConfigFn({
753
+ env
754
+ }); // 合并默认值
625
755
 
626
- delete current.mpConfig;
627
- delete current.isSubpackages;
628
- content[i] = current;
629
- i--; // eslint-disable-line
630
- }
631
- }
756
+ loadash.mergeWith(tmsConfig, defaultTmsConfig); // modules兼容处理
632
757
 
633
- return content;
634
- }
635
- /**
636
- * 递归获取本地所有模块的配置信息
637
- */
758
+ tmsConfig.modules = convertModules(tmsConfig.modules);
759
+ return tmsConfig;
760
+ }; // convertModules 处理默认值
638
761
 
639
762
 
640
- function getLocalModuleConfig(modules = [], appName, moduleDir, moduleConfigFilename) {
641
- const modulesConfig = {};
642
- modules.forEach(({
643
- path
644
- }) => {
645
- const moduleConfigPath = resolve$9(path, moduleConfigFilename);
763
+ const convertModules = modules => {
764
+ const newModules = [];
765
+ modules.forEach(module => {
766
+ const newModule = {};
767
+
768
+ if (typeof module === 'string') {
769
+ // 路径字符串
770
+ Object.assign(newModule, {
771
+ name: path$6.basename(module),
772
+ path: module
773
+ });
774
+ } else if (typeof module === 'object') {
775
+ Object.assign(newModule, module);
646
776
 
647
- if (fs$7.existsSync(moduleConfigPath)) {
648
- const content = fs$7.readFileSync(moduleConfigPath, 'utf-8');
649
- modulesConfig[moduleConfigPath] = setModuleConfig$1(content, appName, moduleDir);
777
+ if (module.name === undefined) {
778
+ newModule.name = path$6.basename(module.path);
779
+ }
650
780
  }
781
+
782
+ newModules.push(newModule);
651
783
  });
652
- return modulesConfig;
653
- }
784
+ return newModules;
785
+ };
654
786
  /**
655
- * 更新appJson里面的首页配置
656
- * @param { object } appJson appJson信息
657
- * @param { array } mainPackages 小程序主包信息
658
- * @returns { object } appJson小程序主页配置信息
787
+ * 读取tms.private.config.js
659
788
  */
660
789
 
661
790
 
662
- function updateMainPackages(appJson, mainPackages = []) {
663
- let foundMainPackages = appJson.subpackages.filter(subpackage => mainPackages.includes(subpackage.name));
791
+ const readTmsPrivateCf$1 = function () {
792
+ let tmsPrivateCf = {};
793
+ const tmsPrivatePath = resolve$c(TMS_PRIVATE_FILENAME);
664
794
 
665
- if (foundMainPackages.length === 0) {
666
- // 没找到主包
667
- foundMainPackages = [appJson.subpackages[0]];
668
- } // 拼装 app.pages
795
+ if (fs$a.existsSync(tmsPrivatePath)) {
796
+ tmsPrivateCf = require(tmsPrivatePath);
797
+ } // 处理modules字段
669
798
 
670
799
 
671
- foundMainPackages.forEach(subpackage => {
800
+ if (tmsPrivateCf.modules instanceof Array) {
801
+ Object.assign(tmsPrivateCf.modules, {
802
+ include: tmsPrivateCf.modules
803
+ });
804
+ }
805
+
806
+ return tmsPrivateCf;
807
+ };
808
+ /**
809
+ * 从tms.config.json中检索用户传入的有效modules
810
+ * @param { object } tmsConfig
811
+ * @param { array } modules
812
+ * @returns
813
+ */
814
+
815
+
816
+ const checkModules$1 = function (tmsConfig, modules) {
817
+ const targetModules = [];
818
+ modules.forEach(moduleName => {
819
+ const module = tmsConfig.modules.find(module => module.name === moduleName);
820
+ module && targetModules.push(module);
821
+ });
822
+
823
+ if (targetModules.length === 0) {
824
+ fail$7(`你启动的模块无效,尝试 ${TMS_NAME$1} -m moduleName`);
825
+ process.exit(1);
826
+ }
827
+
828
+ return targetModules;
829
+ };
830
+ /**
831
+ * 过滤页面为空的分包
832
+ * @param {Array} moduleCfg 模块配置内容
833
+ * @returns pages不为空的分包
834
+ */
835
+
836
+
837
+ const getValidModules$1 = moduleCfg => {
838
+ // 过滤 pages 为空的情况
839
+ const validModules = moduleCfg.filter(item => item.pages.length > 0);
840
+ return validModules;
841
+ };
842
+ /**
843
+ * 适配处理module.config.json的字段
844
+ * @param { object } fileContent module.config.json的内容
845
+ * @param { string } appName 小程序的名称
846
+ */
847
+
848
+
849
+ function adaptMpCgContent(fileContent, appName) {
850
+ const content = fileContent.contents ? JSON.parse(fileContent.contents.toString()) : JSON.parse(fileContent);
851
+
852
+ if (isArray(content)) {
853
+ let i = content.length - 1;
854
+
855
+ while (i >= 0) {
856
+ let current = content[i];
857
+
858
+ if (appName && current.mpConfig && current.mpConfig[appName]) {
859
+ current = { ...current,
860
+ ...current.mpConfig[appName]
861
+ };
862
+ }
863
+
864
+ delete current.mpConfig;
865
+ delete current.isSubpackages;
866
+ content[i] = current;
867
+ i--; // eslint-disable-line
868
+ }
869
+ }
870
+
871
+ return content;
872
+ }
873
+ /**
874
+ * 递归获取本地所有模块的配置信息
875
+ * @param {array} modules 用户要编译的模块列表
876
+ * @param { string } appName 小程序的名称
877
+ * @param { string } moduleConfigFilename moduleConfig的文件名
878
+ */
879
+
880
+
881
+ function getModuleConfig$1(modules = [], appName, moduleConfigFilename) {
882
+ const modulesConfig = {};
883
+ modules.forEach(({
884
+ path
885
+ }) => {
886
+ const moduleConfigPath = resolve$c(path, moduleConfigFilename);
887
+
888
+ if (fs$a.existsSync(moduleConfigPath)) {
889
+ const content = fs$a.readFileSync(moduleConfigPath, 'utf-8');
890
+ modulesConfig[moduleConfigPath] = adaptMpCgContent(content, appName);
891
+ }
892
+ });
893
+ return modulesConfig;
894
+ }
895
+ /**
896
+ * tms.config.js的modules 合并 module.config.json的配置项
897
+ * @param {array} modules
898
+ * @param {string} appName
899
+ * @param {string} moduleDir
900
+ * @returns
901
+ */
902
+
903
+
904
+ const tmsModulesMergeLocalModuleCfg$3 = (modules, appName) => {
905
+ const newModules = [];
906
+ modules.forEach(({
907
+ path: relativePath,
908
+ name: moduleName
909
+ }, moduleIndex) => {
910
+ const moduleConfigPath = resolve$c(relativePath, MODULE_CONFIG_FILENAME$2);
911
+
912
+ if (fs$a.existsSync(moduleConfigPath)) {
913
+ try {
914
+ let findModule = false;
915
+ let moduleConfigContent = fs$a.readFileSync(moduleConfigPath, 'utf-8');
916
+ moduleConfigContent = adaptMpCgContent(moduleConfigContent, appName);
917
+ const moduleContentArr = isObject$1(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
918
+ getValidModules$1(moduleContentArr).forEach(({
919
+ name
920
+ }, moduleContentArrIndex) => {
921
+ if (name === moduleName) {
922
+ findModule = true;
923
+ newModules.push({ ...modules[moduleIndex],
924
+ ...moduleContentArr[moduleContentArrIndex]
925
+ });
926
+ }
927
+ });
928
+
929
+ if (!findModule) {
930
+ fail$7(`启动模块${moduleName}在${moduleConfigPath}没有找到,请检查配置`);
931
+ process.exit(1);
932
+ }
933
+ } catch (e) {
934
+ fail$7(`${moduleConfigPath}配置错误: ${e}`);
935
+ newModules.push({ ...modules[moduleIndex]
936
+ });
937
+ }
938
+ } else {
939
+ newModules.push({ ...modules[moduleIndex]
940
+ });
941
+ }
942
+ });
943
+ return newModules;
944
+ };
945
+ /**
946
+ * 分包依赖了分包的模块 合并所依赖的modules
947
+ * @param { object } tmsConfig
948
+ * @param {array} modules
949
+ * @param {string} moduleDir
950
+ * @returns
951
+ */
952
+
953
+
954
+ const subModulesMergeDepModules$2 = (tmsConfig, modules) => {
955
+ const moduleNames = [];
956
+ modules.forEach(({
957
+ name: moduleName
958
+ }) => {
959
+ moduleNames.push(moduleName);
960
+ });
961
+ let mergeModules = modules;
962
+ let isOver = true;
963
+ modules.forEach(({
964
+ dependencies: dependencyModules
965
+ }) => {
966
+ dependencyModules === null || dependencyModules === void 0 ? void 0 : dependencyModules.forEach(item => {
967
+ // 如果所有模块的dep都在moduleNames内,则所有依赖都齐了
968
+ // 否则递归处理,根据name找到相关配置加到modules里
969
+ if (moduleNames.indexOf(item) === -1) {
970
+ isOver = false;
971
+ const tmpModules = checkModules$1(tmsConfig, [...new Set([item])]);
972
+ mergeModules = [...mergeModules, ...tmpModules];
973
+ mergeModules = tmsModulesMergeLocalModuleCfg$3(mergeModules, tmsConfig.appName);
974
+ }
975
+ });
976
+ });
977
+ return isOver ? mergeModules : subModulesMergeDepModules$2(tmsConfig, mergeModules);
978
+ };
979
+
980
+ var tmsMpconfig = {
981
+ readTmsConfig: readTmsConfig$1,
982
+ readTmsPrivateCf: readTmsPrivateCf$1,
983
+ getModuleConfig: getModuleConfig$1,
984
+ getValidModules: getValidModules$1,
985
+ checkModules: checkModules$1,
986
+ tmsModulesMergeLocalModuleCfg: tmsModulesMergeLocalModuleCfg$3,
987
+ subModulesMergeDepModules: subModulesMergeDepModules$2
988
+ };
989
+
990
+ const global$5 = {
991
+ data: {},
992
+
993
+ setData(...args) {
994
+ if (args.length === 1) {
995
+ Object.keys(args[0]).forEach(k => {
996
+ if (args[0][k]) {
997
+ this.data[k] = args[0][k];
998
+ }
999
+ });
1000
+ } else {
1001
+ const [name, value] = args;
1002
+ this.data[name] = value;
1003
+ }
1004
+ },
1005
+
1006
+ getData(name) {
1007
+ return this.data[name];
1008
+ }
1009
+
1010
+ };
1011
+ var global_1 = {
1012
+ global: global$5
1013
+ };
1014
+
1015
+ const {
1016
+ fail: fail$6
1017
+ } = log$1;
1018
+ const {
1019
+ global: global$4
1020
+ } = global_1;
1021
+
1022
+ function handleError$5(error) {
1023
+ const errMsg = typeof error === 'object' ? error.message : error;
1024
+ const isDev = global$4.getData('isDev');
1025
+
1026
+ if (isDev) {
1027
+ fail$6(errMsg);
1028
+ } else {
1029
+ fail$6(errMsg);
1030
+ process.exit(1);
1031
+ }
1032
+ }
1033
+
1034
+ var handleError_1 = {
1035
+ handleError: handleError$5
1036
+ };
1037
+
1038
+ /**
1039
+ * 生成编译后的app.json
1040
+ */
1041
+ const fs$9 = require$$0__default$2;
1042
+ const {
1043
+ MODULE_CONFIG_FILENAME: MODULE_CONFIG_FILENAME$1,
1044
+ MODULE_CONFIG_INVALID_KEY
1045
+ } = require$$4;
1046
+ const {
1047
+ getModuleConfig,
1048
+ getValidModules
1049
+ } = tmsMpconfig;
1050
+ const {
1051
+ fail: fail$5
1052
+ } = log$1;
1053
+ const {
1054
+ resolve: resolve$b,
1055
+ isObject
1056
+ } = widgets;
1057
+ const {
1058
+ handleError: handleError$4
1059
+ } = handleError_1;
1060
+ /**
1061
+ * 更新appJson里面的主包配置
1062
+ * @param { object } appJson appJson信息
1063
+ * @param { array } mainPackages 小程序主包信息
1064
+ * @returns { object } appJson小程序主页配置信息
1065
+ */
1066
+
1067
+ function updateMainPackages(appJson, mainPackages = []) {
1068
+ let foundMainPackages = appJson.subpackages.filter(subpackage => mainPackages.includes(subpackage.name));
1069
+
1070
+ if (foundMainPackages.length === 0) {
1071
+ // 没找到主包
1072
+ foundMainPackages = [appJson.subpackages[0]];
1073
+ } // 拼装 app.pages
1074
+
1075
+
1076
+ foundMainPackages.forEach(subpackage => {
672
1077
  if (!subpackage.pages || !subpackage.pages.length) {
673
- fail$8(`主包 ${subpackage} 不能没有 pages`);
1078
+ fail$5(`主包 ${subpackage} 不能没有 pages`);
674
1079
  process.exit(-1);
675
1080
  }
676
1081
 
@@ -690,22 +1095,22 @@ function updateMainPackages(appJson, mainPackages = []) {
690
1095
  }
691
1096
  /**
692
1097
  * 获取app.json内容
693
- * @param {string} sourceAppJsonPath
1098
+ * @param {string} sourceAppJsonPath app.json存在的源码路径
694
1099
  * @returns
695
1100
  */
696
1101
 
697
1102
 
698
1103
  const getAppJsonContent = sourceAppJsonPath => {
699
- if (!fs$7.existsSync(sourceAppJsonPath)) {
700
- fail$8(`当前路径 ${sourceAppJsonPath} 没找到app.json`);
1104
+ if (!fs$9.existsSync(sourceAppJsonPath)) {
1105
+ fail$5(`当前路径 ${sourceAppJsonPath} 没找到app.json`);
701
1106
  process.exit(1);
702
1107
  }
703
1108
 
704
- const appJson = JSON.parse(fs$7.readFileSync(sourceAppJsonPath), 'utf-8'); // 加入默认值
1109
+ const appJson = JSON.parse(fs$9.readFileSync(sourceAppJsonPath), 'utf-8'); // 加入默认值
705
1110
 
706
1111
  appJson.subpackages = [];
707
- appJson.pages = [];
708
- appJson.plugins = {};
1112
+ appJson.pages = []; // appJson.plugins = {};
1113
+
709
1114
  delete appJson.entranceDeclare;
710
1115
  return appJson;
711
1116
  };
@@ -719,181 +1124,386 @@ const getAppJsonContent = sourceAppJsonPath => {
719
1124
  const updateSubpackages = (appJson, modulesConfig) => {
720
1125
  // eslint-disable-next-line
721
1126
  for (const name in modulesConfig) {
722
- const moduleInfo = isObject$1(modulesConfig[name]) ? [modulesConfig[name]] : modulesConfig[name]; // eslint-disable-next-line
1127
+ const moduleInfo = isObject(modulesConfig[name]) ? [modulesConfig[name]] : modulesConfig[name]; // 过滤 pages 为空的情况
1128
+
1129
+ const validModules = getValidModules(moduleInfo); // eslint-disable-next-line
723
1130
 
724
- appJson.subpackages = appJson.subpackages.concat(moduleInfo);
1131
+ appJson.subpackages = appJson.subpackages.concat(validModules);
725
1132
  }
726
1133
  };
1134
+ /**
1135
+ * 处理合并subpackages后的appjson, 整理重复不合法的地方
1136
+ * @param {Object} appJson appjson
1137
+ */
1138
+
1139
+
1140
+ const fixAppJson = appJson => {
1141
+ const {
1142
+ subpackages
1143
+ } = appJson;
1144
+ const pluginsMap = {};
1145
+ Object.keys(appJson.plugins || {}).forEach(key => pluginsMap[key] = ['app.json']);
1146
+ const subps = subpackages.map(subp => {
1147
+ const invalidKeys = [];
1148
+ Object.keys(subp).forEach(key => {
1149
+ if (key === 'dependencies') {
1150
+ // eslint-disable-next-line
1151
+ delete subp.dependencies;
1152
+ return;
1153
+ }
1154
+
1155
+ if (key === 'plugins') {
1156
+ Object.keys(subp.plugins).forEach(pk => {
1157
+ pluginsMap[pk] ? pluginsMap[pk].push(`分包${subp.name}`) : pluginsMap[pk] = [`分包${subp.name}`];
1158
+ });
1159
+ return;
1160
+ }
1161
+
1162
+ if (MODULE_CONFIG_INVALID_KEY.indexOf(key) > -1) {
1163
+ // 如果分包配置中有不支持的key,则错误提醒
1164
+ invalidKeys.push(key);
1165
+ return;
1166
+ }
1167
+
1168
+ if (['requiredBackgroundModes', 'embeddedAppIdList'].indexOf(key) > -1) {
1169
+ // 提到appjson最上层处理
1170
+ const preVal = appJson[key]; // eslint-disable-next-line
1171
+
1172
+ preVal ? appJson[key] = Array.from(new Set(preVal // eslint-disable-next-line
1173
+ .slice(0).concat(subp[key]))) : appJson[key] = subp[key].slice(0);
1174
+ return;
1175
+ }
1176
+ });
1177
+
1178
+ if (invalidKeys.length) {
1179
+ fail$5(`不支持分包${subp === null || subp === void 0 ? void 0 : subp.name}配置${invalidKeys.join(',')}\n`);
1180
+ } // eslint-disable-next-line
1181
+
1182
+
1183
+ invalidKeys.concat(['requiredBackgroundModes', 'embeddedAppIdList']).forEach(k => delete subp[k]);
1184
+ return subp;
1185
+ }); // 如果plugins重复,则错误提示
1186
+
1187
+ const pluginsErrMsg = Object.keys(pluginsMap).map(pk => {
1188
+ if (pluginsMap[pk].length > 1) {
1189
+ return `${pluginsMap[pk].join(',')}重复配置plugin(${pk});`;
1190
+ }
1191
+
1192
+ return '';
1193
+ }).reduce((pre, cur) => pre + cur, '');
1194
+
1195
+ if (pluginsErrMsg) {
1196
+ fail$5(`plugins配置出现错误:${pluginsErrMsg}`);
1197
+ } // eslint-disable-next-line
1198
+
1199
+
1200
+ appJson.subpackages = subps;
1201
+ };
727
1202
  /**
728
1203
  * 动态生成编译后的app.json
729
1204
  * @param {object} tmsConfig
730
- * @param {array} modules
1205
+ * @param {array} modules 用户要编译的模块列表
731
1206
  * @returns
732
1207
  */
733
1208
 
734
1209
 
735
- function buildOutputAppJson$2(tmsConfig, modules) {
736
- // 获取当前 modules 下的所有子模块的配置内容
737
- const modulesConfig = getLocalModuleConfig(modules, tmsConfig.appName, DEFAULT_MODULE_DIR$4, MODULE_CONFIG_FILENAME$1); // 获取app.json的配置
1210
+ function buildOutputAppJson$1(tmsConfig, modules) {
1211
+ try {
1212
+ // 获取当前 modules 下的所有子模块的配置内容
1213
+ const modulesConfig = getModuleConfig(modules, tmsConfig.appName, MODULE_CONFIG_FILENAME$1); // 获取app.json的配置
738
1214
 
739
- const appJson = getAppJsonContent(resolve$9('./app.json')); // 更新app.json中的subpackages
1215
+ const appJson = getAppJsonContent(resolve$b('./app.json')); // 更新app.json中的subpackages
740
1216
 
741
- updateSubpackages(appJson, modulesConfig); // 更新主包,需在subpackages处理完成后执行, pages/
1217
+ updateSubpackages(appJson, modulesConfig); // 处理appJson中重复||冲突的地方
742
1218
 
743
- updateMainPackages(appJson, tmsConfig.mainPackages);
744
- fs$7.writeFileSync(resolve$9(`${tmsConfig.webpack.outputDir}/app.json`), JSON.stringify(appJson, null, 2), 'utf8');
745
- return appJson;
1219
+ fixAppJson(appJson); // 更新主包,需在subpackages处理完成后执行, pages/
1220
+
1221
+ updateMainPackages(appJson, tmsConfig.mainPackages);
1222
+ fs$9.writeFileSync(resolve$b(`${tmsConfig.outputDir}/app.json`), JSON.stringify(appJson, null, 2), 'utf8');
1223
+ return appJson;
1224
+ } catch (e) {
1225
+ handleError$4(`生成app.json出现错误: ${e}`);
1226
+ }
746
1227
  }
747
1228
 
748
1229
  var buildAppJson = {
749
- setModuleConfig: setModuleConfig$1,
750
- buildOutputAppJson: buildOutputAppJson$2
1230
+ buildOutputAppJson: buildOutputAppJson$1
751
1231
  };
752
1232
 
1233
+ const fs$8 = require$$0__default$2;
1234
+ const {
1235
+ resolve: resolve$a
1236
+ } = widgets;
1237
+ const {
1238
+ handleError: handleError$3
1239
+ } = handleError_1;
1240
+ const {
1241
+ DEFAULT_CLOUD_MODULE_DIR
1242
+ } = require$$4;
753
1243
  /**
754
- * 本文件主要负责项目或者分包依赖的npm的安装
1244
+ * 根据相关配置创建软链接
1245
+ * @param { object } tmsConfig
755
1246
  */
756
- const fs$6 = require$$0__default$1;
757
- const path$4 = require$$1__default$1;
758
- const shell = require$$0__default$2;
759
- const LOG = log$2;
760
- const dirpath = process.cwd(); // 项目根目录
761
1247
 
762
- const getTarNpmFilename = targetDir => `${targetDir.replaceAll('/', '-')}.tar.gz`; // 缓存npm包
1248
+ const symLink$1 = tmsConfig => {
1249
+ try {
1250
+ if (tmsConfig.cloudModules) {
1251
+ tmsConfig.cloudModules.forEach(item => {
1252
+ fs$8.symlinkSync(resolve$a(item.path), resolve$a(DEFAULT_CLOUD_MODULE_DIR, item.name));
1253
+ });
1254
+ }
1255
+ } catch (e) {
1256
+ handleError$3(`创建软链错误: ${e}`);
1257
+ }
1258
+ };
763
1259
 
1260
+ var symbolicLink = {
1261
+ symLink: symLink$1
1262
+ };
764
1263
 
765
- const npmCache = function (targetDir, cacheDir) {
766
- if (!fs$6.existsSync(cacheDir)) {
767
- fs$6.mkdirSync(cacheDir);
768
- }
1264
+ /**
1265
+ * 下载第三方代码
1266
+ */
1267
+ const MetalSmith = require$$0__default$5;
1268
+ const crypto$1 = require$$1__default$3;
1269
+ const {
1270
+ downloadRepoForGit,
1271
+ pullRepoForGit,
1272
+ resolve: resolve$9
1273
+ } = widgets;
1274
+ const {
1275
+ fail: fail$4,
1276
+ info: info$5
1277
+ } = log$1;
1278
+ const fs$7 = require$$0__default$2;
1279
+ const shelljs$4 = require$$0__default$3;
1280
+ const {
1281
+ handleError: handleError$2
1282
+ } = handleError_1;
1283
+ const {
1284
+ global: global$3
1285
+ } = global_1;
1286
+ /**
1287
+ * 处理用户没有clone git仓库权限问题,拼接tms.private.config.js的账号信息
1288
+ * @param {*} httpRepoUrl
1289
+ * @param {*} moduleName
1290
+ * @returns
1291
+ */
1292
+
1293
+ function replaceGitUrlAccount(httpRepoUrl, moduleName) {
1294
+ var _tmsPrivateCf$gitAcco;
769
1295
 
770
- const tarNpmFilename = getTarNpmFilename(targetDir);
771
- const tarNpmFilePath = `${cacheDir}/${tarNpmFilename}`;
1296
+ // 用户本地的私有项目配置(用来配置环境\模块信息\账号信息)
1297
+ const tmsPrivateCf = global$3.getData('tmsPrivateCf');
1298
+ let gitUrl = httpRepoUrl;
1299
+ const {
1300
+ username = '',
1301
+ pass = ''
1302
+ } = (tmsPrivateCf === null || tmsPrivateCf === void 0 ? void 0 : (_tmsPrivateCf$gitAcco = tmsPrivateCf.gitAccout) === null || _tmsPrivateCf$gitAcco === void 0 ? void 0 : _tmsPrivateCf$gitAcco[moduleName]) || {};
1303
+ const urlPrefixReg = /http(s)?:\/\//;
772
1304
 
773
- if (fs$6.existsSync(tarNpmFilePath)) {
774
- shell.rm('-rf', tarNpmFilePath);
1305
+ if (username && pass && urlPrefixReg.test(gitUrl)) {
1306
+ gitUrl = gitUrl.replace(urlPrefixReg, val => `${val}${encodeURIComponent(username)}:${pass}@`);
775
1307
  }
776
1308
 
777
- const cmd = `tar -zcvf ${tarNpmFilePath} ./node_modules`;
778
- shell.exec(cmd, {
779
- async: true,
780
- silent: true
781
- }); // tar -zcvf /Users/odile/.tmskit/node_modules.tar.gz ./node_modules
782
- }; // 获取缓存npm包
1309
+ return gitUrl;
1310
+ }
1311
+ /**
1312
+ * 对克隆下来的模块进行相应的文件处理操作,比如收集处理模块信息,进行信息缓存等操作
1313
+ * @param { string } sourceDir 缓存文件夹
1314
+ * @param { string } targetDir 目标文件夹
1315
+ * @param { arrary } ignore
1316
+ * @returns { undefined } no return
1317
+ */
783
1318
 
784
1319
 
785
- const getNpmCache = function (targetDir, cacheDir) {
786
- const tarNpmFilename = getTarNpmFilename(targetDir);
787
- const tarNpmFilePath = `${cacheDir}/${tarNpmFilename}`;
1320
+ function moveFile(sourceDir, targetDir, ignore = []) {
1321
+ // 删除不是文件夹的文件
1322
+ return new Promise((resolve, reject) => {
1323
+ MetalSmith(__dirname).ignore(ignore).source(sourceDir).destination(targetDir).build(e => {
1324
+ if (e) {
1325
+ fail$4(`${sourceDir} moveFile ${targetDir}出现错误: ${e}`);
1326
+ reject(e);
1327
+ }
788
1328
 
789
- if (fs$6.existsSync(tarNpmFilePath)) {
790
- const cmd = `tar -zxvf ${tarNpmFilePath} -C ./`;
791
- shell.exec(cmd, {
792
- async: false,
793
- silent: true
1329
+ resolve();
794
1330
  });
795
- } // tar -zxvf /Users/odile/.tmskit/node_modules.tar.gz -C ./
796
-
797
- }; // 遍历安装指定目录下所有项目的npm依赖
1331
+ });
1332
+ }
1333
+ /**
1334
+ * 根据gitUrl 和 branch取md5值
1335
+ * @param {*} gitUrl
1336
+ * @param {*} branch
1337
+ * @returns
1338
+ */
798
1339
 
799
1340
 
800
- const npmInstallAll$1 = async (modules, contextDir, cacheDir) => {
801
- const packageJsonFiles = await findAllPackageJson$1(modules, contextDir);
802
- await Promise.all(packageJsonFiles.map(file => new Promise(resolve => {
803
- const dir = path$4.dirname(file);
804
- shell.cd(dir);
1341
+ function md5ByGitUrlBranch(gitUrl, branch) {
1342
+ const newBranch = branch && typeof branch === 'string' ? branch : 'master';
1343
+ return crypto$1.createHash('md5').update(JSON.stringify({
1344
+ gitUrl,
1345
+ branch: newBranch
1346
+ })).digest('hex');
1347
+ }
1348
+ /**
1349
+ * 下载目标模块
1350
+ * @param { string } sourceDir 缓存文件夹
1351
+ * @param { string } targetDir 目标文件夹
1352
+ * @returns { array } modules 描述模块的列表
1353
+ */
805
1354
 
806
- if (!fs$6.existsSync(`${dir}/node_modules`)) {
807
- getNpmCache(dir, cacheDir);
808
- }
809
1355
 
810
- shell.exec('npx pnpm install --prod --registry http://mirrors.tencent.com/npm/', {
811
- silent: false
812
- });
813
- resolve();
814
- npmCache(dir, cacheDir);
815
- })));
816
- };
1356
+ async function cloneModules$1(sourceDir, targetDir, modules) {
1357
+ // 收集下载模块代码的任务
1358
+ const downloadTasksMap = collectDownLoadTasksMap(sourceDir, targetDir, modules); // 开始执行下载和移动代码的任务
1359
+
1360
+ const arrPromises = [];
1361
+ downloadTasksMap.forEach(({
1362
+ promiseTask,
1363
+ params,
1364
+ callbacks
1365
+ }) => {
1366
+ arrPromises.push(promiseTask(...Object.keys(params).map(key => params[key])).then(async () => {
1367
+ const callArr = callbacks.map(async ({
1368
+ params: cParams,
1369
+ fn
1370
+ }) => fn(...Object.keys(cParams).map(key => cParams[key])));
1371
+ return Promise.all(callArr);
1372
+ }).catch(e => {
1373
+ handleError$2(`下载代码${params.httpRepoUrl}出现错误:${e}`);
1374
+ }));
1375
+ });
1376
+ await Promise.all(arrPromises);
1377
+ }
817
1378
  /**
818
- * 递归查找指定条件的文件
819
- * @param {String} startPath 开始查找的根路径
820
- * @param {String} filter 匹配的字符串
821
- * @returns {Array<String>} 查找到的文件路径列表
1379
+ * 收集下载模块代码的任务
1380
+ * @param { string } sourceDir 代码缓存文件夹
1381
+ * @param { string } targetDir 代码要放到的目标文件夹
1382
+ * @returns { array } modules 描述模块的列表
822
1383
  */
823
1384
 
824
1385
 
825
- const findFilesByFilter = (startPath, filter) => {
826
- const result = [];
827
- /**
828
- * 根据指定的筛选器查找文件
829
- * @param {String} startPath 开始查找的文件夹路径
830
- * @param {String} filter 筛选器
831
- * @returns {Undefined} 无需返回值
832
- */
1386
+ function collectDownLoadTasksMap(sourceDir, targetDir, modules) {
1387
+ // 下载代码任务 Map (key解释 缓存代码路径/md5(gitUrl,branch)
1388
+ // {
1389
+ // '/Users/odile/.tmskit/modules_code/026cb72509c2369dbd75779181f820bc': {
1390
+ // promiseTask, 下载代码的任务
1391
+ // params: { 下载代码时的参数
1392
+ // gitUrl,
1393
+ // sourcePath,
1394
+ // branch,
1395
+ // },
1396
+ // callbacks: [callback],// 下载完代码后的回调
1397
+ // }
1398
+ // }
1399
+ const downloadTasksMap = new Map();
833
1400
 
834
- const find = (startPath, filter) => {
835
- // 目录不存在
836
- if (!fs$6.existsSync(startPath)) {
837
- LOG.fail(`${startPath}目录不存在`);
838
- process.exit(-1);
839
- return;
840
- } // 当前目录下的所有文件 / 文件夹
1401
+ for (const moduleInfo of modules) {
1402
+ if (moduleInfo.repoInfo) {
1403
+ const {
1404
+ repoInfo: {
1405
+ buildGitTag: branch,
1406
+ httpRepoUrl,
1407
+ path: gitPath = ''
1408
+ },
1409
+ path,
1410
+ name
1411
+ } = moduleInfo; // 处理仓库权限问题
841
1412
 
1413
+ const gitUrl = replaceGitUrlAccount(httpRepoUrl, name); // 根据gitUrl与branch计算md5
842
1414
 
843
- const exceptDir = ['node_modules', 'miniprogram_npm'];
1415
+ const md5Key = md5ByGitUrlBranch(gitUrl, branch); // git源码临时存在的源目录
844
1416
 
845
- if (exceptDir.find(item => startPath.indexOf(item) > -1)) {
846
- return;
847
- }
1417
+ const sourcePath = resolve$9(sourceDir, md5Key); // 模块源码要放到目标目录
848
1418
 
849
- const files = fs$6.readdirSync(startPath);
850
- files.forEach(file => {
851
- const filename = path$4.join(startPath, file);
852
- const stat = fs$6.lstatSync(filename); // 当前文件是文件夹类型,继续递归
1419
+ const targetPath = resolve$9(targetDir, path); // 从git源码仓库中找到模块源码路径 (一个仓库存在存放多个模块的情况)
853
1420
 
854
- if (stat.isDirectory()) {
855
- find(filename, filter);
856
- } else if (filename.indexOf(filter) >= 0) {
857
- // 文件类型
858
- result.push(filename);
1421
+ const sourceModulePath = gitPath ? `${sourcePath}/${gitPath}` : sourcePath; // 下载完代码后,添加回调函数(主要将模块代码从临时目录移动代码到目标目录)
1422
+
1423
+ const callback = {
1424
+ params: {
1425
+ sourceModulePath,
1426
+ targetPath
1427
+ },
1428
+ fn: async (sourceModulePath, targetPath) => {
1429
+ if (fs$7.existsSync(targetPath)) {
1430
+ shelljs$4.rm('-rf', `${targetPath}/*`);
1431
+ }
1432
+
1433
+ await moveFile(`${sourceModulePath}`, targetPath, ['node_modules', '.git']);
1434
+ }
1435
+ };
1436
+
1437
+ if (downloadTasksMap.has(sourcePath)) {
1438
+ const task = downloadTasksMap.get(sourcePath);
1439
+ task.callbacks.push(callback);
1440
+ downloadTasksMap.set(sourcePath, task);
1441
+ } else {
1442
+ let promiseTask;
1443
+
1444
+ if (fs$7.existsSync(sourcePath) && fs$7.existsSync(`${sourcePath}/.git`)) {
1445
+ promiseTask = (gitUrl, sourcePath, branch, httpRepoUrl) => {
1446
+ info$5(`git pull仓库:${httpRepoUrl}`);
1447
+ return pullRepoForGit(sourcePath, branch);
1448
+ };
1449
+ } else {
1450
+ promiseTask = (gitUrl, sourcePath, branch, httpRepoUrl) => {
1451
+ info$5(`git clone仓库: ${httpRepoUrl}`);
1452
+ return downloadRepoForGit(gitUrl, sourcePath, branch);
1453
+ };
1454
+ }
1455
+
1456
+ downloadTasksMap.set(sourcePath, {
1457
+ promiseTask,
1458
+ params: {
1459
+ gitUrl,
1460
+ sourcePath,
1461
+ branch,
1462
+ httpRepoUrl
1463
+ },
1464
+ callbacks: [callback]
1465
+ });
859
1466
  }
860
- });
861
- };
1467
+ }
1468
+ }
862
1469
 
863
- find(startPath, filter);
864
- return result;
865
- };
1470
+ return downloadTasksMap;
1471
+ }
866
1472
  /**
867
- * 找到项目中所有的package.json文件
868
- * @param {Array<String>} subRoots 需要安装npm依赖的路径
869
- * @param {String} contextDir 命令运行的目录
870
- * @returns {Array<String>} 找到的所有package.json文件的路径
1473
+ * 检查远程模块的gitUrl与 branch是否有更新
1474
+ * @param {string} sourceDir 模块源码在缓存区的目录
1475
+ * @param {object} moduleInfo 模块的配置信息
1476
+ * @returns
871
1477
  */
872
1478
 
873
1479
 
874
- const findAllPackageJson$1 = (subRoots = [], contextDir) => {
875
- const packageJsonName = 'package.json'; // 查找文件名
876
-
877
- const cwd = contextDir || dirpath;
878
- const result = [path$4.join(cwd, packageJsonName)]; // 默认填充根目录下的package.json
1480
+ function checkRemoteModGitUrlBranch$1(sourceDir, moduleInfo) {
1481
+ if (moduleInfo.repoInfo) {
1482
+ const {
1483
+ repoInfo: {
1484
+ buildGitTag,
1485
+ httpRepoUrl
1486
+ },
1487
+ name
1488
+ } = moduleInfo;
1489
+ const gitUrl = replaceGitUrlAccount(httpRepoUrl, name);
1490
+ const md5Key = md5ByGitUrlBranch(gitUrl, buildGitTag);
879
1491
 
880
- subRoots.forEach(subRoot => {
881
- const toppath = path$4.join(cwd, subRoot.root); // 从该目录开始查找package.json文件
1492
+ if (!fs$7.existsSync(`${sourceDir}/${md5Key}`)) {
1493
+ return true;
1494
+ }
1495
+ }
882
1496
 
883
- const list = findFilesByFilter(toppath, packageJsonName);
884
- result.push(...list);
885
- });
886
- return result;
887
- };
1497
+ return false;
1498
+ }
888
1499
 
889
- var npmUtils = {
890
- npmInstallAll: npmInstallAll$1,
891
- findAllPackageJson: findAllPackageJson$1
1500
+ var cloneModules_1 = {
1501
+ cloneModules: cloneModules$1,
1502
+ checkRemoteModGitUrlBranch: checkRemoteModGitUrlBranch$1
892
1503
  };
893
1504
 
894
- /* eslint-disable require-jsdoc */
895
- const ci = require$$0__default$6;
896
- const path$3 = require$$1__default$1;
1505
+ const ci = require$$0__default$7;
1506
+ const path$5 = require$$3__default;
897
1507
  /**
898
1508
  * 获取小程序ci的Project对象
899
1509
  * @returns {Object} 小程序ci对象
@@ -907,7 +1517,7 @@ const getMpCi = ({
907
1517
  }) => {
908
1518
  var _cfgJsonContent$packO;
909
1519
 
910
- const cfgJsonContent = require(path$3.join(projectPath, 'project.config.json'));
1520
+ const cfgJsonContent = require(path$5.join(projectPath, 'project.config.json'));
911
1521
 
912
1522
  const ignores = (cfgJsonContent === null || cfgJsonContent === void 0 ? void 0 : (_cfgJsonContent$packO = cfgJsonContent.packOptions) === null || _cfgJsonContent$packO === void 0 ? void 0 : _cfgJsonContent$packO.ignore.map(({
913
1523
  value
@@ -949,7 +1559,7 @@ const formatPackNpmWarning = warning => {
949
1559
  */
950
1560
 
951
1561
 
952
- const buildMpNpm$2 = async ({
1562
+ const buildMpNpm$1 = async ({
953
1563
  appId,
954
1564
  projectPath,
955
1565
  privateKey
@@ -969,306 +1579,311 @@ const buildMpNpm$2 = async ({
969
1579
  return Promise.resolve();
970
1580
  };
971
1581
 
972
- var mpCiUtils = {
973
- buildMpNpm: buildMpNpm$2
974
- };
975
-
976
- class Globale {
977
- constructor() {
978
- this.moduleCache = {};
979
- }
980
-
981
- setModuleCache(url, branch, dest) {
982
- const instance = getGlobalInstance$1();
983
- const key = `${branch}:${url}`;
984
- instance.moduleCache[key] = {
985
- dest
986
- };
987
- return instance.moduleCache[key];
988
- }
989
-
990
- getModuleCache(url, branch) {
991
- const instance = getGlobalInstance$1();
992
- return instance.moduleCache[`${branch}:${url}`];
993
- }
994
-
995
- }
996
-
997
- let instance;
998
-
999
- function getGlobalInstance$1() {
1000
- if (instance) {
1001
- return instance;
1002
- }
1003
-
1004
- return instance = new Globale();
1005
- }
1006
-
1007
- var global = {
1008
- getGlobalInstance: getGlobalInstance$1
1582
+ var mpCi = {
1583
+ buildMpNpm: buildMpNpm$1
1009
1584
  };
1010
1585
 
1011
- const MetalSmith = require$$0__default$5;
1012
- const {
1013
- getGlobalInstance
1014
- } = global;
1586
+ /**
1587
+ * 本文件主要负责项目或者分包依赖的npm的安装
1588
+ */
1589
+ const fs$6 = require$$0__default$2;
1590
+ const fsExtra = require$$1__default$4;
1591
+ const crypto = require$$1__default$3;
1592
+ const path$4 = require$$3__default;
1593
+ const shell = require$$0__default$3;
1594
+ const glob = require$$5__default;
1595
+ const log = log$1;
1015
1596
  const {
1016
- downloadRepoForGit,
1017
- resolve: resolve$8
1597
+ npmInstall
1018
1598
  } = widgets;
1019
1599
  const {
1020
- fail: fail$7
1021
- } = log$2;
1022
- const fs$5 = require$$0__default$1;
1023
- const shelljs$4 = require$$0__default$2;
1024
- /**
1025
- * 对克隆下来的模块进行相应的文件处理操作,比如收集处理模块信息,进行信息缓存等操作
1026
- * @param { string } sourceDir 缓存文件夹
1027
- * @param { string } targetDir 目标文件夹
1028
- * @param { arrary } ignore
1029
- * @returns { undefined } no return
1030
- */
1031
-
1032
- function moveFile(sourceDir, targetDir, ignore = []) {
1033
- // 删除不是文件夹的文件
1034
- return new Promise(resolve => {
1035
- MetalSmith(__dirname).ignore(ignore).source(sourceDir).destination(targetDir).build(e => {
1036
- if (e) {
1037
- fail$7(e); // eslint-disable-line
1038
-
1039
- console.log('MetalSmith 详细的错误信息:', e);
1040
- }
1041
-
1042
- resolve();
1043
- });
1044
- });
1045
- }
1046
- /**
1047
- * 下载目标模块
1048
- * @param { string } sourceDir 缓存文件夹
1049
- * @param { string } targetDir 目标文件夹
1050
- * @returns { array } modules 描述模块的列表
1051
- */
1600
+ handleError: handleError$1
1601
+ } = handleError_1;
1602
+ const {
1603
+ info: info$4
1604
+ } = require$$9__default;
1605
+ const shellJsOption = {
1606
+ async: false,
1607
+ silent: true
1608
+ };
1609
+ const dirPath = process.cwd(); // 项目根目录
1610
+
1611
+ const collectNpmTasksMap = (packageJsonFiles, cacheDir) => {
1612
+ // 下载代码任务 Map (key解释 缓存代码路径/md5(package.json.dependencies)
1613
+ // {
1614
+ // '/Users/odile/.tmskit/node_modules/026cb72509c2369dbd75779181f820bc': {
1615
+ // promiseTask, 下载的任务
1616
+ // params: { 下载代码时的参数
1617
+ // gitUrl,
1618
+ // sourcePath,
1619
+ // branch,
1620
+ // },
1621
+ // callbacks: [callback],// 下载完代码后的回调
1622
+ // }
1623
+ // }
1624
+ const npmTasksMap = new Map();
1625
+
1626
+ for (const packageJsonPath of packageJsonFiles) {
1627
+ const packageContent = fs$6.readFileSync(packageJsonPath);
1628
+ const packageJson = JSON.parse(packageContent);
1629
+ const md5Obj = {
1630
+ dependencies: packageJson.dependencies || {}
1631
+ };
1052
1632
 
1633
+ if (Object.keys(md5Obj.dependencies).length !== 0) {
1634
+ const md5Key = crypto.createHash('md5').update(JSON.stringify(md5Obj)).digest('hex');
1635
+ const cacheNMPath = path$4.join(cacheDir, md5Key);
1636
+ const cacheNMTarFile = path$4.join(cacheNMPath, 'node_modules.tar.gz'); // 下载后,添加回调函数 (拷贝node_modules.tar.gz到编译目录并解压)
1637
+
1638
+ const callback = {
1639
+ params: {
1640
+ cacheNMPath,
1641
+ cacheNMTarFile,
1642
+ packageJsonDir: path$4.dirname(packageJsonPath),
1643
+ shell
1644
+ },
1645
+ fn: async (cacheNMPath, cacheNMTarFile, packageJsonDir, shell) => {
1646
+ shell.cd(cacheNMPath);
1647
+ shell.cp('-Rf', cacheNMTarFile, `${packageJsonDir}/`);
1648
+ const newShellJsOption = { ...shellJsOption,
1649
+ cwd: packageJsonDir
1650
+ };
1651
+ shell.exec('tar -xzvf ./node_modules.tar.gz -C ./', newShellJsOption);
1652
+ shell.exec('rm -rf ./node_modules.tar.gz', newShellJsOption);
1653
+ }
1654
+ };
1053
1655
 
1054
- async function cloneModules$1(sourceDir, targetDir, modules) {
1055
- // 根据小程序的配置文件下载模块, 并且处理信息
1056
- for (const moduleInfo of modules) {
1057
- // eslint-disable-line
1058
- if (moduleInfo.repoInfo) {
1059
- await downLoadAndMoveModule(sourceDir, targetDir, moduleInfo);
1060
- }
1061
- }
1062
- }
1063
- /**
1064
- * 下载模块信息并且将它移动到对应的位置
1065
- * @param { string } sourceDir 代码缓存文件夹
1066
- * @param { string } targetDir 代码要放到的目标文件夹
1067
- * @returns { array } moduleInfo 描述模块的信息
1068
- */
1656
+ if (npmTasksMap.has(cacheNMPath)) {
1657
+ const task = npmTasksMap.get(cacheNMPath);
1658
+ task.callbacks.push(callback);
1659
+ npmTasksMap.set(cacheNMPath, task);
1660
+ } else {
1661
+ const missCache = !fsExtra.pathExistsSync(cacheNMPath) || !fsExtra.existsSync(cacheNMTarFile) || fsExtra.statSync(cacheNMTarFile).size < 512;
1662
+
1663
+ let promiseTask = () => Promise.resolve();
1664
+
1665
+ if (missCache) {
1666
+ promiseTask = (packageJsonPath, cacheNMPath, shell) => {
1667
+ fsExtra.emptydirSync(cacheNMPath);
1668
+ shell.cp('-f', packageJsonPath, cacheNMPath);
1669
+ info$4(`npm install: ${packageJsonPath}`);
1670
+ return npmInstall(cacheNMPath).then(() => {
1671
+ const newShellJsOption = { ...shellJsOption,
1672
+ cwd: cacheNMPath
1673
+ };
1674
+ shell.exec('tar -zcvf ./node_modules.tar.gz ./node_modules', newShellJsOption);
1675
+ shell.exec('rm -rf ./node_modules', newShellJsOption);
1676
+ });
1677
+ };
1678
+ }
1069
1679
 
1680
+ npmTasksMap.set(cacheNMPath, {
1681
+ promiseTask,
1682
+ params: {
1683
+ packageJsonPath,
1684
+ cacheNMPath,
1685
+ shell
1686
+ },
1687
+ callbacks: [callback]
1688
+ });
1689
+ }
1690
+ }
1691
+ }
1070
1692
 
1071
- async function downLoadAndMoveModule(sourceDir, targetDir, moduleInfo) {
1072
- const {
1073
- repoInfo: {
1074
- buildGitTag,
1075
- httpRepoUrl
1076
- },
1077
- path
1078
- } = moduleInfo; // 源码临时存在的源目录
1693
+ return npmTasksMap;
1694
+ }; // 遍历安装指定目录下所有项目的npm依赖
1079
1695
 
1080
- let sourcePath = resolve$8(sourceDir, path); // 源码要放到目标目录
1081
1696
 
1082
- const targetPath = resolve$8(targetDir, path); // 设置模块的构建分支
1697
+ const mpNpmInstallAll$1 = async (modules, contextDir, cacheDir) => {
1698
+ const packageJsonFiles = await findAllPackageJson(modules, contextDir); // 收集npm install的任务
1083
1699
 
1084
- const cloneBranch = buildGitTag && typeof buildGitTag === 'string' ? buildGitTag : 'master'; // 检查缓存中有没有
1700
+ const npmTasksMap = collectNpmTasksMap(packageJsonFiles, cacheDir); // 开始执行npm install和回调(移动)的任务
1085
1701
 
1086
- const globalInstance = getGlobalInstance();
1087
- const moduleInCache = globalInstance.getModuleCache(httpRepoUrl, cloneBranch);
1702
+ const arrPromises = [];
1703
+ npmTasksMap.forEach(({
1704
+ promiseTask,
1705
+ params,
1706
+ callbacks
1707
+ }) => {
1708
+ arrPromises.push(promiseTask(...Object.keys(params).map(key => params[key])).then(async () => {
1709
+ const callArr = callbacks.map(async ({
1710
+ params: cParams,
1711
+ fn
1712
+ }) => fn(...Object.keys(cParams).map(key => cParams[key])));
1713
+ return Promise.all(callArr);
1714
+ }).catch(e => {
1715
+ handleError$1(`npm install ${params.packageJsonPath}出现错误:${e}`);
1716
+ }));
1717
+ });
1718
+ await Promise.all(arrPromises);
1719
+ };
1720
+ /**
1721
+ * 递归查找指定条件的文件
1722
+ * @param {String} startPath 开始查找的根路径
1723
+ * @param {String} filter 匹配的字符串
1724
+ * @returns {Array<String>} 查找到的文件路径列表
1725
+ */
1088
1726
 
1089
- try {
1090
- if (!moduleInCache) {
1091
- await downloadRepoForGit(httpRepoUrl, sourcePath, cloneBranch);
1092
- globalInstance.setModuleCache(httpRepoUrl, cloneBranch, sourcePath);
1093
- } else {
1094
- sourcePath = globalInstance.getModuleCache(httpRepoUrl, cloneBranch).dest;
1095
- }
1096
1727
 
1097
- if (fs$5.existsSync(targetPath)) {
1098
- shelljs$4.rm('-rf', targetPath);
1099
- }
1728
+ const findFilesByFilter = (startPath, filter) => {
1729
+ const result = [];
1730
+ /**
1731
+ * 根据指定的筛选器查找文件
1732
+ * @param {String} startPath 开始查找的文件夹路径
1733
+ * @param {String} filter 筛选器
1734
+ * @returns {Undefined} 无需返回值
1735
+ */
1100
1736
 
1101
- await moveFile(sourcePath, targetPath, ['node_modules', '.git']);
1102
- } catch (e) {
1103
- fail$7(`downLoadAndMoveModule ${e}`); // eslint-disable-line
1737
+ const find = (startPath, filter) => {
1738
+ // 目录不存在
1739
+ if (!fs$6.existsSync(startPath)) {
1740
+ log.fail(`${startPath}目录不存在`);
1741
+ process.exit(-1);
1742
+ return;
1743
+ } // 当前目录下的所有文件 / 文件夹
1104
1744
 
1105
- process.exit(-1);
1106
- }
1107
- }
1108
1745
 
1109
- var cloneModules_1 = {
1110
- cloneModules: cloneModules$1
1111
- };
1746
+ const exceptDir = ['node_modules', 'miniprogram_npm'];
1112
1747
 
1113
- var defaultTmsConfig$1 = {
1114
- // 全局的环境配置项
1115
- envData: {},
1116
- // 模块配置信息
1117
- modules: [],
1118
- webpack: {
1119
- /** 编译输出文件夹位置 */
1120
- outputDir: 'dist',
1748
+ if (exceptDir.find(item => startPath.indexOf(item) > -1)) {
1749
+ return;
1750
+ }
1121
1751
 
1122
- /** 源码监听路径 */
1123
- sourceDir: './',
1752
+ const files = fs$6.readdirSync(startPath);
1753
+ files.forEach(file => {
1754
+ const filename = path$4.join(startPath, file);
1755
+ const stat = fs$6.lstatSync(filename); // 当前文件是文件夹类型,继续递归
1124
1756
 
1125
- /** 源码Map */
1126
- sourceMap: 'none',
1757
+ if (stat.isDirectory()) {
1758
+ find(filename, filter);
1759
+ } else if (filename.indexOf(filter) >= 0) {
1760
+ // 文件类型
1761
+ result.push(filename);
1762
+ }
1763
+ });
1764
+ };
1127
1765
 
1128
- /** 别名 */
1129
- alias: {}
1130
- }
1766
+ find(startPath, filter);
1767
+ return result;
1131
1768
  };
1132
-
1133
- const loadash = require$$0__default$7;
1134
- const fs$4 = require$$0__default$1;
1135
- const {
1136
- TMS_NAME: TMS_NAME$1,
1137
- TMS_CONFIG_FILENAME,
1138
- MODULE_CONFIG_FILENAME
1139
- } = require$$3;
1140
- const {
1141
- resolve: resolve$7,
1142
- isObject
1143
- } = widgets;
1144
- const {
1145
- setModuleConfig
1146
- } = buildAppJson;
1147
- const defaultTmsConfig = defaultTmsConfig$1;
1148
- const {
1149
- fail: fail$6
1150
- } = log$2;
1151
1769
  /**
1152
- * 读取tms.config.json
1153
- * @param env {string} 环境变量
1154
- */
1770
+ * 找到项目中所有的package.json文件
1771
+ * @param {Array<String>} subRoots 需要安装npm依赖的路径
1772
+ * @param {String} contextDir 命令运行的目录
1773
+ * @returns {Array<String>} 找到的所有package.json文件的路径
1774
+ */
1155
1775
 
1156
- const readTmsConfig$1 = function (env) {
1157
- const tmsConfigPath = resolve$7(TMS_CONFIG_FILENAME);
1158
1776
 
1159
- if (!fs$4.existsSync(tmsConfigPath)) {
1160
- fail$6('当前执行目录没有tms.config.js的配置项,请进行配置');
1161
- process.exit(1);
1162
- }
1777
+ const findAllPackageJson = (subRoots = [], contextDir) => {
1778
+ const packageJsonName = 'package.json'; // 查找文件名
1163
1779
 
1164
- const tmsConfigFn = require(tmsConfigPath);
1780
+ const cwd = contextDir || dirPath;
1781
+ const result = [path$4.join(cwd, packageJsonName)]; // 默认填充根目录下的package.json
1165
1782
 
1166
- const tmsConfig = tmsConfigFn({
1167
- env
1168
- }); // 合并默认值
1783
+ subRoots.forEach(subRoot => {
1784
+ if (!subRoot.root) {
1785
+ log.fail(`请检查${subRoot.name}的module.config.json是否有root字段`);
1786
+ process.exit(1);
1787
+ }
1169
1788
 
1170
- loadash.mergeWith(tmsConfig, defaultTmsConfig);
1171
- return tmsConfig;
1789
+ const toppath = path$4.join(cwd, subRoot.root); // 从该目录开始查找package.json文件
1790
+
1791
+ const list = findFilesByFilter(toppath, packageJsonName);
1792
+ result.push(...list);
1793
+ });
1794
+ return result;
1172
1795
  };
1173
- /**
1174
- * 从tms.config.json中检索用户传入的有效modules
1175
- * @param { object } tmsConfig
1176
- * @param { array } modules
1177
- * @returns
1178
- */
1179
1796
 
1797
+ function cloudNpmInstall$1(contextDir) {
1798
+ return new Promise((resolve, reject) => {
1799
+ glob(`${contextDir}/**/package.json`, ['node_modules', 'miniprogram_npm'], (err, files) => {
1800
+ if (err) {
1801
+ reject(err);
1802
+ }
1180
1803
 
1181
- const checkModules$1 = function (tmsConfig, modules) {
1182
- const targetModules = [];
1183
- modules.forEach(moduleName => {
1184
- const module = tmsConfig.modules.find(module => module.name === moduleName);
1185
- module && targetModules.push(module);
1804
+ files.forEach(file => {
1805
+ const dir = path$4.dirname(file);
1806
+ shell.cd(dir);
1807
+ shell.exec('npx npm install --production --registry http://mirrors.tencent.com/npm/', {
1808
+ silent: false
1809
+ });
1810
+ });
1811
+ resolve();
1812
+ });
1186
1813
  });
1814
+ }
1187
1815
 
1188
- if (targetModules.length === 0) {
1189
- fail$6(`你启动的模块无效,尝试 ${TMS_NAME$1} -m moduleName`);
1190
- process.exit(1);
1191
- }
1192
-
1193
- return targetModules;
1816
+ var npm = {
1817
+ cloudNpmInstall: cloudNpmInstall$1,
1818
+ mpNpmInstallAll: mpNpmInstallAll$1,
1819
+ findAllPackageJson
1194
1820
  };
1195
- /**
1196
- * tms.config.js的modules 合并 module.config.json的配置项
1197
- * @param {array} modules
1198
- * @param {string} appName
1199
- * @param {string} moduleDir
1200
- * @returns
1201
- */
1202
1821
 
1822
+ const {
1823
+ createTask: createTask$1,
1824
+ resolve: resolve$8
1825
+ } = widgets;
1826
+ const {
1827
+ buildMpNpm
1828
+ } = mpCi;
1829
+ const {
1830
+ CACHE_DIR
1831
+ } = require$$4;
1832
+ const {
1833
+ cloudNpmInstall,
1834
+ mpNpmInstallAll
1835
+ } = npm;
1836
+ const {
1837
+ global: global$2
1838
+ } = global_1;
1839
+
1840
+ async function install$2(tmsConfig, modules, isCloud = false) {
1841
+ // 小程序npm install
1842
+ await createTask$1(mpNpmInstallAll, '小程序 开始npm install', '小程序npm install 完成')(modules, resolve$8(tmsConfig.outputDir), `${CACHE_DIR}/node_modules`);
1843
+ const tmsPrivateCf = global$2.getData('tmsPrivateCf'); // 构建miniprogram_npm
1203
1844
 
1204
- const tmsModulesMergeLocalModuleCfg$3 = (modules, appName, moduleDir) => {
1205
- const newModules = [];
1206
- modules.forEach(({
1207
- path: relativePath,
1208
- name: moduleName
1209
- }, moduleIndex) => {
1210
- const moduleConfigPath = resolve$7(relativePath, MODULE_CONFIG_FILENAME);
1845
+ await createTask$1(buildMpNpm, '开始构建miniprogram_npm', '构建miniprogram_npm 完成')({
1846
+ appId: tmsConfig.appId,
1847
+ projectPath: resolve$8('./'),
1848
+ privateKey: tmsPrivateCf.privateKey
1849
+ }); // 安装云函数的
1211
1850
 
1212
- if (fs$4.existsSync(moduleConfigPath)) {
1213
- let moduleConfigContent = fs$4.readFileSync(moduleConfigPath, 'utf-8');
1214
- moduleConfigContent = setModuleConfig(moduleConfigContent, appName, moduleDir);
1215
- const moduleContentArr = isObject(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
1216
- moduleContentArr.forEach(({
1217
- name
1218
- }, moduleContentArrIndex) => {
1219
- if (name === moduleName) {
1220
- newModules.push({ ...modules[moduleIndex],
1221
- ...moduleContentArr[moduleContentArrIndex]
1222
- });
1223
- }
1224
- });
1225
- } else {
1226
- newModules.push({ ...modules[moduleIndex]
1227
- });
1228
- }
1229
- });
1230
- return newModules;
1231
- };
1851
+ isCloud && createTask$1(cloudNpmInstall, '云函数npm install', '云函数npm install安装完毕')(resolve$8(tmsConfig.cloudDir));
1852
+ }
1232
1853
 
1233
- var tkitUtils = {
1234
- readTmsConfig: readTmsConfig$1,
1235
- checkModules: checkModules$1,
1236
- tmsModulesMergeLocalModuleCfg: tmsModulesMergeLocalModuleCfg$3
1237
- };
1854
+ var install_1 = install$2;
1238
1855
 
1239
- const shelljs$3 = require$$0__default$2;
1240
- const fs$3 = require$$0__default$1;
1856
+ const shelljs$3 = require$$0__default$3;
1857
+ const fs$5 = require$$0__default$2;
1241
1858
  const io = io$2;
1242
1859
  const {
1243
- resolve: resolve$6,
1244
- createTask: createTask$3
1860
+ resolve: resolve$7,
1861
+ createTask
1245
1862
  } = widgets;
1246
1863
  const {
1247
- buildOutputAppJson: buildOutputAppJson$1
1864
+ buildOutputAppJson
1248
1865
  } = buildAppJson;
1249
1866
  const {
1250
- npmInstallAll
1251
- } = npmUtils;
1252
- const {
1253
- buildMpNpm: buildMpNpm$1
1254
- } = mpCiUtils;
1867
+ symLink
1868
+ } = symbolicLink;
1255
1869
  const {
1256
- MODULE_CODE_DIR,
1257
- CACHE_DIR,
1258
- DEFAULT_COPY_CONFIG: DEFAULT_COPY_CONFIG$2,
1259
- DEFAULT_MODULE_DIR: DEFAULT_MODULE_DIR$3
1260
- } = require$$3;
1870
+ MODULE_CODE_DIR: MODULE_CODE_DIR$1,
1871
+ DEFAULT_COPY_CONFIG
1872
+ } = require$$4;
1261
1873
  const {
1262
1874
  cloneModules
1263
1875
  } = cloneModules_1;
1264
1876
  const {
1265
- tmsModulesMergeLocalModuleCfg: tmsModulesMergeLocalModuleCfg$2
1266
- } = tkitUtils;
1877
+ tmsModulesMergeLocalModuleCfg: tmsModulesMergeLocalModuleCfg$2,
1878
+ subModulesMergeDepModules: subModulesMergeDepModules$1
1879
+ } = tmsMpconfig;
1267
1880
  const {
1268
- fail: fail$5
1269
- } = log$2;
1881
+ fail: fail$3,
1882
+ info: info$3
1883
+ } = log$1;
1884
+ const install$1 = install_1;
1270
1885
  /**
1271
- * 拷贝package.json\模块的代码到编译输出目录
1886
+ * 拷贝相关配置文件到编译输出目录
1272
1887
  * @param { object } tmsConfig
1273
1888
  * @param { array } modules
1274
1889
  * @param { array } defaultFiles 默认需要拷贝的配置项
@@ -1276,504 +1891,876 @@ const {
1276
1891
  */
1277
1892
 
1278
1893
  const cpFilesToOutput = function (tmsConfig, targetModules, defaultFiles) {
1279
- const outputDir = resolve$6(tmsConfig.webpack.outputDir);
1894
+ const outputDir = resolve$7(tmsConfig.outputDir);
1280
1895
  io.ensureDirExist(outputDir);
1281
1896
  defaultFiles.forEach(item => {
1282
- if (fs$3.existsSync(resolve$6(item))) {
1283
- shelljs$3.cp('-rf', resolve$6(item), resolve$6(tmsConfig.webpack.outputDir, item));
1897
+ if (fs$5.existsSync(resolve$7(item))) {
1898
+ shelljs$3.cp('-rf', resolve$7(item), resolve$7(tmsConfig.outputDir, item));
1284
1899
  }
1285
- }); // 拷贝模块的代码到编译输出目录
1900
+ }); // 拷贝模块的package.json到编译输出目录
1286
1901
 
1287
1902
  targetModules.forEach(item => {
1288
- const outputModuleDir = resolve$6(`${tmsConfig.webpack.outputDir}/${item.root}`);
1903
+ const outputModuleDir = resolve$7(`${tmsConfig.outputDir}/${item.root}`);
1289
1904
 
1290
- if (!fs$3.existsSync(resolve$6(item.path))) {
1291
- fail$5(`${item.path}模块代码路径不存在, 请检查tms.config.js的${item.name}模块的path`);
1905
+ if (!fs$5.existsSync(resolve$7(item.path))) {
1906
+ fail$3(`${item.path}模块代码路径不存在, 请检查tms.config.js的${item.name}模块的path`);
1292
1907
  process.exit(1);
1293
1908
  }
1294
1909
 
1295
- if (!fs$3.existsSync(outputModuleDir)) {
1296
- shelljs$3.mkdir('-p', outputModuleDir);
1297
- } else {
1298
- // 删除除了node_modules、miniprogram_npm 的其他文件
1299
- // eslint-disable-next-line
1300
- shelljs$3.exec('find . -not \( -name node_modules -or -name miniprogram_npm \) -delete', {
1301
- silent: true
1302
- });
1303
- }
1304
-
1305
- shelljs$3.cp('-Rf', `${resolve$6(item.path)}/*`, outputModuleDir);
1910
+ io.ensureDirExist(outputModuleDir);
1911
+ const modulePackagePath = resolve$7(item.path, 'package.json');
1912
+ if (fs$5.existsSync(modulePackagePath)) shelljs$3.cp('-Rf', modulePackagePath, outputModuleDir);
1306
1913
  });
1307
1914
  };
1308
1915
 
1309
1916
  async function task(tmsConfig, targetModules) {
1310
1917
  // 下载和移动代码
1311
- await createTask$3(cloneModules, '开始下载模块代码完成', '下载模块代码码完成')(MODULE_CODE_DIR, resolve$6('./'), targetModules); // tms.config.js的modules 合并 module.config.json的配置项
1918
+ await createTask(cloneModules, '开始下载模块代码', '下载模块代码码完成')(MODULE_CODE_DIR$1, resolve$7('./'), targetModules); // tms.config.js的modules 合并 module.config.json的配置项
1312
1919
 
1313
- const newModules = tmsModulesMergeLocalModuleCfg$2(targetModules, tmsConfig.appName, DEFAULT_MODULE_DIR$3);
1314
- console.log('当前init的有效模块', newModules.map(item => item.name)); // 拷贝相关配置文件到输出目录
1920
+ let newModules = tmsModulesMergeLocalModuleCfg$2(targetModules, tmsConfig.appName); // A分包依赖了B分包的代码, merge B分包进行编译;
1315
1921
 
1316
- await createTask$3(cpFilesToOutput, '开始拷贝文件到编译输出目录', '拷贝文件到编译输出目录完成')(tmsConfig, newModules, DEFAULT_COPY_CONFIG$2); // npm install
1922
+ newModules = subModulesMergeDepModules$1(tmsConfig, newModules); // 拷贝相关配置文件到输出目录
1317
1923
 
1318
- await createTask$3(npmInstallAll, '开始npm install', 'npm install 完成')(newModules, resolve$6(tmsConfig.webpack.outputDir), `${CACHE_DIR}/node_modules`); // 构建miniprograme_npm
1924
+ await createTask(cpFilesToOutput, '开始拷贝文件到编译输出目录', '拷贝文件到编译输出目录完成')(tmsConfig, newModules, DEFAULT_COPY_CONFIG); // install
1319
1925
 
1320
- await createTask$3(buildMpNpm$1, '开始构建miniprograme_npm', '构建miniprograme_npm 完成')({
1321
- appId: tmsConfig.appId,
1322
- projectPath: resolve$6('./'),
1323
- privateKey: tmsConfig.privateKey
1324
- }); // 动态生成编译后的app.json;
1926
+ await install$1(tmsConfig, newModules, false); // 动态生成编译后的app.json;
1325
1927
 
1326
- await createTask$3(buildOutputAppJson$1, '开始生成编译后的app.json', '生成编译后的app.json完成')(tmsConfig, newModules);
1928
+ await createTask(buildOutputAppJson, '开始生成编译后的app.json', '生成编译后的app.json完成')(tmsConfig, newModules);
1929
+ await createTask(symLink, '开始创建软链接', '创建软链接完成')(tmsConfig);
1327
1930
  return newModules;
1328
1931
  }
1329
1932
 
1330
- async function bootstrap(tmsConfig, targetModules) {
1331
- const newModules = await task(tmsConfig, targetModules);
1332
- return {
1333
- targetModules: newModules
1334
- };
1933
+ async function init$5(tmsConfig, targetModules) {
1934
+ try {
1935
+ const newModules = await task(tmsConfig, targetModules);
1936
+ return {
1937
+ targetModules: newModules
1938
+ };
1939
+ } catch (error) {
1940
+ const errMsg = typeof error === 'object' ? error.message : error;
1941
+ fail$3(`init流程出现错误${errMsg}`);
1942
+ info$3('详细的错误信息', error);
1943
+ process.exit(1);
1944
+ }
1335
1945
  }
1336
1946
 
1337
- var init$5 = bootstrap;
1947
+ var init_1 = init$5;
1338
1948
 
1339
- const path$2 = require$$1__default$1;
1340
- const fs$2 = require$$0__default$1;
1341
- const {
1342
- resolve: resolve$5
1343
- } = widgets;
1344
- const {
1345
- buildOutputAppJson
1346
- } = buildAppJson;
1347
- const {
1348
- tmsModulesMergeLocalModuleCfg: tmsModulesMergeLocalModuleCfg$1
1349
- } = tkitUtils;
1350
- const {
1351
- findAllPackageJson
1352
- } = npmUtils;
1353
- const {
1354
- fail: fail$4
1355
- } = log$2;
1356
- const replaceExt = require$$7__default;
1357
- const extensions = ['.ts', '.js'];
1949
+ var dev$3 = {exports: {}};
1358
1950
 
1359
- function ext(entry, extensions) {
1360
- let newEntry = entry;
1951
+ /* eslint-disable no-param-reassign */
1952
+ const strip = require$$0__default$8; // 匹配规则
1361
1953
 
1362
- try {
1363
- const stat = fs$2.lstatSync(newEntry);
1954
+ const MATCH_RULE = new RegExp(/@import *(?:url\(['"]?([^'")]+)['"]?\)|['"]([^'"]+)['"]);?/g);
1955
+ /**
1956
+ * 获取样式文件中的@import语句
1957
+ * @param code 代码片段
1958
+ * @returns 结果数组
1959
+ */
1364
1960
 
1365
- if (stat.isDirectory()) {
1366
- newEntry += newEntry[newEntry.length - 1] === '/' ? 'index' : '/index';
1367
- }
1368
- } catch (e) {}
1961
+ const findCssImports$1 = code => {
1962
+ // 将buffer转成字符串
1963
+ code = code.toString(); // 去除注释
1369
1964
 
1370
- for (const ext of extensions) {
1371
- const file = replaceExt(newEntry, ext);
1965
+ code = strip.block(code); // 定义最后返回的结果
1372
1966
 
1373
- if (fs$2.existsSync(file)) {
1374
- return {
1375
- file,
1376
- ext
1377
- };
1378
- }
1379
- }
1967
+ const result = [];
1968
+ let matchList; // 循环遍历代码段,直至匹配结果为空
1380
1969
 
1381
- return null;
1382
- } // 获取所有的package.json里的依赖包Dir
1970
+ while (matchList = MATCH_RULE.exec(code)) {
1971
+ var _matchList, _matchList2;
1383
1972
 
1973
+ // 存入结果数组
1974
+ result.push(((_matchList = matchList) === null || _matchList === void 0 ? void 0 : _matchList[1]) || ((_matchList2 = matchList) === null || _matchList2 === void 0 ? void 0 : _matchList2[2]));
1975
+ } // 返回结果
1384
1976
 
1385
- function getAlias$1(modules) {
1386
- const alias = {};
1387
- const allPackages = findAllPackageJson(modules, resolve$5('./dist'));
1388
- allPackages.forEach(packageFilePath => {
1389
- const {
1390
- dependencies
1391
- } = require(packageFilePath);
1392
1977
 
1393
- Object.keys(dependencies).forEach(dependence => {
1394
- alias[dependence] = path$2.join(path$2.dirname(packageFilePath), `./miniprogram_npm/${dependence}`);
1395
- });
1396
- });
1397
- return alias;
1398
- } // 根据用户选择的modules,找到module.config.json的配置信息,找到所有的page
1978
+ return result;
1979
+ };
1399
1980
 
1981
+ var findCssImport = {
1982
+ findCssImports: findCssImports$1
1983
+ };
1400
1984
 
1401
- function getPageEntry(modules, tmsConfig, moduleDir) {
1402
- const entry = {}; // tms.config.js的modules 合并 module.config.json的配置项
1985
+ /* eslint-disable no-param-reassign */
1986
+ const {
1987
+ fail: fail$2
1988
+ } = log$1;
1403
1989
 
1404
- const newModules = tmsModulesMergeLocalModuleCfg$1(modules, tmsConfig.appName, moduleDir);
1405
- newModules.forEach(({
1406
- path: relativePath,
1407
- pages,
1408
- root
1409
- }) => {
1410
- pages.forEach(page => {
1411
- const pageJsonPath = `${resolve$5(relativePath, page)}.json`;
1990
+ function pluginError$3(error, isWatch) {
1991
+ const errMsg = error.message;
1412
1992
 
1413
- if (fs$2.existsSync(pageJsonPath)) {
1414
- const pageJsonContent = JSON.parse(fs$2.readFileSync(pageJsonPath, 'utf-8'));
1415
- const pageDir = path$2.dirname(pageJsonPath); // 该页面所在的目录
1993
+ if (isWatch) {
1994
+ fail$2(errMsg);
1995
+ } else {
1996
+ fail$2(errMsg);
1997
+ process.exit(1);
1998
+ }
1999
+ }
1416
2000
 
1417
- const extValue = ext(resolve$5(relativePath, page), extensions);
2001
+ var pluginError_1 = {
2002
+ pluginError: pluginError$3
2003
+ };
1418
2004
 
1419
- if (!extValue) {
1420
- fail$4(`当前${page}找不到入口.js或.ts文件`);
1421
- process.exit(1);
2005
+ /* eslint-disable no-param-reassign */
2006
+ const through$2 = require$$0__default$9;
2007
+ const precinct = require$$1__default$5;
2008
+ const path$3 = require$$3__default;
2009
+ const {
2010
+ findCssImports
2011
+ } = findCssImport;
2012
+ const {
2013
+ ext: ext$2,
2014
+ fileInDir: fileInDir$2,
2015
+ diffContentCopyFile: diffContentCopyFile$2
2016
+ } = io$2;
2017
+ const {
2018
+ resolve: resolve$6
2019
+ } = widgets;
2020
+ const fs$4 = require$$0__default$2;
2021
+ const {
2022
+ pluginError: pluginError$2
2023
+ } = pluginError_1;
2024
+ const cssFilter = ['.less', '.wxss'];
2025
+
2026
+ const dfsFindCommonDep$2 = function (anaFileOriginFile, anaFileDestFile, extensions, isWatch = true) {
2027
+ const resDep = new Map();
2028
+
2029
+ function dfs(anaFileOriginFile, anaFileDestFile, extensions) {
2030
+ let contents = '';
2031
+
2032
+ try {
2033
+ contents = fs$4.readFileSync(anaFileOriginFile, 'utf8');
2034
+ } catch (e) {
2035
+ pluginError$2(e, isWatch);
2036
+ }
2037
+
2038
+ const deps = cssFilter.indexOf(path$3.extname(anaFileOriginFile)) > -1 ? findCssImports(contents) : precinct(contents);
2039
+ deps.forEach(depItem => {
2040
+ if (depItem.startsWith('.')) {
2041
+ // 被依赖文件的存在的绝对路径
2042
+ const depOriginPath = path$3.join(path$3.dirname(anaFileOriginFile), depItem); // 被依赖文件加上后缀
2043
+
2044
+ const {
2045
+ ext: extAlias,
2046
+ file: depOriginFile,
2047
+ extPath
2048
+ } = ext$2(depOriginPath, extensions);
2049
+
2050
+ if (!fs$4.existsSync(depOriginFile)) {
2051
+ pluginError$2(new Error(`${anaFileOriginFile}引用路径${depOriginFile}文件不存在, 请检查应用路径`), isWatch);
2052
+ return;
1422
2053
  }
1423
2054
 
1424
- const entryKey = `${root}/${page}${extValue.ext}`;
1425
- Object.assign(entry, {
1426
- [entryKey]: extValue.file
1427
- }, getComponentEntry(pageJsonContent, pageDir, path$2.dirname(entryKey)));
2055
+ const depDestPath = resolve$6(path$3.dirname(anaFileDestFile), depItem);
2056
+ const depDestFile = depDestPath.endsWith(extAlias) ? depDestPath : depDestPath + extPath;
2057
+
2058
+ if (!resDep.has(depDestFile)) {
2059
+ resDep.set(depDestFile, {
2060
+ anaFileOriginFile,
2061
+ anaFileDestFile,
2062
+ depDestFile,
2063
+ depOriginFile
2064
+ });
2065
+ dfs(depOriginFile, depDestFile, extensions);
2066
+ }
1428
2067
  }
1429
2068
  });
1430
- });
1431
- return entry;
1432
- } // 根据appJson,获取所有的page
2069
+ }
1433
2070
 
2071
+ dfs(anaFileOriginFile, anaFileDestFile, extensions);
2072
+ return resDep;
2073
+ };
2074
+
2075
+ function mpCommonDep$1(tmsConfig, module, extensions = [], isWatch = true) {
2076
+ const stream = through$2.obj(function (file, enc, cb) {
2077
+ // 依赖分析的文件
2078
+ const anaFileOriginFile = file.history[0];
2079
+ const anaFileRelativeModule = path$3.relative(resolve$6(module.from), anaFileOriginFile);
2080
+ const anaFileDestFile = resolve$6(tmsConfig.outputDir, module.to, anaFileRelativeModule);
2081
+
2082
+ if (file.isBuffer()) {
2083
+ let contents = String(file.contents);
2084
+ const deps = cssFilter.indexOf(path$3.extname(file.path)) > -1 ? findCssImports(contents) : precinct(contents);
2085
+ const copyModules = new Map();
2086
+ Object.keys(tmsConfig.dependencies).forEach(includeName => {
2087
+ const includePath = tmsConfig.dependencies[includeName];
2088
+ deps.forEach(depItem => {
2089
+ if (depItem.indexOf(includeName) > -1) {
2090
+ // 被依赖文件的存在的绝对路径 (eg: /User/thirdparty/loadsh)
2091
+ const depOriginPath = path$3.join(path$3.dirname(anaFileOriginFile), depItem); // 被依赖文件加上后缀
2092
+
2093
+ const {
2094
+ ext: extAlias,
2095
+ file: depOriginFile,
2096
+ extPath
2097
+ } = ext$2(depOriginPath, extensions);
2098
+
2099
+ if (!fileInDir$2(includePath, depOriginFile)) {
2100
+ pluginError$2(new Error(`${anaFileOriginFile}引用路径${depOriginFile}不在${includePath}不在文件夹内, 请检查应用路径`), isWatch);
2101
+ return;
2102
+ } // eslint-disable-next-line
2103
+
2104
+
2105
+ const reg = new RegExp(`^(\./|\.\.\/)+.*\/${includeName}\/(.*)`);
2106
+ const regRes = depItem.match(reg) || [];
2107
+
2108
+ if (regRes[2]) {
2109
+ const depDestPath = resolve$6(tmsConfig.outputDir, module.to, includeName, regRes[2]);
2110
+ const depDestFile = depDestPath.endsWith(extAlias) ? depDestPath : depDestPath + extPath;
2111
+
2112
+ if (!copyModules.has(depDestFile)) {
2113
+ copyModules.set(depDestFile, {
2114
+ depOriginFile,
2115
+ depDestFile,
2116
+ beforeDepPath: depItem,
2117
+ afterDepPath: path$3.relative(path$3.dirname(anaFileDestFile), depDestPath).replace(/\\/g, '/')
2118
+ });
2119
+ }
2120
+ }
2121
+ }
2122
+ });
2123
+ }); // console.log('mpCommonDep copyModules', copyModules);
2124
+
2125
+ copyModules.forEach(({
2126
+ depOriginFile,
2127
+ depDestFile,
2128
+ beforeDepPath,
2129
+ afterDepPath
2130
+ }) => {
2131
+ diffContentCopyFile$2(depOriginFile, depDestFile);
2132
+ const reg = new RegExp(`['"]${beforeDepPath}["']`, 'g');
2133
+ contents = contents.replace(reg, `"${afterDepPath}"`);
2134
+ const defs = dfsFindCommonDep$2(depOriginFile, depDestFile, extensions, isWatch);
2135
+ defs.forEach(item => {
2136
+ diffContentCopyFile$2(item.depOriginFile, item.depDestFile);
2137
+ }); // console.log('mpCommonDep defs', defs);
2138
+ });
2139
+ file.contents = Buffer.from(contents);
2140
+ }
1434
2141
 
1435
- function getEntry$2(defaultWebpackEntry, modules, tmsConfig, moduleDir) {
1436
- const defaultEntry = {};
1437
- Object.keys(defaultWebpackEntry).forEach(key => {
1438
- const extValue = ext(defaultWebpackEntry[key], extensions);
1439
- defaultEntry[key + extValue.ext] = extValue.file;
2142
+ this.push(file);
2143
+ cb();
1440
2144
  });
1441
- return { ...defaultEntry,
1442
- ...getPageEntry(modules, tmsConfig, moduleDir)
1443
- };
1444
- } // 根据pageJson,filePath,获取页面引入的所有component
2145
+ return stream;
2146
+ }
1445
2147
 
2148
+ var mpCommonDep_1 = {
2149
+ mpCommonDep: mpCommonDep$1,
2150
+ dfsFindCommonDep: dfsFindCommonDep$2
2151
+ };
1446
2152
 
1447
- function getComponentEntry(pageJson, pagePath, pageKey) {
1448
- const componentEntry = {};
2153
+ /* eslint-disable no-param-reassign */
2154
+ const through$1 = require$$0__default$9;
2155
+ const path$2 = require$$3__default;
2156
+ const {
2157
+ ext: ext$1,
2158
+ fileInDir: fileInDir$1,
2159
+ diffContentCopyFile: diffContentCopyFile$1
2160
+ } = io$2;
2161
+ const {
2162
+ resolve: resolve$5
2163
+ } = widgets;
2164
+ const fs$3 = require$$0__default$2;
2165
+ const {
2166
+ pluginError: pluginError$1
2167
+ } = pluginError_1;
2168
+ const {
2169
+ dfsFindCommonDep: dfsFindCommonDep$1
2170
+ } = mpCommonDep_1;
2171
+
2172
+ function mpJsonDep$1(tmsConfig, module, extensions = ['.json'], filesExt = ['.wxml', '.json', '.js', '.ts', '.wxss', '.less'], isWatch) {
2173
+ const stream = through$1.obj(function (file, enc, cb) {
2174
+ // 当前分析的文件的路径
2175
+ const anaFileOriginFile = file.history[0];
2176
+ const anaFileRelativeModule = path$2.relative(resolve$5(module.from), anaFileOriginFile);
2177
+ const anaFileDestFile = resolve$5(tmsConfig.outputDir, module.to, anaFileRelativeModule);
2178
+
2179
+ if (file.isBuffer()) {
2180
+ let contents = String(file.contents);
2181
+ const copyModules = new Map();
2182
+
2183
+ try {
2184
+ try {
2185
+ contents = contents ? JSON.parse(contents) : {};
2186
+ } catch (e) {
2187
+ throw new Error(`解析${file.path}出现错误,请检查配置信息: ${e}`);
2188
+ }
1449
2189
 
1450
- function task(json, dir, rootKey) {
1451
- if (!json.usingComponents) {
1452
- return;
2190
+ if (contents.usingComponents) {
2191
+ Object.keys(tmsConfig.dependencies).forEach(includeName => {
2192
+ const includePath = tmsConfig.dependencies[includeName];
2193
+ Object.keys(contents.usingComponents).forEach(componentKey => {
2194
+ const componentPath = contents.usingComponents[componentKey];
2195
+
2196
+ if (componentPath.indexOf(includeName) > -1) {
2197
+ const depOriginPath = path$2.join(path$2.dirname(anaFileOriginFile), componentPath); // 被依赖文件加上后缀
2198
+
2199
+ const {
2200
+ ext: extAlias,
2201
+ file: depOriginFile,
2202
+ extPath
2203
+ } = ext$1(depOriginPath, extensions);
2204
+ const isFileInDir = fileInDir$1(includePath, depOriginFile);
2205
+
2206
+ if (!isFileInDir) {
2207
+ pluginError$1(new Error(`${anaFileOriginFile}引用的路径${depOriginFile}不在${includePath}不在文件夹内, 请检查应用路径`), isWatch);
2208
+ return;
2209
+ } // eslint-disable-next-line
2210
+
2211
+
2212
+ const reg = new RegExp(`^(\./\.\.\/)+.*\/${includeName}\/(.*)`);
2213
+ const regRes = componentPath.match(reg) || [];
2214
+
2215
+ if (regRes[2]) {
2216
+ const depDestPath = resolve$5(tmsConfig.outputDir, module.to, includeName, regRes[2]);
2217
+ const depDestFile = depDestPath.endsWith(extAlias) ? depDestPath : depDestPath + extPath;
2218
+
2219
+ if (!copyModules.has(depDestFile)) {
2220
+ copyModules.set(depDestFile, {
2221
+ depOriginFile,
2222
+ depOriginExt: extAlias,
2223
+ depDestFile,
2224
+ beforeDepPath: componentPath,
2225
+ afterDepPath: path$2.relative(path$2.dirname(anaFileDestFile), depDestPath).replace(/\\/g, '/')
2226
+ });
2227
+ }
2228
+ }
2229
+ }
2230
+ });
2231
+ });
2232
+ }
2233
+ } catch (e) {
2234
+ pluginError$1(e, isWatch);
2235
+ } // console.log('json copyModules', copyModules);
2236
+
2237
+
2238
+ copyModules.forEach(({
2239
+ depOriginFile,
2240
+ depOriginExt,
2241
+ depDestFile,
2242
+ beforeDepPath,
2243
+ afterDepPath
2244
+ }) => {
2245
+ // 拷贝当前依赖组件几个部分 wxml、wxss、wxs、json
2246
+ filesExt.forEach(extKey => {
2247
+ const originFile = depOriginFile.replace(depOriginExt, extKey);
2248
+ const destFile = depDestFile.replace(depOriginExt, extKey);
2249
+
2250
+ if (fs$3.existsSync(originFile)) {
2251
+ diffContentCopyFile$1(originFile, destFile);
2252
+ const extensionsFilter = ['.js', '.ts', '.wxss', '.less'];
2253
+
2254
+ if (extensionsFilter.indexOf(extKey) > -1) {
2255
+ const defs = dfsFindCommonDep$1(originFile, destFile, extensionsFilter); // console.log('json defs', defs);
2256
+
2257
+ defs.forEach(item => {
2258
+ diffContentCopyFile$1(item.depOriginFile, item.depDestFile);
2259
+ });
2260
+ }
2261
+ }
2262
+ });
2263
+ contents = typeof contents === 'object' ? JSON.stringify(contents, null, 2) : contents;
2264
+ const reg = new RegExp(`['"]${beforeDepPath}["']`, 'g');
2265
+ contents = contents.replace(reg, `"${afterDepPath}"`);
2266
+ });
2267
+ contents = typeof contents === 'object' ? JSON.stringify(contents, null, 2) : contents;
2268
+ file.contents = Buffer.from(contents);
1453
2269
  }
1454
2270
 
1455
- const componentKeys = Object.keys(json.usingComponents); // 如果存在依赖的组件
1456
-
1457
- componentKeys.forEach(key => {
1458
- if (json.usingComponents[key].startsWith('.')) {
1459
- // 拼出组件所在位置的绝对路径
1460
- const comValue = path$2.join(dir, json.usingComponents[key]);
1461
- const extValue = ext(comValue, extensions);
1462
- const comKey = path$2.resolve('/', rootKey, json.usingComponents[key]);
1463
-
1464
- if (!extValue) {
1465
- fail$4(`当前page: ${pagePath} component: ${comValue}找不到入口.js或.ts文件`);
1466
- process.exit(1);
1467
- }
2271
+ this.push(file);
2272
+ cb();
2273
+ });
2274
+ return stream;
2275
+ }
1468
2276
 
1469
- componentEntry[`${comKey.slice(1)}${extValue.ext}`] = extValue.file;
1470
- const comJsonPath = `${comValue}.json`;
2277
+ var mpJsonDep_1 = {
2278
+ mpJsonDep: mpJsonDep$1
2279
+ };
1471
2280
 
1472
- if (fs$2.existsSync(comJsonPath)) {
1473
- const comJsonContent = JSON.parse(fs$2.readFileSync(comJsonPath, 'utf-8'));
1474
- const comDir = path$2.dirname(comJsonPath); // 该页面所在的目录
2281
+ /* eslint-disable no-param-reassign */
2282
+ const through = require$$0__default$9;
2283
+ const htmlparser2 = require$$1__default$6;
2284
+ const fs$2 = require$$0__default$2;
2285
+ const path$1 = require$$3__default;
2286
+ const {
2287
+ diffContentCopyFile,
2288
+ ext,
2289
+ fileInDir
2290
+ } = io$2;
2291
+ const {
2292
+ resolve: resolve$4
2293
+ } = widgets;
2294
+ const {
2295
+ dfsFindCommonDep
2296
+ } = mpCommonDep_1;
2297
+ const {
2298
+ pluginError
2299
+ } = pluginError_1; // 处理后缀(源码引入依赖时,不带后缀的情况)
2300
+
2301
+ const extFile = function (name, file) {
2302
+ const extMap = {
2303
+ import: '.wxml',
2304
+ include: '.wxml',
2305
+ wxs: '.wxs'
2306
+ };
2307
+ let extObj = {};
1475
2308
 
1476
- task(comJsonContent, comDir, path$2.dirname(comKey));
1477
- }
1478
- }
1479
- });
2309
+ if (Object.keys(extMap).indexOf(name) > -1 && !file.endsWith(extMap[name])) {
2310
+ extObj = ext(file, [extMap[name]]);
1480
2311
  }
1481
2312
 
1482
- task(pageJson, pagePath, pageKey);
1483
- return componentEntry;
1484
- } // 根据modules处理需要拷贝的模块,copy-webpack-plugin需要的参数
2313
+ return {
2314
+ extPath: extObj.extPath || '',
2315
+ ext: extObj.ext || '',
2316
+ file: extObj.file || file
2317
+ };
2318
+ };
1485
2319
 
2320
+ const dfsFindWxmlDep = function (anaFileOriginFile, anaFileDestFile, isWatch = true) {
2321
+ const resDep = {
2322
+ image: new Map(),
2323
+ wxml: new Map(),
2324
+ wxs: new Map()
2325
+ };
1486
2326
 
1487
- function getCopyPlugin$2(defaultCopyConfig, modules, tmsConfig, env) {
1488
- const toPath = tmsConfig.webpack.outputDir;
2327
+ function dfs(anaFileOriginFile, anaFileDestFile) {
2328
+ let contents = '';
1489
2329
 
1490
- function generatorAppJson(tmsConfig, modules) {
1491
2330
  try {
1492
- return buildOutputAppJson(tmsConfig, modules);
2331
+ contents = fs$2.readFileSync(anaFileOriginFile, 'utf8');
1493
2332
  } catch (e) {
1494
- fail$4(`动态生成app.json出现错误${e} 请检查你的配置项`);
1495
- return {};
2333
+ pluginError(e, isWatch);
1496
2334
  }
1497
- }
1498
2335
 
1499
- const patterns = []; // 默认的一些配置拷贝文件 package.json、sitemap.json等
2336
+ const parser = new htmlparser2.Parser({
2337
+ onopentag(name, attributes) {
2338
+ var _attributes$src;
1500
2339
 
1501
- defaultCopyConfig.forEach(item => {
1502
- if (fs$2.existsSync(resolve$5(item))) {
1503
- patterns.push({
1504
- from: resolve$5(item),
1505
- to: resolve$5(`./${toPath}/${item}`),
1506
- transform: {
1507
- cache: true
1508
- }
1509
- });
1510
- }
1511
- }); // 拷贝模块的代码
2340
+ if (attributes !== null && attributes !== void 0 && (_attributes$src = attributes.src) !== null && _attributes$src !== void 0 && _attributes$src.startsWith('.')) {
2341
+ const depOriginPath = path$1.join(path$1.dirname(anaFileOriginFile), attributes.src); // 被依赖文件加上后缀
1512
2342
 
1513
- modules.forEach(item => {
1514
- patterns.push({
1515
- from: resolve$5(item.path),
1516
- to: resolve$5(`./${toPath}/${item.root}`),
1517
- globOptions: {
1518
- ignore: ['**/*.js', '*.js', '**/*.ts', '*.ts']
1519
- },
1520
- transform: {
1521
- cache: true,
1522
- transformer: env === 'dev' ? (content, absoluteFrom) => {
1523
- // 监听module.config.json的修改, 自动生成编译后的app.json
1524
- if (absoluteFrom.indexOf('module.config.json') > -1) {
1525
- generatorAppJson(tmsConfig, modules);
1526
- }
2343
+ const {
2344
+ ext,
2345
+ file: depOriginFile,
2346
+ extPath
2347
+ } = extFile(name, depOriginPath);
1527
2348
 
1528
- return content;
1529
- } : content => content
1530
- }
1531
- });
1532
- });
2349
+ if (!fs$2.existsSync(depOriginFile)) {
2350
+ pluginError(new Error(`${anaFileOriginFile}引用的路径${depOriginFile}找不到应用文件,请检查引用路径`), isWatch);
2351
+ return;
2352
+ }
1533
2353
 
1534
- if (env === 'dev') {
1535
- // 拷贝app.json时,自动生成编译后的app.json
1536
- const appJsonConfig = ['app.json'];
1537
- appJsonConfig.forEach(item => {
1538
- patterns.push({
1539
- from: resolve$5(item),
1540
- to: resolve$5(`./${toPath}/${item}`),
1541
- transform: {
1542
- cache: true,
1543
- transformer: () => {
1544
- const appJson = generatorAppJson(tmsConfig, modules);
1545
- return JSON.stringify(appJson, null, 2);
2354
+ const depDestPath = path$1.join(path$1.dirname(anaFileDestFile), attributes.src);
2355
+ const depDestFile = depDestPath.endsWith(ext) ? depDestPath : depDestPath + extPath; // 收集wxml依赖
2356
+
2357
+ if (['import', 'include'].indexOf(name) > -1) {
2358
+ resDep.wxml.set(depDestFile, {
2359
+ anaFileOriginFile,
2360
+ anaFileDestFile,
2361
+ depDestFile,
2362
+ depOriginFile
2363
+ });
2364
+ dfs(depOriginFile, depDestFile);
2365
+ } // 收集image依赖
2366
+ // if (name === 'image') {
2367
+ // resDep.image.set(attributes.src, {
2368
+ // anaFileOriginFile,
2369
+ // anaFileDestFile,
2370
+ // depDestFile,
2371
+ // depOriginFile,
2372
+ // });
2373
+ // dfs(depOriginFile, depDestFile);
2374
+ // }
2375
+ // 收集wxs依赖
2376
+
2377
+
2378
+ if (name === 'wxs') {
2379
+ resDep.wxs.set(depDestFile, {
2380
+ anaFileOriginFile,
2381
+ anaFileDestFile,
2382
+ depDestFile,
2383
+ depOriginFile
2384
+ });
2385
+ const defs = dfsFindCommonDep(depOriginFile, depDestFile, ['.wxs']);
2386
+ defs.forEach((item, key) => {
2387
+ resDep.wxs.set(key, item);
2388
+ });
1546
2389
  }
1547
2390
  }
1548
- });
2391
+ }
2392
+
1549
2393
  });
2394
+ parser.write(contents);
2395
+ parser.end();
1550
2396
  }
1551
2397
 
1552
- return patterns;
1553
- } // dev时,给webpack注入相应的事件
2398
+ dfs(anaFileOriginFile, anaFileDestFile);
2399
+ return resDep;
2400
+ };
1554
2401
 
2402
+ function mpWxmlDep$1(tmsConfig, module, isWatch) {
2403
+ const stream = through.obj(function (file, enc, cb) {
2404
+ // 依赖分析的文件
2405
+ const anaFileOriginFile = file.history[0];
2406
+ const anaFileRelativeModule = path$1.relative(resolve$4(module.from), anaFileOriginFile);
2407
+ const anaFileDestFile = resolve$4(tmsConfig.outputDir, module.to, anaFileRelativeModule);
2408
+
2409
+ if (file.isBuffer()) {
2410
+ let contents = String(file.contents);
2411
+ const copyModules = new Map();
2412
+ const parser = new htmlparser2.Parser({
2413
+ onopentag(name, attributes) {
2414
+ const nameFilter = ['import', 'include', 'wxs'];
2415
+
2416
+ if (nameFilter.indexOf(name) > -1 && attributes.src) {
2417
+ const depOriginPath = path$1.join(path$1.dirname(anaFileOriginFile), attributes.src); // 处理后缀(源码引入依赖时,后缀不全的情况)
2418
+
2419
+ const {
2420
+ ext,
2421
+ file: depOriginFile,
2422
+ extPath
2423
+ } = extFile(name, depOriginPath);
2424
+ Object.keys(tmsConfig.dependencies).forEach(includeName => {
2425
+ if (attributes.src.indexOf(includeName) > -1) {
2426
+ const includePath = tmsConfig.dependencies[includeName];
2427
+
2428
+ if (!fileInDir(includePath, depOriginFile)) {
2429
+ pluginError(new Error(`${anaFileOriginFile}引用路径${depOriginFile}不在${includePath}不在文件夹内, 请检查应用路径`), isWatch);
2430
+ return;
2431
+ } // eslint-disable-next-line
2432
+
2433
+
2434
+ const reg = new RegExp(`^(\./\.\.\/)+.*\/${includeName}\/(.*)`);
2435
+ const regRes = attributes.src.match(reg) || [];
2436
+
2437
+ if (regRes[2]) {
2438
+ const depDestPath = resolve$4(tmsConfig.outputDir, module.to, includeName, regRes[2]);
2439
+ const depDestFile = depDestPath.endsWith(ext) ? depDestPath : depDestPath + extPath;
2440
+
2441
+ if (!copyModules.has(depDestFile)) {
2442
+ copyModules.set(depDestFile, {
2443
+ depOriginFile,
2444
+ depDestFile,
2445
+ beforeDepPath: attributes.src,
2446
+ afterDepPath: path$1.relative(path$1.dirname(anaFileDestFile), depDestFile).replace(/\\/g, '/')
2447
+ });
2448
+ }
2449
+ }
2450
+ }
2451
+ });
2452
+ }
2453
+ }
1555
2454
 
1556
- const setupDevWebPackHooks$1 = (context, firstDone) => {
1557
- let tempFirstDone = true;
2455
+ });
2456
+ parser.write(contents);
2457
+ parser.end(); // console.log('wxml copyModules', copyModules);
2458
+
2459
+ copyModules.forEach(({
2460
+ depOriginFile,
2461
+ depDestFile,
2462
+ beforeDepPath,
2463
+ afterDepPath
2464
+ }) => {
2465
+ if (fs$2.existsSync(depOriginFile)) {
2466
+ diffContentCopyFile(depOriginFile, depDestFile);
2467
+ const reg = new RegExp(`['"]${beforeDepPath}["']`, 'g');
2468
+ contents = contents.replace(reg, `"${afterDepPath}"`);
2469
+ }
1558
2470
 
1559
- const invalid = () => {
1560
- // eslint-disable-next-line
1561
- context.stats = undefined;
1562
- };
2471
+ if (depOriginFile.endsWith('.wxml')) {
2472
+ const defs = dfsFindWxmlDep(depOriginFile, depDestFile, isWatch); // console.log('wxml defs', defs);
1563
2473
 
1564
- const done = stats => {
1565
- // eslint-disable-next-line
1566
- context.stats = stats;
1567
- process.nextTick(() => {
1568
- const {
1569
- stats
1570
- } = context;
1571
- if (!stats) return;
2474
+ [...defs.wxml, ...defs.wxs].forEach(([, item]) => {
2475
+ diffContentCopyFile(item.depOriginFile, item.depDestFile);
2476
+ });
2477
+ }
1572
2478
 
1573
- if (tempFirstDone) {
1574
- tempFirstDone = false;
1575
- firstDone();
1576
- }
1577
- });
1578
- };
2479
+ if (depOriginFile.endsWith('.wxs')) {
2480
+ const defs = dfsFindCommonDep(depOriginFile, depDestFile, ['.wxs'], isWatch); // console.log('wxs defs', defs);
1579
2481
 
1580
- const {
1581
- compiler
1582
- } = context;
1583
- compiler.hooks.watchRun.tap('miniprogram-dev', invalid);
1584
- compiler.hooks.invalid.tap('miniprogram-dev', invalid);
1585
- compiler.hooks.done.tap('miniprogram-dev', done);
1586
- };
2482
+ defs.forEach(item => {
2483
+ diffContentCopyFile(item.depOriginFile, item.depDestFile);
2484
+ });
2485
+ }
2486
+ });
2487
+ file.contents = Buffer.from(contents);
2488
+ }
1587
2489
 
1588
- const stringified$1 = raw => ({
1589
- 'process.env': Object.keys(raw).reduce((env, key) => {
1590
- // eslint-disable-next-line
1591
- env[key] = JSON.stringify(raw[key]);
1592
- return env;
1593
- }, {})
1594
- });
2490
+ this.push(file);
2491
+ cb();
2492
+ });
2493
+ return stream;
2494
+ }
1595
2495
 
1596
- var utils = {
1597
- getCopyPlugin: getCopyPlugin$2,
1598
- setupDevWebPackHooks: setupDevWebPackHooks$1,
1599
- getEntry: getEntry$2,
1600
- stringified: stringified$1,
1601
- getAlias: getAlias$1
2496
+ var mpWxmlDep_1 = {
2497
+ mpWxmlDep: mpWxmlDep$1,
2498
+ dfsFindWxmlDep
1602
2499
  };
1603
2500
 
1604
- const WebpackChain = require$$0__default$8;
1605
- const webpack$2 = require$$0__default$9;
1606
2501
  const {
1607
- getEntry: getEntry$1,
1608
- stringified,
1609
- getAlias
1610
- } = utils;
2502
+ src: src$1,
2503
+ dest,
2504
+ lastRun
2505
+ } = require$$0__default$a;
2506
+ const px2rpx = require$$1__default$7;
2507
+ const watch = require$$2__default$1; // const cache = require('gulp-cache');
2508
+ // const image = require('gulp-image');
2509
+ // const replaceEnv = require('./plugins/replaceEnv');
2510
+
1611
2511
  const {
1612
- resolve: resolve$4
1613
- } = widgets;
2512
+ mpCommonDep
2513
+ } = mpCommonDep_1;
2514
+ const {
2515
+ mpJsonDep
2516
+ } = mpJsonDep_1;
1614
2517
  const {
1615
- DEFAULT_WEBPACK_ENTRY: DEFAULT_WEBPACK_ENTRY$1,
1616
- DEFAULT_MODULE_DIR: DEFAULT_MODULE_DIR$2
1617
- } = require$$3;
2518
+ mpWxmlDep
2519
+ } = mpWxmlDep_1; // const postcss = require('gulp-postcss');
2520
+ // const base64 = require('./plugins/postcss-font-base64');
1618
2521
 
1619
- var base = (tmsConfig, modules) => {
1620
- const {
1621
- envData = {},
1622
- webpack: tmsWebpack
1623
- } = tmsConfig;
1624
- let webpackConfig = new WebpackChain();
1625
- const alias = getAlias(modules);
1626
- const entry = getEntry$1(DEFAULT_WEBPACK_ENTRY$1, modules, tmsConfig, DEFAULT_MODULE_DIR$2);
1627
- webpackConfig.merge({
1628
- entry,
1629
- output: {
1630
- path: resolve$4(`./${tmsWebpack.outputDir}`),
1631
- libraryTarget: 'commonjs2',
1632
- filename: '[name]'
1633
- },
1634
- // TODO 有报错,先注释掉
1635
- // cache: {
1636
- // type: 'filesystem',
1637
- // cacheDirectory: resolve(`./${tmsConfig.webpack.outputDir}/node_modules/.cache`),
1638
- // },
1639
- resolve: {
1640
- extensions: ['.tsx', '.ts', '.js'],
1641
- alias: Object.assign(tmsWebpack.alias, alias)
1642
- },
1643
- devtool: tmsWebpack.sourceMap ? 'source-map' : false
1644
- });
1645
- webpackConfig.module.rule('ts-loader').test(/\.ts$/).use('ts-loader').loader(require.resolve('ts-loader')).options({
1646
- configFile: resolve$4('./tsconfig.json'),
1647
- // 只进行语法转换,不进行类型校验,提高构建速度
1648
- transpileOnly: true
1649
- }).end(); // webpackConfig.module
1650
- // .rule('babel')
1651
- // .test(/\.(js|mjs|jsx|ts|tsx)$/)
1652
- // .pre()
1653
- // .exclude.add(/(node_modules|miniprogram_npm)/).end()
1654
- // .use(require.resolve('babel-loader'))
1655
- // .loader(require.resolve('babel-loader'));
1656
-
1657
- webpackConfig.plugin('definePlugin').use(webpack$2.DefinePlugin, [stringified(envData)]).end(); // 执行tms.config.js自定义的webpackChain
1658
-
1659
- if (tmsWebpack.webpackChain) {
1660
- webpackConfig = tmsWebpack.webpackChain(webpackConfig, {
1661
- modules
2522
+ const {
2523
+ fail: fail$1
2524
+ } = log$1;
2525
+
2526
+ const since = task => file => lastRun(task) > file.stat.ctime ? lastRun(task) : 0;
2527
+
2528
+ var compile = function (tmsConfig, {
2529
+ glob,
2530
+ destPath,
2531
+ srcOption,
2532
+ module,
2533
+ watchOption = {
2534
+ events: ['change', 'add', 'unlink']
2535
+ },
2536
+ isWatch
2537
+ }) {
2538
+ Object.keys(glob).forEach(globKey => {
2539
+ const globValue = glob[globKey];
2540
+
2541
+ const task = () => src$1(globValue, { ...srcOption,
2542
+ since: since(task)
1662
2543
  });
1663
- }
1664
2544
 
1665
- return webpackConfig;
1666
- };
2545
+ let srcPipe = task();
1667
2546
 
1668
- const SingleEntryPlugin = require$$0__default$a;
1669
- const {
1670
- DEFAULT_WEBPACK_ENTRY,
1671
- DEFAULT_MODULE_DIR: DEFAULT_MODULE_DIR$1
1672
- } = require$$3;
1673
- const {
1674
- getEntry
1675
- } = utils;
2547
+ if (isWatch) {
2548
+ srcPipe = srcPipe.pipe(watch(globValue, watchOption));
2549
+ }
1676
2550
 
1677
- class EntryExtraPlugin {
1678
- constructor(options = {}) {
1679
- this.options = options;
1680
- }
2551
+ switch (globKey) {
2552
+ case 'js':
2553
+ srcPipe // .pipe(replaceEnv(/process\.env(\.(\w*))?/g, tmsConfig.envData))
2554
+ .pipe(mpCommonDep(tmsConfig, module, ['.js', '.ts', '.wxs', '.json'], isWatch)).pipe(dest(destPath)).on('error', err => {
2555
+ fail$1(`js编译报错${err}`);
2556
+ });
2557
+ break;
2558
+
2559
+ case 'wxss':
2560
+ srcPipe.pipe(mpCommonDep(tmsConfig, module, ['.wxss', '.less'], isWatch)).on('error', err => {
2561
+ fail$1(`mpCommonDep编译报错${err}`);
2562
+ }) // .pipe(postcss([base64()]))
2563
+ // .on('error', (err) => {
2564
+ // fail(`postcss编译报错${err}`);
2565
+ // })
2566
+ .pipe(px2rpx({
2567
+ designWidth: 375,
2568
+ // 设计稿宽度,默认为750
2569
+ precision: 2 // 小数最大精度,默认为6
2570
+
2571
+ })).pipe(dest(destPath));
2572
+ break;
2573
+
2574
+ case 'json':
2575
+ srcPipe.pipe(mpJsonDep(tmsConfig, module, ['.json'], ['.wxml', '.json', '.js', '.ts', '.wxss', '.less'], isWatch)).on('error', err => {
2576
+ fail$1(`mpJsonDep编译报错${err}`);
2577
+ }).pipe(dest(destPath));
2578
+ break;
2579
+
2580
+ case 'wxml':
2581
+ srcPipe.pipe(mpWxmlDep(tmsConfig, module, isWatch)).pipe(dest(destPath));
2582
+ break;
2583
+
2584
+ case 'image':
2585
+ srcPipe // .pipe(cache(image()))
2586
+ // .on('error', (err) => {
2587
+ // fail(`image编译报错${err}`);
2588
+ // })
2589
+ .pipe(dest(destPath));
2590
+ break;
2591
+
2592
+ case 'other':
2593
+ srcPipe.pipe(dest(destPath));
2594
+ break;
2595
+ }
2596
+ });
2597
+ };
1681
2598
 
1682
- applyEntry(compiler, entry) {
1683
- const {
1684
- context
1685
- } = compiler.options;
1686
- Object.keys(entry).forEach(key => {
1687
- new SingleEntryPlugin(context, entry[key], key).apply(compiler);
2599
+ (function (module) {
2600
+ const path = require$$3__default;
2601
+ const fs = require$$0__default$2;
2602
+ const watch = require$$2__default$1;
2603
+ const {
2604
+ resolve
2605
+ } = widgets;
2606
+ const {
2607
+ buildOutputAppJson
2608
+ } = buildAppJson;
2609
+ const {
2610
+ DEFAULT_COPY_CONFIG
2611
+ } = require$$4;
2612
+ const compile$1 = compile;
2613
+
2614
+ function excludeGlob(glob) {
2615
+ const otherArr = new Set();
2616
+ otherArr.add('!**/*.{ttf,otf,woff,eot}');
2617
+ Object.keys(glob).forEach(globKey => {
2618
+ if (typeof glob[globKey] === 'string') {
2619
+ const data = glob[globKey].startsWith('!') ? glob[globKey] : `!${glob[globKey]}`;
2620
+ otherArr.add(data);
2621
+ }
2622
+
2623
+ if (Array.isArray(glob[globKey])) {
2624
+ glob[globKey].forEach(value => {
2625
+ if (typeof value === 'string') {
2626
+ const data = value.startsWith('!') ? value : `!${value}`;
2627
+ otherArr.add(data);
2628
+ }
2629
+ });
2630
+ }
1688
2631
  });
2632
+ return Array.from(otherArr);
1689
2633
  }
1690
2634
 
1691
- apply(compiler) {
1692
- const {
1693
- tmsConfig = {},
1694
- modules = []
1695
- } = this.options;
1696
- compiler.hooks.watchRun.tap('EntryExtraPlugin', () => {
1697
- const entry = getEntry(DEFAULT_WEBPACK_ENTRY, modules, tmsConfig, DEFAULT_MODULE_DIR$1);
1698
- this.applyEntry(compiler, entry);
1699
- });
2635
+ function adaptPath(pathDir) {
2636
+ let newPath = pathDir;
2637
+ newPath = newPath.startsWith('/') ? newPath : resolve(newPath);
2638
+ newPath = newPath.endsWith('/') ? newPath.slice(0, newPath.length - 1) : newPath;
2639
+ return newPath;
1700
2640
  }
1701
2641
 
1702
- }
2642
+ module.exports = async (tmsConfig, newModules, isWatch = true) => {
2643
+ // 监听app.json
2644
+ if (isWatch) {
2645
+ watch(resolve('app.json'), {
2646
+ ignoreInitial: false,
2647
+ events: ['add', 'change']
2648
+ }, () => {
2649
+ buildOutputAppJson(tmsConfig, newModules, isWatch);
2650
+ });
2651
+ } else {
2652
+ buildOutputAppJson(tmsConfig, newModules, isWatch);
2653
+ } // 监听根目录的文件
1703
2654
 
1704
- var entryExtractPlugin = EntryExtraPlugin;
1705
2655
 
1706
- const webpackConfig$1 = base;
1707
- const {
1708
- DEFAULT_COPY_CONFIG: DEFAULT_COPY_CONFIG$1
1709
- } = require$$3;
1710
- const {
1711
- getCopyPlugin: getCopyPlugin$1
1712
- } = utils;
2656
+ compile$1(tmsConfig, {
2657
+ glob: {
2658
+ json: DEFAULT_COPY_CONFIG.map(item => resolve(item)) // wxss: ['app.less', 'app.wxss'].map(item => resolve(item)),
2659
+ // js: ['app.js', 'app.ts'].map(item => resolve(item)),
1713
2660
 
1714
- var dev$2 = (...args) => {
1715
- const [tmsConfig, modules] = args;
1716
- const webpackDevConfig = webpackConfig$1(...args);
1717
- webpackDevConfig.devtool('source-map');
1718
- webpackDevConfig.mode('development');
1719
- const copyPluginParams = getCopyPlugin$1(DEFAULT_COPY_CONFIG$1, modules, tmsConfig, 'dev'); // console.log('copyPluginParams', copyPluginParams);
2661
+ },
2662
+ module: {
2663
+ from: '',
2664
+ to: ''
2665
+ },
2666
+ destPath: resolve(tmsConfig.outputDir),
2667
+ srcOption: {
2668
+ allowEmpty: true
2669
+ },
2670
+ isWatch
2671
+ }); // 监听模块的文件
2672
+
2673
+ for (let module of newModules) {
2674
+ // 处理默认参数
2675
+ module = { ...{
2676
+ exclude: []
2677
+ },
2678
+ ...module
2679
+ };
1720
2680
 
1721
- webpackDevConfig.plugin('copy-webpack-plugin').use(require$$3__default, [{
1722
- patterns: copyPluginParams
1723
- }]).end();
1724
- webpackDevConfig.plugin('ExtractPlugin').use(entryExtractPlugin, [{
1725
- tmsConfig,
1726
- modules
1727
- }]).end();
1728
- return webpackDevConfig;
1729
- };
2681
+ if (isWatch) {
2682
+ // 监听模块配置文件
2683
+ watch(`${resolve(module.path)}/**/module.config.json`, {
2684
+ events: ['change']
2685
+ }, () => {
2686
+ buildOutputAppJson(tmsConfig, newModules, isWatch);
2687
+ });
2688
+ }
1730
2689
 
1731
- const webpack$1 = require$$0__default$9;
1732
- const webDevConfig = dev$2;
1733
- const {
1734
- setupDevWebPackHooks
1735
- } = utils;
1736
- const {
1737
- fail: fail$3
1738
- } = log$2;
2690
+ const excludes = module.exclude.map(key => `!${resolve(key)}`);
2691
+ const modulePath = adaptPath(module.path);
2692
+ const glob = {
2693
+ js: [`${modulePath}/**/*.{js,ts,wxs}`, ...excludes],
2694
+ json: [`${modulePath}/**/*.json`, ...excludes],
2695
+ wxss: [`${modulePath}/**/*.{less,wxss}`, ...excludes],
2696
+ wxml: [`${modulePath}/**/*.wxml`, ...excludes],
2697
+ image: [`${modulePath}/**/*.{png,jpg,jpeg,gif,svg}`, ...excludes]
2698
+ };
2699
+ compile$1(tmsConfig, {
2700
+ glob: { ...glob,
2701
+ other: [`${modulePath}/**/*`, ...excludeGlob(glob)]
2702
+ },
2703
+ destPath: resolve(tmsConfig.outputDir, module.root),
2704
+ module: {
2705
+ from: module.path,
2706
+ to: module.root
2707
+ },
2708
+ srcOption: {
2709
+ allowEmpty: true
2710
+ },
2711
+ isWatch
2712
+ });
2713
+ } // 静态资源目录-拷贝
1739
2714
 
1740
- var devServer = (...args) => {
1741
- const config = webDevConfig(...args);
1742
- const compiler = webpack$1(config.toConfig());
1743
- setupDevWebPackHooks({
1744
- compiler
1745
- }, () => {// TODO 判断open参数,打开微信开发者工具
1746
- // openDevtool(api.resolve(config.outputDir || 'dist'))
1747
- });
1748
- compiler.watch({
1749
- aggregateTimeout: 1000,
1750
- poll: undefined
1751
- }, (err, stats) => {
1752
- if (err) {
1753
- fail$3(err);
1754
- console.log('详细的错误信息:', err);
1755
- }
1756
2715
 
1757
- if (stats.hasErrors() || stats.hasWarnings()) {
1758
- console.log(stats.toString({
1759
- // 增加控制台颜色开关
1760
- colors: true
1761
- }));
2716
+ if (tmsConfig !== null && tmsConfig !== void 0 && tmsConfig.static && (tmsConfig === null || tmsConfig === void 0 ? void 0 : tmsConfig.static.length) > 0) {
2717
+ for (const item of tmsConfig.static) {
2718
+ item.from = adaptPath(item.from);
2719
+ item.to = adaptPath(item.to);
2720
+ let glob = {};
2721
+ const ext = path.extname(item.from).slice(1);
2722
+
2723
+ if (ext) {
2724
+ glob[ext] = [item.from];
2725
+ } else {
2726
+ glob = {
2727
+ js: [`${item.from}/**/*.{js,ts,wxs}`],
2728
+ json: [`${item.from}/**/*.json`],
2729
+ wxss: [`${item.from}/**/*.{less,wxss}`],
2730
+ wxml: [`${item.from}/**/*.wxml`],
2731
+ image: [`${item.from}/**/*.{png,jpg,jpeg,gif,svg}`]
2732
+ };
2733
+ glob.other = [`${item.from}/**/*`, ...excludeGlob(glob)];
2734
+ }
2735
+
2736
+ const from = fs.lstatSync(item.from).isFile() ? path.dirname(item.from) : item.from;
2737
+ compile$1(tmsConfig, {
2738
+ glob,
2739
+ destPath: item.to,
2740
+ module: {
2741
+ from,
2742
+ to: item.to
2743
+ },
2744
+ srcOption: {
2745
+ allowEmpty: true
2746
+ },
2747
+ isWatch
2748
+ });
2749
+ }
1762
2750
  }
1763
- });
1764
- return compiler;
1765
- };
2751
+ };
2752
+ })(dev$3);
1766
2753
 
1767
- const fs$1 = require$$0__default$1;
1768
- const semver$1 = require$$1__default$4;
2754
+ const fs$1 = require$$0__default$2;
2755
+ const semver$1 = require$$1__default$8;
1769
2756
  const {
1770
2757
  resolve: resolve$3
1771
2758
  } = widgets;
1772
- const path$1 = require$$1__default$1;
2759
+ const path = require$$3__default;
2760
+ const shelljs$2 = require$$0__default$3;
1773
2761
  const {
1774
- fail: fail$2
1775
- } = log$2;
1776
- const shelljs$2 = require$$0__default$2;
2762
+ handleError
2763
+ } = handleError_1;
1777
2764
 
1778
2765
  const getLatestVersion = npmName => {
1779
2766
  const data = shelljs$2.exec(`npm view ${npmName} version`);
@@ -1794,12 +2781,12 @@ const checkDependencies$1 = (modules, cwd, outputDir) => {
1794
2781
  // 1.1根目录的package.json
1795
2782
 
1796
2783
  const packageArr = [{
1797
- srcPackageDir: path$1.join(cwd, packageJsonName),
2784
+ srcPackageDir: path.join(cwd, packageJsonName),
1798
2785
  destNpmDir: resolve$3(outputDir, 'node_modules')
1799
2786
  }]; // 1.2模块的package.json
1800
2787
 
1801
2788
  modules.forEach(item => {
1802
- const srcPackageDir = path$1.join(cwd, item.path, 'package.json');
2789
+ const srcPackageDir = path.join(cwd, item.path, 'package.json');
1803
2790
 
1804
2791
  if (fs$1.existsSync(srcPackageDir)) {
1805
2792
  packageArr.push({
@@ -1811,25 +2798,25 @@ const checkDependencies$1 = (modules, cwd, outputDir) => {
1811
2798
 
1812
2799
  for (const item of packageArr) {
1813
2800
  const packageJson = fs$1.readFileSync(item.srcPackageDir, 'utf-8');
1814
- let dependencies;
2801
+ let dependencies = {};
1815
2802
 
1816
2803
  try {
1817
- dependencies = JSON.parse(packageJson).dependencies;
2804
+ const json = JSON.parse(packageJson);
2805
+ dependencies = json !== null && json !== void 0 && json.dependencies ? json === null || json === void 0 ? void 0 : json.dependencies : {};
1818
2806
  } catch (e) {
1819
- fail$2(`解析${packageJson}报错,请检查是否是正确的json配置项`);
1820
- process.exit(1);
2807
+ handleError(`解析${item.srcPackageDir}报错,请检查是否是正确的json配置项 ${e}`);
1821
2808
  }
1822
2809
 
1823
2810
  const dependenciesKeys = Object.keys(dependencies);
1824
2811
 
1825
2812
  for (const key of dependenciesKeys) {
1826
- const depPath = path$1.join(item.destNpmDir, key);
2813
+ const depPath = path.join(item.destNpmDir, key);
1827
2814
 
1828
2815
  if (!fs$1.existsSync(depPath)) {
1829
2816
  return true;
1830
2817
  }
1831
2818
 
1832
- const depPackagePath = path$1.join(depPath, 'package.json');
2819
+ const depPackagePath = path.join(depPath, 'package.json');
1833
2820
 
1834
2821
  if (fs$1.existsSync(depPackagePath)) {
1835
2822
  const packageData = require(depPackagePath);
@@ -1856,26 +2843,53 @@ var checkDependencies_1 = {
1856
2843
  checkDependencies: checkDependencies$1
1857
2844
  };
1858
2845
 
1859
- const webpackServer = devServer;
1860
- const fs = require$$0__default$1;
2846
+ const fs = require$$0__default$2;
1861
2847
  const {
1862
2848
  resolve: resolve$2
1863
2849
  } = widgets;
1864
- const init$4 = init$5;
1865
2850
  const {
1866
- DEFAULT_MODULE_DIR
1867
- } = require$$3;
2851
+ MODULE_CONFIG_FILENAME,
2852
+ MODULE_CODE_DIR
2853
+ } = require$$4;
1868
2854
  const {
1869
- tmsModulesMergeLocalModuleCfg
1870
- } = tkitUtils;
2855
+ checkRemoteModGitUrlBranch
2856
+ } = cloneModules_1;
1871
2857
  const {
1872
2858
  checkDependencies
1873
2859
  } = checkDependencies_1;
1874
2860
  const {
1875
- fail: fail$1
1876
- } = log$2;
2861
+ fail
2862
+ } = log$1;
2863
+
2864
+ function checkModule(targetModules, contextDir) {
2865
+ // 判断\源码\dist\是否存在用户指定的模块
2866
+ for (const item of targetModules) {
2867
+ // 此模块没有root字段(原因:没有merge到module.config.json的配置项。第三方模块的代码可能还没有下载)
2868
+ if (!item.root) {
2869
+ return true;
2870
+ } // 判断dist目录是否有该模块
2871
+
2872
+
2873
+ if (!fs.existsSync(`${contextDir}/${item.root}/${MODULE_CONFIG_FILENAME}`)) {
2874
+ return true;
2875
+ } // 判断第三方远程模块git地址与branch是否有更新
2876
+
2877
+
2878
+ if (checkRemoteModGitUrlBranch(MODULE_CODE_DIR, item)) {
2879
+ return true;
2880
+ } // 判断源码目录是否有该模块
2881
+
2882
+
2883
+ if (item.path && !fs.existsSync(resolve$2(item.path))) {
2884
+ fail(`${item.path}模块代码路径不存在, 请检查tms.config.js的${item.name}模块的path`);
2885
+ process.exit(1);
2886
+ }
2887
+ }
1877
2888
 
1878
- function isInit(tmsConfig, targetModules, contextDir) {
2889
+ return false;
2890
+ }
2891
+
2892
+ function isInit$1(tmsConfig, targetModules, contextDir) {
1879
2893
  // 判断是否存在dist目录
1880
2894
  if (!fs.existsSync(contextDir)) {
1881
2895
  return true;
@@ -1894,235 +2908,193 @@ function isInit(tmsConfig, targetModules, contextDir) {
1894
2908
 
1895
2909
  if (!fs.existsSync(`${contextDir}/app.json`)) {
1896
2910
  return true;
1897
- } // 判断\源码\dist\是否存在用户指定的模块
1898
-
1899
-
1900
- for (const item of targetModules) {
1901
- // 此模块没有root字段(原因:没有merge到module.config.json的配置项。第三方模块的代码可能还没有下载)
1902
- if (!item.root) {
1903
- return true;
1904
- } // 判断编译目录是否有该模块
1905
-
1906
-
1907
- if (!fs.existsSync(`${contextDir}/${item.root}`)) {
1908
- return true;
1909
- } // 判断源码目录是否有该模块
2911
+ } // 判断模块信息
1910
2912
 
1911
2913
 
1912
- if (item.path && !fs.existsSync(resolve$2(item.path))) {
1913
- fail$1(`${item.path}模块代码路径不存在, 请检查tms.config.js的${item.name}模块的path`);
1914
- process.exit(1);
1915
- }
2914
+ if (checkModule(targetModules, contextDir)) {
2915
+ return true;
1916
2916
  } // 判断package.json的版本是否有新的版本
1917
2917
 
1918
2918
 
1919
- return checkDependencies(targetModules, resolve$2('./'), tmsConfig.webpack.outputDir);
1920
- }
1921
-
1922
- async function dev$1(tmsConfig, targetModules, env) {
1923
- // tms.config.js的modules 合并 module.config.json的配置项
1924
- let newModules = tmsModulesMergeLocalModuleCfg(targetModules, tmsConfig.appName, DEFAULT_MODULE_DIR); // 判断是否进行init命令
1925
-
1926
- if (isInit(tmsConfig, newModules, resolve$2('dist'))) {
1927
- // init函数会将 最新的tms.config.js的modules 合并 module.config.json的配置项 返回,不需要再做重复工作
1928
- const initData = await init$4(tmsConfig, targetModules);
1929
- newModules = initData.targetModules;
2919
+ if (checkDependencies(targetModules, resolve$2('./'), tmsConfig.outputDir)) {
2920
+ return true;
1930
2921
  }
1931
2922
 
1932
- console.log('当前dev启动的有效模块', newModules.map(item => item.name));
1933
- webpackServer(tmsConfig, newModules, env);
2923
+ return false;
1934
2924
  }
1935
2925
 
1936
- var dev_1 = dev$1;
1937
-
1938
- const webpackConfig = base;
1939
- const {
1940
- DEFAULT_COPY_CONFIG
1941
- } = require$$3;
1942
- const {
1943
- getCopyPlugin
1944
- } = utils;
1945
-
1946
- var build$2 = (...args) => {
1947
- const [tmsConfig, modules] = args;
1948
- const webpackBuildConfig = webpackConfig(...args);
1949
- webpackBuildConfig.mode('production');
1950
- const copyPluginParams = getCopyPlugin(DEFAULT_COPY_CONFIG, modules, tmsConfig, 'build'); // console.log('copyPluginParams', copyPluginParams);
1951
-
1952
- webpackBuildConfig.plugin('copy-webpack-plugin').use(require$$3__default, [{
1953
- patterns: copyPluginParams
1954
- }]).end();
1955
- return webpackBuildConfig;
2926
+ var isInIt = {
2927
+ isInit: isInit$1
1956
2928
  };
1957
2929
 
1958
- const webpack = require$$0__default$9;
1959
- const webBuildConfig = build$2;
2930
+ const shelljs$1 = require$$0__default$3;
2931
+ const compileDev = dev$3.exports;
1960
2932
  const {
1961
- createTask: createTask$2
2933
+ resolve: resolve$1
1962
2934
  } = widgets;
2935
+ const init$4 = init_1;
1963
2936
  const {
1964
- fail
1965
- } = log$2;
1966
-
1967
- function compilerRun(compiler) {
1968
- return new Promise(resolve => {
1969
- compiler.run((err, stats) => {
1970
- resolve({
1971
- err,
1972
- stats
1973
- });
1974
- });
2937
+ isInit
2938
+ } = isInIt;
2939
+ const {
2940
+ tmsModulesMergeLocalModuleCfg: tmsModulesMergeLocalModuleCfg$1
2941
+ } = tmsMpconfig;
2942
+ const {
2943
+ info: info$2
2944
+ } = log$1;
2945
+ const {
2946
+ global: global$1
2947
+ } = global_1; // 用户编译分包时,需要将dist中其他分包(主包不能删除)的内容删除,否则其他分包的内容混入到主包(导致主包的体积超2M)
2948
+
2949
+ function delOtherModule(tmsConfig, targetModules) {
2950
+ const modules = tmsModulesMergeLocalModuleCfg$1(tmsConfig.modules, tmsConfig.appName);
2951
+ const targetModulesName = targetModules.map(item => item.name);
2952
+ modules.forEach(item => {
2953
+ if (item.root && targetModulesName.indexOf(item.name) === -1) {
2954
+ const moduleRootDir = resolve$1(`dist/${item.root}`);
2955
+ shelljs$1.rm('-rf', `${moduleRootDir}/*`, {
2956
+ silent: true
2957
+ }); // 解决微信开发者工具(dist/app.json: ["subpackages"][0]["root"] 字段需为 目录)错误 - 提前创建该目录
2958
+ // io.ensureDirExist(moduleRootDir);
2959
+ }
1975
2960
  });
1976
2961
  }
1977
2962
 
1978
- var buildServer = async (...args) => {
1979
- const config = webBuildConfig(...args);
1980
- const compiler = webpack(config.toConfig());
1981
- const {
1982
- err,
1983
- stats
1984
- } = await createTask$2(compilerRun, '开始webpack打包编译', 'webpack打包编译完成')(compiler);
2963
+ async function dev$2(tmsConfig, targetModules, env) {
2964
+ let newModules = targetModules;
2965
+ const isLatest = global$1.getData('cmd').latest; // 判断是否进行init命令
1985
2966
 
1986
- if (err) {
1987
- fail(err);
1988
- console.log('详细的错误信息:', err);
2967
+ if (isLatest || isInit(tmsConfig, targetModules, resolve$1('dist'))) {
2968
+ // init函数 下载第三方代码后,会将最新的tms.config.js的modules 合并 module.config.json的配置项返回
2969
+ const initData = await init$4(tmsConfig, newModules);
2970
+ newModules = initData.targetModules;
1989
2971
  }
1990
2972
 
1991
- if (stats.hasErrors() || stats.hasWarnings()) {
1992
- console.log(stats.toString({
1993
- // 增加控制台颜色开关
1994
- colors: true,
1995
- errorDetails: true
1996
- }));
1997
- }
1998
- return compiler;
2973
+ info$2('当前dev启动的有效模块', newModules.map(item => item.name).sort());
2974
+ delOtherModule(tmsConfig, newModules);
2975
+ compileDev(tmsConfig, newModules, env);
2976
+ }
2977
+
2978
+ var dev_1 = dev$2;
2979
+
2980
+ const dev$1 = dev$3.exports;
2981
+
2982
+ var build$2 = async (tmsConfig, newModules) => {
2983
+ dev$1(tmsConfig, newModules, false);
1999
2984
  };
2000
2985
 
2001
- const shelljs$1 = require$$0__default$2;
2002
- const webpackBuildServer = buildServer;
2986
+ const shelljs = require$$0__default$3;
2003
2987
  const {
2004
- resolve: resolve$1
2988
+ resolve
2005
2989
  } = widgets;
2006
- const init$3 = init$5;
2990
+ const init$3 = init_1;
2991
+ const compileBuild = build$2;
2007
2992
 
2008
2993
  async function build$1(tmsConfig, targetModules, env) {
2009
2994
  // 开始构建前,清理输出目录
2010
- await shelljs$1.rm('-rf', resolve$1('dist'));
2995
+ await shelljs.rm('-rf', resolve(tmsConfig.outputDir));
2011
2996
  const {
2012
2997
  targetModules: newModules
2013
2998
  } = await init$3(tmsConfig, targetModules);
2014
- webpackBuildServer(tmsConfig, newModules, env);
2999
+ compileBuild(tmsConfig, newModules, env);
2015
3000
  }
2016
3001
 
2017
3002
  var build_1 = build$1;
2018
3003
 
2019
- const shelljs = require$$0__default$2;
2020
- const {
2021
- createTask: createTask$1
2022
- } = widgets;
2023
- const {
2024
- buildMpNpm
2025
- } = mpCiUtils;
2026
- const glob = require$$3__default$1;
2027
- const path = require$$1__default$1;
2028
-
2029
- function npmInstall(contextDir) {
2030
- return new Promise((resolve, reject) => {
2031
- glob(`${contextDir}/**/package.json`, ['node_modules', 'miniprogram_npm'], (err, files) => {
2032
- if (err) {
2033
- reject(err);
2034
- }
2035
-
2036
- files.forEach(file => {
2037
- const dir = path.dirname(file);
2038
- shelljs.cd(dir);
2039
- shelljs.exec('npx pnpm install --prod --registry http://mirrors.tencent.com/npm/', {
2040
- silent: false
2041
- });
2042
- });
2043
- resolve();
2044
- });
2045
- });
2046
- }
2047
-
2048
- async function install$1(contextDir) {
2049
- // npm install
2050
- await createTask$1(npmInstall, '开始npm install', 'npm install完成')(contextDir); // 构建miniprograme_npm
2051
-
2052
- await createTask$1(buildMpNpm, '开始构建miniprogram_npm', '构建miniprogram_npm 完成')({
2053
- appId: 'null',
2054
- projectPath: contextDir,
2055
- privateKey: 'null'
2056
- });
2057
- }
2058
-
2059
- var install_1 = install$1;
2060
-
2061
- const init$2 = init$5;
3004
+ const init$2 = init_1;
2062
3005
  const dev = dev_1;
2063
3006
  const build = build_1;
2064
3007
  const install = install_1;
2065
3008
  const {
2066
- createTask,
2067
- resolve
2068
- } = widgets;
2069
- const {
2070
- MODE
2071
- } = require$$3;
3009
+ global
3010
+ } = global_1;
2072
3011
  const {
2073
3012
  readTmsConfig,
2074
- checkModules
2075
- } = tkitUtils;
3013
+ readTmsPrivateCf,
3014
+ checkModules,
3015
+ tmsModulesMergeLocalModuleCfg,
3016
+ subModulesMergeDepModules
3017
+ } = tmsMpconfig;
3018
+
3019
+ const handleModuleArg = cmd => {
3020
+ // 单模块或多模块开发-用户通过脚手架参数指定的模块
3021
+ if (typeof cmd.module === 'string') {
3022
+ return cmd.module.split(',');
3023
+ }
3024
+
3025
+ return [];
3026
+ };
3027
+ /**
3028
+ * 获取用户指定要跑的模块
3029
+ * @param {Array} moduleArg 参数指定的模块
3030
+ * @param {Object} modulePrivateCfg 私有配置里的模块
3031
+ * @param {Array} moduleAll 当前小程序全部模块
3032
+ */
2076
3033
 
2077
- const handleModulesArg = cmd => {
2078
- // 主模块开发
2079
- if (cmd.module === MODE.main) {
2080
- return MODE.main;
2081
- } // 单模块 或 多模块开发
2082
3034
 
3035
+ const getSpecificModules = (moduleArg, modulePrivateCfg, moduleAll) => {
3036
+ if (moduleArg.length > 0) {
3037
+ return moduleArg;
3038
+ } // 单模块或多模块开发-用户在tms.private.js指定的模块
2083
3039
 
2084
- if (cmd.module) {
2085
- return [cmd.module, ...cmd.args];
2086
- } // 全量模块
2087
3040
 
3041
+ if (modulePrivateCfg) {
3042
+ var _modulePrivateCfg$inc, _modulePrivateCfg$exc;
2088
3043
 
2089
- return MODE.all;
2090
- };
3044
+ if (((_modulePrivateCfg$inc = modulePrivateCfg.include) === null || _modulePrivateCfg$inc === void 0 ? void 0 : _modulePrivateCfg$inc.length) > 0) {
3045
+ return modulePrivateCfg.include;
3046
+ }
2091
3047
 
2092
- async function run(commandName, cmd) {
2093
- if (commandName === 'install') {
2094
- install(resolve('./'));
2095
- return;
3048
+ if (((_modulePrivateCfg$exc = modulePrivateCfg.exclude) === null || _modulePrivateCfg$exc === void 0 ? void 0 : _modulePrivateCfg$exc.length) > 0) {
3049
+ return moduleAll.filter(module => !modulePrivateCfg.exclude.includes(module.name)).map(item => item.name);
3050
+ }
3051
+
3052
+ if (modulePrivateCfg.blockRemote === true) {
3053
+ return moduleAll.filter(module => module.repoInfo === undefined).map(item => item.name);
3054
+ }
2096
3055
  }
2097
3056
 
2098
- const moduleArg = handleModulesArg(cmd);
3057
+ return moduleAll.map(item => item.name);
3058
+ };
3059
+
3060
+ async function run(commandName, cmd) {
3061
+ // 用户本地的私有项目配置(用来配置环境\模块信息\账号信息)
3062
+ const tmsPrivateCf = readTmsPrivateCf();
2099
3063
  const {
2100
- env
3064
+ env = tmsPrivateCf === null || tmsPrivateCf === void 0 ? void 0 : tmsPrivateCf.env
2101
3065
  } = cmd;
2102
- const tmsConfig = await createTask(readTmsConfig, '开始读取脚手架的配置项', '读取脚手架的配置项完成')(env);
2103
- let modules; // 主模块
2104
-
2105
- if (moduleArg === MODE.main) {
2106
- modules = checkModules(tmsConfig, [...new Set([...tmsConfig.mainPackages])]);
2107
- } else if (moduleArg === MODE.all) {
2108
- // 全量模块
2109
- modules = tmsConfig.modules;
2110
- } else {
2111
- // 检查用户输入modules的有效性
2112
- modules = checkModules(tmsConfig, [...new Set([...tmsConfig.mainPackages, ...moduleArg])]);
2113
- }
3066
+ const tmsConfig = readTmsConfig(env); // 处理module参数
3067
+
3068
+ const specificModules = getSpecificModules(handleModuleArg(cmd), tmsPrivateCf.modules, tmsConfig.modules);
3069
+ const modules = checkModules(tmsConfig, [...new Set([...tmsConfig.mainPackages, ...specificModules])]); // tms.config.js的modules 合并 module.config.json的配置项
3070
+
3071
+ let newModules = tmsModulesMergeLocalModuleCfg(modules, tmsConfig.appName); // A分包依赖了B分包的代码, merge B分包进行编译;
3072
+
3073
+ newModules = subModulesMergeDepModules(tmsConfig, newModules); // 缓存数据
3074
+
3075
+ global.setData({
3076
+ env,
3077
+ cmd,
3078
+ tmsPrivateCf
3079
+ });
2114
3080
 
2115
3081
  switch (commandName) {
2116
3082
  case 'init':
2117
- init$2(tmsConfig, modules, env);
3083
+ init$2(tmsConfig, newModules, env);
2118
3084
  return;
2119
3085
 
2120
3086
  case 'dev':
2121
- dev(tmsConfig, modules, env);
3087
+ global.setData('isDev', true);
3088
+ dev(tmsConfig, newModules, env);
3089
+ return;
3090
+
3091
+ case 'install':
3092
+ install(tmsConfig, newModules, env);
2122
3093
  return;
2123
3094
 
2124
3095
  case 'build':
2125
- build(tmsConfig, modules, env);
3096
+ global.setData('isDev', false);
3097
+ build(tmsConfig, newModules, env);
2126
3098
  return;
2127
3099
 
2128
3100
  default:
@@ -2139,22 +3111,59 @@ var entry = [{
2139
3111
  create_1(appName, cmd);
2140
3112
  }
2141
3113
  }, {
2142
- command: 'run <command-name>',
2143
- options: [['-m, --module [moduleName]', '模块名称'], ['-e, --env [env]', '环境变量']],
2144
- description: '运行模块',
2145
- action: (commandName, cmd) => {
2146
- run_1(commandName, cmd);
2147
- }
3114
+ name: 'run',
3115
+ type: 'child',
3116
+ description: '项目开发使用的命令',
3117
+ commands: [{
3118
+ command: 'install',
3119
+ description: '安装依赖',
3120
+ options: [['-m, --module [moduleName]', '模块名称'], ['-e, --env [env]', '环境变量']],
3121
+ action: cmd => {
3122
+ run_1('install', cmd);
3123
+ }
3124
+ }, {
3125
+ command: 'dev',
3126
+ description: 'dev 打包编译',
3127
+ options: [['-m, --module [moduleName]', '模块名称'], ['-e, --env [env]', '环境变量'], ['-latest, --latest', '下载最新第三方模块代码、安装最新依赖']],
3128
+ action: cmd => {
3129
+ run_1('dev', cmd);
3130
+ }
3131
+ }, {
3132
+ command: 'build',
3133
+ description: 'prod 打包编译',
3134
+ options: [['-m, --module [moduleName]', '模块名称'], ['-e, --env [env]', '环境变量']],
3135
+ action: cmd => {
3136
+ run_1('build', cmd);
3137
+ }
3138
+ } // 对外暂不暴露该命令
3139
+ // {
3140
+ // command: 'init',
3141
+ // description: '模块配置初始化项目(eg: 下载第三方模块代码、安装依赖、生成app.json等)',
3142
+ // options: [
3143
+ // ['-m, --module [moduleName]', '模块名称'],
3144
+ // ['-e, --env [env]', '环境变量'],
3145
+ // ],
3146
+ // action: (cmd) => {
3147
+ // require('./scripts/run/index')('init', cmd);
3148
+ // },
3149
+ // },
3150
+ ]
2148
3151
  }];
2149
3152
 
2150
- var require$$6 = {
3153
+ var require$$7 = {
2151
3154
  name: "@tmsfe/tmskit",
2152
- version: "0.0.5",
3155
+ version: "0.0.8",
2153
3156
  description: "tmskit",
2154
- main: "main.js",
3157
+ main: "dist/index.cjs",
2155
3158
  bin: {
2156
3159
  tmskit: "main.js"
2157
3160
  },
3161
+ files: [
3162
+ "src",
3163
+ "dist",
3164
+ "main.js",
3165
+ "package.json"
3166
+ ],
2158
3167
  scripts: {
2159
3168
  dev: "rollup -wc --environment TARGET:tmskit",
2160
3169
  build: "rollup -c --environment TARGET:tmskit"
@@ -2180,40 +3189,47 @@ var require$$6 = {
2180
3189
  dependencies: {
2181
3190
  async: "^3.2.2",
2182
3191
  chalk: "^4.1.0",
2183
- commander: "^6.2.1",
3192
+ commander: "^8.3.0",
2184
3193
  "copy-webpack-plugin": "^9.1.0",
2185
- "download-git-repo": "^3.0.2",
2186
3194
  ejs: "^3.1.5",
3195
+ "fs-extra": "^10.0.1",
2187
3196
  "glob-ignore": "^1.0.2",
3197
+ gulp: "^4.0.2",
3198
+ "gulp-cache": "^1.1.3",
3199
+ "gulp-postcss": "^9.0.1",
3200
+ "gulp-px-to-rpx": "^1.0.7",
3201
+ "gulp-watch": "^5.0.1",
3202
+ htmlparser2: "^7.2.0",
2188
3203
  inquirer: "^7.3.3",
2189
3204
  leven: "3.1.0",
2190
3205
  lodash: "^4.17.21",
2191
3206
  metalsmith: "^2.3.0",
2192
3207
  "miniprogram-ci": "1.4.13",
3208
+ "object-assign": "^4.0.1",
2193
3209
  ora: "^5.1.0",
3210
+ "plugin-error": "^1.0.0",
3211
+ postcss: "^8.4.6",
3212
+ precinct: "^8.3.1",
2194
3213
  "replace-ext": "^2.0.0",
2195
3214
  shelljs: "^0.8.4",
2196
- "ts-loader": "^9.2.6",
2197
- webpack: "^5.64.0",
2198
- "webpack-chain": "^6.5.1"
3215
+ "strip-comments": "^2.0.1",
3216
+ through2: "^4.0.2",
3217
+ "vinyl-sourcemaps-apply": "^0.2.0"
2199
3218
  },
2200
3219
  engines: {
2201
- node: "^12.17.0 || >= 14.0.0"
3220
+ node: "^12.17.0 || >= 14.13.1"
2202
3221
  },
2203
3222
  jest: {
2204
3223
  testEnvironment: "jest-environment-node"
2205
3224
  }
2206
3225
  };
2207
3226
 
3227
+ const semver = require$$1__default$8;
3228
+ const packageJson = require$$7;
3229
+ const chalk$1 = require$$0__default;
2208
3230
  const {
2209
- exec
2210
- } = require$$0__default$2;
2211
- const semver = require$$1__default$4;
2212
- const packageJson = require$$6;
2213
- const chalk$1 = require$$0__default$3;
2214
- const {
2215
- log: log$1
2216
- } = widgets;
3231
+ info: info$1
3232
+ } = log$1;
2217
3233
  const requiredVersion = packageJson.engines.node;
2218
3234
  const packName = packageJson.name;
2219
3235
  /**
@@ -2227,7 +3243,7 @@ const checkNodeVersion = (wanted, id) => {
2227
3243
  if (!semver.satisfies(process.version, wanted, {
2228
3244
  includePrerelease: true
2229
3245
  })) {
2230
- log$1(chalk$1.red(`你正在使用的Node版本: ${process.version}, 但是此版本的 ${id} 需要的Node最小版本 ${wanted}.\n请先升级你的Node版本.`));
3246
+ info$1(chalk$1.red(`你正在使用的Node版本: ${process.version}, 但是此版本的 ${id} 需要的Node最小版本 ${wanted}.\n请先升级你的Node版本.`));
2231
3247
  process.exit(1);
2232
3248
  }
2233
3249
  };
@@ -2240,47 +3256,59 @@ const checkNodeVersion = (wanted, id) => {
2240
3256
  function initCliContext() {
2241
3257
  // 执行操作前检查node版本
2242
3258
  // 旧版本node直接提示升级,退出脚本
2243
- checkNodeVersion(requiredVersion, packName); // 执行前配置正确的npm源
2244
-
2245
- exec('npm config set registry https://mirrors.tencent.com/npm/ --global', {
2246
- silent: true
2247
- });
3259
+ checkNodeVersion(requiredVersion, packName);
2248
3260
  }
2249
3261
 
2250
3262
  var init$1 = initCliContext;
2251
3263
 
2252
- const chalk = require$$0__default$3;
2253
- const program = require$$0__default;
3264
+ const chalk = require$$0__default;
3265
+ const commander = require$$0__default$1;
2254
3266
  const {
2255
- log,
2256
3267
  suggestCommands
2257
3268
  } = widgets;
3269
+ const {
3270
+ info
3271
+ } = log$1;
2258
3272
  const {
2259
3273
  TMS_NAME
2260
- } = require$$3;
3274
+ } = require$$4;
2261
3275
  const commands = entry;
2262
3276
  const init = init$1;
2263
3277
  init();
2264
- program.version(`${TMS_NAME} ${require$$6.version}`);
2265
- commands.forEach(cmd => {
2266
- var _cmd$options;
2267
-
2268
- const command = program.command(cmd.command);
2269
- cmd.usage && command.usage(cmd.usage);
2270
- cmd.description && command.description(cmd.description);
2271
- (_cmd$options = cmd.options) === null || _cmd$options === void 0 ? void 0 : _cmd$options.forEach(opt => command.option(...opt));
2272
- command.action(cmd.action);
2273
- });
3278
+ const program = new commander.Command(TMS_NAME);
3279
+ program.version(`${TMS_NAME} ${require$$7.version}`, '-v, -V, --version');
3280
+
3281
+ function registerCommand(program, commands) {
3282
+ commands.forEach(cmd => {
3283
+ if (cmd.type === 'child') {
3284
+ const childProgram = new commander.Command(cmd.name);
3285
+ cmd.usage && childProgram.usage(cmd.usage);
3286
+ cmd.description && childProgram.description(cmd.description);
3287
+ registerCommand(childProgram, cmd.commands);
3288
+ program.addCommand(childProgram);
3289
+ } else {
3290
+ var _cmd$options;
3291
+
3292
+ const command = program.command(cmd.command);
3293
+ cmd.usage && command.usage(cmd.usage);
3294
+ cmd.description && command.description(cmd.description);
3295
+ (_cmd$options = cmd.options) === null || _cmd$options === void 0 ? void 0 : _cmd$options.forEach(opt => command.option(...opt));
3296
+ command.action(cmd.action);
3297
+ }
3298
+ });
3299
+ }
3300
+
3301
+ registerCommand(program, commands);
2274
3302
  program.on('--help', () => {
2275
- log();
2276
- log(` Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
2277
- log();
3303
+ info();
3304
+ info(` Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
3305
+ info();
2278
3306
  }); // 捕获未注册的命令
2279
3307
 
2280
3308
  program.arguments('<command>').action(cmd => {
2281
3309
  program.outputHelp();
2282
- log(` ${chalk.red(`Unknown command ${chalk.yellow(cmd)}.`)}`);
2283
- log();
3310
+ info(` ${chalk.red(`Unknown command ${chalk.yellow(cmd)}.`)}`);
3311
+ info();
2284
3312
  suggestCommands(cmd);
2285
3313
  process.exitCode = 1;
2286
3314
  });
@@ -2291,6 +3319,6 @@ if (!process.argv.slice(2).length) {
2291
3319
  }
2292
3320
 
2293
3321
  program.parse(process.argv);
2294
- var src = src$1;
3322
+ var src = src$2;
2295
3323
 
2296
3324
  module.exports = src;