@tmsfe/tmskit 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +18 -2
  2. package/dist/index.cjs.js +1852 -1050
  3. package/package.json +24 -6
  4. package/src/config/constant.js +5 -2
  5. package/src/config/defaultTmsConfig.js +9 -10
  6. package/src/entry.js +48 -8
  7. package/src/gulp/build.js +5 -0
  8. package/src/gulp/compile.js +87 -0
  9. package/src/gulp/dev.js +102 -0
  10. package/src/gulp/plugins/less.js +116 -0
  11. package/src/gulp/plugins/mpCommonDep.js +131 -0
  12. package/src/gulp/plugins/mpJsonDep.js +108 -0
  13. package/src/gulp/plugins/mpWxmlDep.js +194 -0
  14. package/src/gulp/plugins/postcss-font-base64.js +72 -0
  15. package/src/gulp/plugins/replaceEnv.js +29 -0
  16. package/src/gulp/plugins/utils/pluginError.js +25 -0
  17. package/src/index.js +24 -9
  18. package/src/init.js +0 -5
  19. package/src/scripts/run/build/index.js +5 -4
  20. package/src/scripts/run/dev/index.js +30 -13
  21. package/src/scripts/run/index.js +30 -25
  22. package/src/scripts/run/init/index.js +31 -41
  23. package/src/scripts/run/install/index.js +19 -29
  24. package/src/utils/buildAppJson.js +100 -23
  25. package/src/utils/checkDependencies.js +6 -6
  26. package/src/utils/cloneModules.js +39 -13
  27. package/src/utils/findCssImport.js +30 -0
  28. package/src/utils/handleError.js +16 -0
  29. package/src/utils/io.js +85 -0
  30. package/src/utils/mpCiUtils.js +0 -1
  31. package/src/utils/npmUtils.js +77 -37
  32. package/src/utils/tkitUtils.js +90 -16
  33. package/src/utils/widgets.js +11 -14
  34. package/CHANGELOG.md +0 -0
  35. package/rollup.config.js +0 -179
  36. package/src/webpack/base.js +0 -65
  37. package/src/webpack/build.js +0 -21
  38. package/src/webpack/buildServer.js +0 -34
  39. package/src/webpack/dev.js +0 -31
  40. package/src/webpack/devServer.js +0 -37
  41. package/src/webpack/plugins/entryExtractPlugin/index.js +0 -28
  42. package/src/webpack/utils.js +0 -244
@@ -2,58 +2,63 @@ const init = require('./init/index');
2
2
  const dev = require('./dev/index');
3
3
  const build = require('./build/index');
4
4
  const install = require('./install/index');
5
- const { createTask, resolve } = require('../../utils/widgets');
5
+ const { createTask } = require('../../utils/widgets');
6
6
  const { MODE } = require('../../config/constant');
7
- const { readTmsConfig, checkModules } = require('../../utils/tkitUtils');
7
+ const { readTmsConfig, readTmsPrivateCf, checkModules } = require('../../utils/tkitUtils');
8
+ const { tmsModulesMergeLocalModuleCfg, subModulesMergeDepModules } = require('../../utils/tkitUtils');
8
9
 
9
- const handleModulesArg = (cmd) => {
10
- // 主模块开发
11
- if (cmd.module === MODE.main) {
12
- return MODE.main;
13
- }
14
- // 单模块 或 多模块开发
10
+ const handleModulesArg = (cmd, tmsPrivateCg) => {
11
+ // 单模块或多模块开发-用户通过脚手架参数指定的模块
15
12
  if (cmd.module) {
13
+ const { argv } = process;
14
+ const reset = argv.indexOf('-m') > -1 ? argv.slice(argv.indexOf('-m') + 1) : [];
16
15
  return [
17
16
  cmd.module,
18
- ...cmd.args,
17
+ ...reset,
19
18
  ];
20
19
  }
20
+ // 单模块或多模块开发-用户在tms.private.js指定的模块
21
+ if (tmsPrivateCg?.modules && tmsPrivateCg?.modules.length > 0) {
22
+ return tmsPrivateCg?.modules;
23
+ }
21
24
  // 全量模块
22
25
  return MODE.all;
23
26
  };
24
27
 
25
28
  async function run(commandName, cmd) {
26
- if (commandName === 'install') {
27
- install(resolve('./'));
28
- return;
29
- }
30
-
31
- const moduleArg = handleModulesArg(cmd);
32
- const { env } = cmd;
33
-
29
+ // 用户本地的私有项目配置(用来配置环境\模块信息\账号信息)
30
+ const tmsPrivateCg = readTmsPrivateCf();
31
+ // 处理module参数
32
+ const moduleArg = handleModulesArg(cmd, tmsPrivateCg);
33
+ const { env = tmsPrivateCg?.env } = cmd;
34
34
  const tmsConfig = await createTask(readTmsConfig, '开始读取脚手架的配置项', '读取脚手架的配置项完成')(env);
35
35
 
36
36
  let modules;
37
- // 主模块
38
- if (moduleArg === MODE.main) {
39
- modules = checkModules(tmsConfig, [...new Set([...tmsConfig.mainPackages])]);;
40
- } else if (moduleArg === MODE.all) {
37
+ if (moduleArg === MODE.all) {
41
38
  // 全量模块
42
39
  modules = tmsConfig.modules;
43
40
  } else {
44
41
  // 检查用户输入modules的有效性
45
- modules = checkModules(tmsConfig, [...new Set([...tmsConfig.mainPackages, ...moduleArg])]);;
42
+ modules = checkModules(tmsConfig, [...new Set([...tmsConfig.mainPackages, ...moduleArg])]);
46
43
  }
47
44
 
45
+ // tms.config.js的modules 合并 module.config.json的配置项
46
+ let newModules = tmsModulesMergeLocalModuleCfg(modules, tmsConfig.appName);
47
+ // A分包依赖了B分包的代码, merge B分包进行编译;
48
+ newModules = subModulesMergeDepModules(tmsConfig, newModules);
49
+
48
50
  switch (commandName) {
49
51
  case 'init':
50
- init(tmsConfig, modules, env);
52
+ init(tmsConfig, newModules, env);
51
53
  return;
52
54
  case 'dev':
53
- dev(tmsConfig, modules, env);
55
+ dev(tmsConfig, newModules, env);
56
+ return;
57
+ case 'install':
58
+ install(tmsConfig, newModules, env);
54
59
  return;
55
60
  case 'build':
56
- build(tmsConfig, modules, env);
61
+ build(tmsConfig, newModules, env);
57
62
  return;
58
63
  default:
59
64
  return;
@@ -3,58 +3,53 @@ const fs = require('fs');
3
3
  const io = require('../../../utils/io');
4
4
  const { resolve, createTask } = require('../../../utils/widgets');
5
5
  const { buildOutputAppJson } = require('../../../utils/buildAppJson');
6
- const { npmInstallAll } = require('../../../utils/npmUtils');
7
- const { buildMpNpm } = require('../../../utils/mpCiUtils');
8
- const { MODULE_CODE_DIR, CACHE_DIR, DEFAULT_COPY_CONFIG, DEFAULT_MODULE_DIR } = require('../../../config/constant');
6
+ const { MODULE_CODE_DIR, DEFAULT_COPY_CONFIG } = require('../../../config/constant');
9
7
  const { cloneModules } = require('../../../utils/cloneModules');
10
- const { tmsModulesMergeLocalModuleCfg } = require('../../../utils/tkitUtils');
8
+ const { tmsModulesMergeLocalModuleCfg, subModulesMergeDepModules } = require('../../../utils/tkitUtils');
11
9
  const { fail } = require('../../../utils/log');
10
+ const install = require('../install');
12
11
 
13
12
  /**
14
- * 拷贝package.json\模块的代码到编译输出目录
13
+ * 拷贝相关配置文件到编译输出目录
15
14
  * @param { object } tmsConfig
16
15
  * @param { array } modules
17
16
  * @param { array } defaultFiles 默认需要拷贝的配置项
18
17
  * @returns
19
18
  */
20
19
  const cpFilesToOutput = function (tmsConfig, targetModules, defaultFiles) {
21
- const outputDir = resolve(tmsConfig.webpack.outputDir);
20
+ const outputDir = resolve(tmsConfig.outputDir);
22
21
  io.ensureDirExist(outputDir);
23
22
  defaultFiles.forEach((item) => {
24
23
  if (fs.existsSync(resolve(item))) {
25
- shelljs.cp('-rf', resolve(item), resolve(tmsConfig.webpack.outputDir, item));
24
+ shelljs.cp('-rf', resolve(item), resolve(tmsConfig.outputDir, item));
26
25
  }
27
26
  });
28
27
 
29
- // 拷贝模块的代码到编译输出目录
28
+ // 拷贝模块的package.json到编译输出目录
30
29
  targetModules.forEach((item) => {
31
- const outputModuleDir = resolve(`${tmsConfig.webpack.outputDir}/${item.root}`);
30
+ const outputModuleDir = resolve(`${tmsConfig.outputDir}/${item.root}`);
32
31
  if (!fs.existsSync(resolve(item.path))) {
33
32
  fail(`${item.path}模块代码路径不存在, 请检查tms.config.js的${item.name}模块的path`);
34
33
  process.exit(1);
35
34
  }
36
- if (!fs.existsSync(outputModuleDir)) {
37
- shelljs.mkdir('-p', outputModuleDir);
38
- } else {
39
- // 删除除了node_modules、miniprogram_npm 的其他文件
40
- // eslint-disable-next-line
41
- shelljs.exec('find . -not \( -name node_modules -or -name miniprogram_npm \) -delete', { silent: true });
42
- }
43
- shelljs.cp('-Rf', `${resolve(item.path)}/*`, outputModuleDir);
35
+ io.ensureDirExist(outputModuleDir);
36
+ const modulePackagePath = resolve(item.path, 'package.json');
37
+ if (fs.existsSync(modulePackagePath)) shelljs.cp('-Rf', modulePackagePath, outputModuleDir);
44
38
  });
45
39
  };
46
40
 
47
- async function task(tmsConfig, targetModules) {
41
+ async function task(tmsConfig, targetModules, isDev) {
48
42
  // 下载和移动代码
49
43
  await createTask(
50
44
  cloneModules,
51
45
  '开始下载模块代码完成',
52
46
  '下载模块代码码完成',
53
- )(MODULE_CODE_DIR, resolve('./'), targetModules);
47
+ )(MODULE_CODE_DIR, resolve('./'), targetModules, isDev);
54
48
 
55
49
  // tms.config.js的modules 合并 module.config.json的配置项
56
- const newModules = tmsModulesMergeLocalModuleCfg(targetModules, tmsConfig.appName, DEFAULT_MODULE_DIR);
57
- console.log('当前init的有效模块', newModules.map(item => item.name));
50
+ let newModules = tmsModulesMergeLocalModuleCfg(targetModules, tmsConfig.appName);
51
+ // A分包依赖了B分包的代码, merge B分包进行编译;
52
+ newModules = subModulesMergeDepModules(tmsConfig, newModules);
58
53
 
59
54
  // 拷贝相关配置文件到输出目录
60
55
  await createTask(
@@ -63,35 +58,30 @@ async function task(tmsConfig, targetModules) {
63
58
  '拷贝文件到编译输出目录完成',
64
59
  )(tmsConfig, newModules, DEFAULT_COPY_CONFIG);
65
60
 
66
- // npm install
67
- await createTask(
68
- npmInstallAll,
69
- '开始npm install',
70
- 'npm install 完成',
71
- )(newModules, resolve(tmsConfig.webpack.outputDir), `${CACHE_DIR}/node_modules`);
72
-
73
- // 构建miniprograme_npm
74
- await createTask(
75
- buildMpNpm,
76
- '开始构建miniprograme_npm',
77
- '构建miniprograme_npm 完成',
78
- )({ appId: tmsConfig.appId, projectPath: resolve('./'), privateKey: tmsConfig.privateKey });
61
+ // install
62
+ await install(tmsConfig, newModules, false);
79
63
 
80
64
  // 动态生成编译后的app.json;
81
65
  await createTask(
82
66
  buildOutputAppJson,
83
67
  '开始生成编译后的app.json',
84
68
  '生成编译后的app.json完成',
85
- )(tmsConfig, newModules);
69
+ )(tmsConfig, newModules, isDev);
86
70
 
87
71
  return newModules;
88
72
  }
89
- async function bootstrap(tmsConfig, targetModules) {
90
- const newModules = await task(tmsConfig, targetModules);
73
+ async function init(tmsConfig, targetModules, isDev) {
74
+ try {
75
+ const newModules = await task(tmsConfig, targetModules, isDev);
91
76
 
92
- return {
93
- targetModules: newModules,
94
- };
77
+ return {
78
+ targetModules: newModules,
79
+ };
80
+ } catch (error) {
81
+ const errMsg = typeof error === 'object' ? error.message : error;
82
+ fail(`init流程出现错误${errMsg}`);
83
+ process.exit(1);
84
+ }
95
85
  }
96
86
 
97
- module.exports = bootstrap;
87
+ module.exports = init;
@@ -1,39 +1,29 @@
1
- const shelljs = require('shelljs');
2
- const { createTask } = require('../../../utils/widgets');
1
+ const { createTask, resolve } = require('../../../utils/widgets');
3
2
  const { buildMpNpm } = require('../../../utils/mpCiUtils');
4
- const glob = require('glob-ignore');
5
- const path = require('path');
3
+ const { CACHE_DIR } = require('../../../config/constant');
4
+ const { cloudNpmInstall, mpNpmInstallAll } = require('../../../utils/npmUtils');
6
5
 
7
- function npmInstall(contextDir) {
8
- return new Promise((resolve, reject) => {
9
- glob(`${contextDir}/**/package.json`, ['node_modules', 'miniprogram_npm'], (err, files) => {
10
- if (err) {
11
- reject(err);
12
- }
13
- files.forEach((file) => {
14
- const dir = path.dirname(file);
15
- shelljs.cd(dir);
16
- shelljs.exec('npx pnpm install --prod --registry http://mirrors.tencent.com/npm/', { silent: false });
17
- });
18
- resolve();
19
- });
20
- });
21
- }
22
-
23
- async function install(contextDir) {
24
- // npm install
6
+ async function install(tmsConfig, modules, isCloud = false) {
7
+ // 小程序npm install
25
8
  await createTask(
26
- npmInstall,
27
- '开始npm install',
28
- 'npm install完成',
29
- )(contextDir);
9
+ mpNpmInstallAll,
10
+ '小程序 开始npm install',
11
+ '小程序npm install 完成',
12
+ )(modules, resolve(tmsConfig.outputDir), `${CACHE_DIR}/node_modules`);
30
13
 
31
14
  // 构建miniprograme_npm
32
15
  await createTask(
33
16
  buildMpNpm,
34
- '开始构建miniprogram_npm',
35
- '构建miniprogram_npm 完成',
36
- )({ appId: 'null', projectPath: contextDir, privateKey: 'null' });
17
+ '开始构建miniprograme_npm',
18
+ '构建miniprograme_npm 完成',
19
+ )({ appId: tmsConfig.appId, projectPath: resolve('./'), privateKey: tmsConfig.privateKey });
20
+
21
+ // 安装云函数的
22
+ isCloud && createTask(
23
+ cloudNpmInstall,
24
+ '云函数npm install',
25
+ '云函数npm install安装完毕',
26
+ )(resolve(tmsConfig.cloudDir));
37
27
  }
38
28
 
39
29
  module.exports = install;
@@ -1,25 +1,23 @@
1
1
  const fs = require('fs');
2
- const { DEFAULT_MODULE_DIR, MODULE_CONFIG_FILENAME } = require('../config/constant');
2
+ const { MODULE_CONFIG_FILENAME, MODULE_CONFIG_INVALID_KEY } = require('../config/constant');
3
3
  const { fail } = require('./log');
4
4
  const { resolve, isObject, isArray } = require('./widgets');
5
+ const { handleError } = require('./handleError');
5
6
 
6
7
  /**
7
8
  * 获取每个模块下面的信息,并且收集,后续更新到appJson里面
8
9
  * @param { object } file 操作目录下面所有的文件
9
10
  * @param { string } appName 小程序的名称
10
11
  */
11
- function setModuleConfig(file, appName, moduleDir) {
12
+
13
+ function setModuleConfig(file, appName) {
12
14
  const content = file.contents ? JSON.parse(file.contents.toString()) : JSON.parse(file);
13
15
 
14
- if (isObject(content)) {
15
- content.root = content.root.indexOf(moduleDir) > -1 ? content.root : `${moduleDir}/${content.root}`;
16
- }
17
16
 
18
17
  if (isArray(content)) {
19
18
  let i = content.length - 1;
20
19
  while (i >= 0) {
21
20
  let current = content[i];
22
- current.root = current.root.indexOf(moduleDir) > -1 ? current.root : `${moduleDir}/${current.root}`;
23
21
 
24
22
  if (appName && current.mpConfig && current.mpConfig[appName]) {
25
23
  current = { ...current, ...current.mpConfig[appName] };
@@ -38,16 +36,17 @@ function setModuleConfig(file, appName, moduleDir) {
38
36
  /**
39
37
  * 递归获取本地所有模块的配置信息
40
38
  */
41
- function getLocalModuleConfig(modules = [], appName, moduleDir, moduleConfigFilename) {
39
+ function getLocalModuleConfig(modules = [], appName, moduleConfigFilename) {
42
40
  const modulesConfig = {};
43
41
 
44
42
  modules.forEach(({ path }) => {
45
43
  const moduleConfigPath = resolve(path, moduleConfigFilename);
46
44
  if (fs.existsSync(moduleConfigPath)) {
47
45
  const content = fs.readFileSync(moduleConfigPath, 'utf-8');
48
- modulesConfig[moduleConfigPath] = setModuleConfig(content, appName, moduleDir);
46
+ modulesConfig[moduleConfigPath] = setModuleConfig(content, appName);
49
47
  }
50
48
  });
49
+
51
50
  return modulesConfig;
52
51
  }
53
52
 
@@ -98,7 +97,7 @@ const getAppJsonContent = (sourceAppJsonPath) => {
98
97
  // 加入默认值
99
98
  appJson.subpackages = [];
100
99
  appJson.pages = [];
101
- appJson.plugins = {};
100
+ // appJson.plugins = {};
102
101
  delete appJson.entranceDeclare;
103
102
  return appJson;
104
103
  };
@@ -111,9 +110,80 @@ const updateSubpackages = (appJson, modulesConfig) => {
111
110
  // eslint-disable-next-line
112
111
  for (const name in modulesConfig) {
113
112
  const moduleInfo = isObject(modulesConfig[name]) ? [modulesConfig[name]] : modulesConfig[name];
113
+ // 过滤 pages 为空的情况
114
+ const validModules = getValidModules(moduleInfo);
115
+ // eslint-disable-next-line
116
+ appJson.subpackages = appJson.subpackages.concat(validModules);
117
+ }
118
+ };
119
+ /**
120
+ * 过滤页面为空的分包
121
+ * @param {Array} moduleCfg 模块配置内容
122
+ * @returns pages不为空的分包
123
+ */
124
+ const getValidModules = (moduleCfg) => {
125
+ // 过滤 pages 为空的情况
126
+ const validModules = moduleCfg.filter(item => item.pages.length > 0);
127
+ return validModules;
128
+ };
129
+
130
+ /**
131
+ * 处理合并subpackages后的appjson, 整理重复不合法的地方
132
+ * @param {Object} appJson appjson
133
+ */
134
+ const processAppJson = (appJson) => {
135
+ const { subpackages } = appJson;
136
+ const pluginsMap = {};
137
+ Object.keys(appJson.plugins || {}).forEach(key => pluginsMap[key] = ['app.json']);
138
+ const subps = subpackages.map((subp) => {
139
+ const invalidKeys = [];
140
+ Object.keys(subp).forEach((key) => {
141
+ if (key === 'dependencies') {
142
+ // eslint-disable-next-line
143
+ delete subp.dependencies;
144
+ return;
145
+ }
146
+ if (key === 'plugins') {
147
+ Object.keys(subp.plugins).forEach((pk) => {
148
+ pluginsMap[pk] ? pluginsMap[pk].push(`分包${subp.name}`) : pluginsMap[pk] = [`分包${subp.name}`];
149
+ });
150
+ return;
151
+ }
152
+ if (MODULE_CONFIG_INVALID_KEY.indexOf(key) > -1) {
153
+ // 如果分包配置中有不支持的key,则错误提醒
154
+ invalidKeys.push(key);
155
+ return;
156
+ }
157
+ if (['requiredBackgroundModes', 'embeddedAppIdList'].indexOf(key) > -1) {
158
+ // 提到appjson最上层处理
159
+ const preVal = appJson[key];
160
+ // eslint-disable-next-line
161
+ preVal ? appJson[key] = Array.from(new Set(preVal
162
+ // eslint-disable-next-line
163
+ .slice(0).concat(subp[key]))) : appJson[key] = subp[key].slice(0);
164
+ return;
165
+ }
166
+ });
167
+ if (invalidKeys.length) {
168
+ fail(`不支持分包${subp?.name}配置${invalidKeys.join(',')}\n`);
169
+ }
114
170
  // eslint-disable-next-line
115
- appJson.subpackages = appJson.subpackages.concat(moduleInfo);
171
+ invalidKeys.concat(['requiredBackgroundModes', 'embeddedAppIdList']).forEach(k => delete subp[k]);
172
+ return subp;
173
+ });
174
+ // 如果plugins重复,则错误提示
175
+ const pluginsErrMsg = Object.keys(pluginsMap).map((pk) => {
176
+ if (pluginsMap[pk].length > 1) {
177
+ return `${pluginsMap[pk].join(',')}重复配置plugin(${pk});`;
178
+ }
179
+ return '';
180
+ })
181
+ .reduce((pre, cur) => pre + cur, '');
182
+ if (pluginsErrMsg) {
183
+ fail(`plugins配置出现错误:${pluginsErrMsg}`);
116
184
  }
185
+ // eslint-disable-next-line
186
+ appJson.subpackages = subps;
117
187
  };
118
188
 
119
189
 
@@ -123,22 +193,29 @@ const updateSubpackages = (appJson, modulesConfig) => {
123
193
  * @param {array} modules
124
194
  * @returns
125
195
  */
126
- function buildOutputAppJson(tmsConfig, modules) {
127
- // 获取当前 modules 下的所有子模块的配置内容
128
- const modulesConfig = getLocalModuleConfig(modules, tmsConfig.appName, DEFAULT_MODULE_DIR, MODULE_CONFIG_FILENAME);
129
- // 获取app.json的配置
130
- const appJson = getAppJsonContent(resolve('./app.json'));
131
- // 更新app.json中的subpackages
132
- updateSubpackages(appJson, modulesConfig);
133
- // 更新主包,需在subpackages处理完成后执行, pages/
134
- updateMainPackages(appJson, tmsConfig.mainPackages, DEFAULT_MODULE_DIR);
135
-
136
- fs.writeFileSync(resolve(`${tmsConfig.webpack.outputDir}/app.json`), JSON.stringify(appJson, null, 2), 'utf8');
137
-
138
- return appJson;
196
+ function buildOutputAppJson(tmsConfig, modules, isDev) {
197
+ try {
198
+ // 获取当前 modules 下的所有子模块的配置内容
199
+ const modulesConfig = getLocalModuleConfig(modules, tmsConfig.appName, MODULE_CONFIG_FILENAME);
200
+ // 获取app.json的配置
201
+ const appJson = getAppJsonContent(resolve('./app.json'));
202
+ // 更新app.json中的subpackages
203
+ updateSubpackages(appJson, modulesConfig);
204
+ // 处理appJson中重复||冲突的地方
205
+ processAppJson(appJson);
206
+ // 更新主包,需在subpackages处理完成后执行, pages/
207
+ updateMainPackages(appJson, tmsConfig.mainPackages);
208
+
209
+ fs.writeFileSync(resolve(`${tmsConfig.outputDir}/app.json`), JSON.stringify(appJson, null, 2), 'utf8');
210
+
211
+ return appJson;
212
+ } catch (e) {
213
+ handleError(`生成app.json出现错误: ${e}`, isDev);
214
+ }
139
215
  }
140
216
 
141
217
  module.exports = {
142
218
  setModuleConfig,
219
+ getValidModules,
143
220
  buildOutputAppJson,
144
221
  };
@@ -2,8 +2,8 @@ const fs = require('fs');
2
2
  const semver = require('semver');
3
3
  const { resolve } = require('./widgets');
4
4
  const path = require('path');
5
- const { fail } = require('./log');
6
5
  const shelljs = require('shelljs');
6
+ const { handleError } = require('./handleError');
7
7
 
8
8
  const getLatestVersion = (npmName) => {
9
9
  const data = shelljs.exec(`npm view ${npmName} version`);
@@ -17,7 +17,7 @@ const getLatestVersion = (npmName) => {
17
17
  * @param {*} outputDir 待检查node_modules存放的目录 (eg: dist/node_modules)
18
18
  * @returns
19
19
  */
20
- const checkDependencies = (modules, cwd, outputDir) => {
20
+ const checkDependencies = (modules, cwd, outputDir, isDev) => {
21
21
  // 步骤1. 收集package.json
22
22
  const packageJsonName = 'package.json'; // 查找文件名
23
23
  // 1.1根目录的package.json
@@ -41,12 +41,12 @@ const checkDependencies = (modules, cwd, outputDir) => {
41
41
  // 步骤2. 比较package.json的依赖与node_modules依赖的版本号
42
42
  for (const item of packageArr) {
43
43
  const packageJson = fs.readFileSync(item.srcPackageDir, 'utf-8');
44
- let dependencies;
44
+ let dependencies = {};
45
45
  try {
46
- dependencies = JSON.parse(packageJson).dependencies;
46
+ const json = JSON.parse(packageJson);
47
+ dependencies = json?.dependencies ? json?.dependencies : {};
47
48
  } catch (e) {
48
- fail(`解析${packageJson}报错,请检查是否是正确的json配置项`);
49
- process.exit(1);
49
+ handleError(`解析${item.srcPackageDir}报错,请检查是否是正确的json配置项`, isDev);
50
50
  }
51
51
  const dependenciesKeys = Object.keys(dependencies);
52
52
  for (const key of dependenciesKeys) {
@@ -1,9 +1,29 @@
1
1
  const MetalSmith = require('metalsmith');
2
2
  const { getGlobalInstance } = require('./global.js');
3
3
  const { downloadRepoForGit, resolve } = require('./widgets');
4
+ const { readTmsPrivateCf } = require('../utils/tkitUtils');
4
5
  const { fail } = require('./log');
5
6
  const fs = require('fs');
6
7
  const shelljs = require('shelljs');
8
+ const { handleError } = require('./handleError.js');
9
+
10
+ /**
11
+ * 处理用户没有clone git仓库权限问题——拼接账号信息
12
+ * @param {*} httpRepoUrl
13
+ * @param {*} moduleName
14
+ * @returns
15
+ */
16
+ function replaceGitUrlAccount(httpRepoUrl, moduleName, privateCf) {
17
+ let gitUrl = httpRepoUrl;
18
+ const { username = '', pass = '' } = privateCf?.gitAccout?.[moduleName] || {};
19
+
20
+ const urlPrefixReg = /http(s)?:\/\//;
21
+ if (username && pass && urlPrefixReg.test(gitUrl)) {
22
+ gitUrl = gitUrl.replace(urlPrefixReg, val => `${val}${encodeURIComponent(username)}:${pass}@`);
23
+ }
24
+
25
+ return gitUrl;
26
+ }
7
27
 
8
28
  /**
9
29
  * 对克隆下来的模块进行相应的文件处理操作,比如收集处理模块信息,进行信息缓存等操作
@@ -14,15 +34,15 @@ const shelljs = require('shelljs');
14
34
  */
15
35
  function moveFile(sourceDir, targetDir, ignore = []) {
16
36
  // 删除不是文件夹的文件
17
- return new Promise((resolve) => {
37
+ return new Promise((resolve, reject) => {
18
38
  MetalSmith(__dirname)
19
39
  .ignore(ignore)
20
40
  .source(sourceDir)
21
41
  .destination(targetDir)
22
42
  .build((e) => {
23
43
  if (e) {
24
- fail(e); // eslint-disable-line
25
- console.log('MetalSmith 详细的错误信息:', e);
44
+ fail(`${sourceDir} moveFile ${targetDir}出现错误: ${e}`);
45
+ reject(e);
26
46
  }
27
47
  resolve();
28
48
  });
@@ -33,13 +53,17 @@ function moveFile(sourceDir, targetDir, ignore = []) {
33
53
  * 下载目标模块
34
54
  * @param { string } sourceDir 缓存文件夹
35
55
  * @param { string } targetDir 目标文件夹
56
+ * @param { boolean } isDev 是否是dev
36
57
  * @returns { array } modules 描述模块的列表
37
58
  */
38
- async function cloneModules(sourceDir, targetDir, modules) {
59
+ async function cloneModules(sourceDir, targetDir, modules, isDev) {
60
+ // 用户本地的私有项目配置(用来配置环境\模块信息\账号信息)
61
+ const privateCf = readTmsPrivateCf();
62
+
39
63
  // 根据小程序的配置文件下载模块, 并且处理信息
40
- for (const moduleInfo of modules) { // eslint-disable-line
64
+ for (const moduleInfo of modules) {
41
65
  if (moduleInfo.repoInfo) {
42
- await downLoadAndMoveModule(sourceDir, targetDir, moduleInfo);
66
+ await downLoadAndMoveModule(sourceDir, targetDir, moduleInfo, privateCf, isDev);
43
67
  }
44
68
  }
45
69
  }
@@ -48,13 +72,14 @@ async function cloneModules(sourceDir, targetDir, modules) {
48
72
  * 下载模块信息并且将它移动到对应的位置
49
73
  * @param { string } sourceDir 代码缓存文件夹
50
74
  * @param { string } targetDir 代码要放到的目标文件夹
75
+ * @param { boolean } isDev 是否是dev
51
76
  * @returns { array } moduleInfo 描述模块的信息
52
77
  */
53
- async function downLoadAndMoveModule(sourceDir, targetDir, moduleInfo) {
54
- const { repoInfo: { buildGitTag, httpRepoUrl }, path } = moduleInfo;
78
+ async function downLoadAndMoveModule(sourceDir, targetDir, moduleInfo, privateCf, isDev) {
79
+ const { repoInfo: { buildGitTag, httpRepoUrl }, path, name } = moduleInfo;
55
80
 
56
81
  // 源码临时存在的源目录
57
- let sourcePath = resolve(sourceDir, path);
82
+ let sourcePath = resolve(sourceDir, name);
58
83
  // 源码要放到目标目录
59
84
  const targetPath = resolve(targetDir, path);
60
85
  // 设置模块的构建分支
@@ -66,22 +91,23 @@ async function downLoadAndMoveModule(sourceDir, targetDir, moduleInfo) {
66
91
 
67
92
  try {
68
93
  if (!moduleInCache) {
69
- await downloadRepoForGit(httpRepoUrl, sourcePath, cloneBranch);
94
+ // 处理仓库权限问题
95
+ const gitUrl = replaceGitUrlAccount(httpRepoUrl, name, privateCf);
96
+ await downloadRepoForGit(gitUrl, sourcePath, cloneBranch);
70
97
  globalInstance.setModuleCache(httpRepoUrl, cloneBranch, sourcePath);
71
98
  } else {
72
99
  sourcePath = globalInstance.getModuleCache(httpRepoUrl, cloneBranch).dest;
73
100
  }
74
101
 
75
102
  if (fs.existsSync(targetPath)) {
76
- shelljs.rm('-rf', targetPath);
103
+ shelljs.rm('-rf', `${targetPath}/*`);
77
104
  }
78
105
  await moveFile(sourcePath, targetPath, [
79
106
  'node_modules',
80
107
  '.git',
81
108
  ]);
82
109
  } catch (e) {
83
- fail(`downLoadAndMoveModule ${e}`); // eslint-disable-line
84
- process.exit(-1);
110
+ handleError(e, isDev);
85
111
  }
86
112
  }
87
113
 
@@ -0,0 +1,30 @@
1
+ /* eslint-disable no-param-reassign */
2
+ const strip = require('strip-comments');
3
+ // 匹配规则
4
+ const MATCH_RULE = new RegExp(/@import *(?:url\(['"]?([^'")]+)['"]?\)|['"]([^'"]+)['"]);?/g);
5
+
6
+ /**
7
+ * 获取样式文件中的@import语句
8
+ * @param code 代码片段
9
+ * @returns 结果数组
10
+ */
11
+ const findCssImports = (code) => {
12
+ // 将buffer转成字符串
13
+ code = code.toString();
14
+ // 去除注释
15
+ code = strip.block(code);
16
+ // 定义最后返回的结果
17
+ const result = [];
18
+ let matchList;
19
+ // 循环遍历代码段,直至匹配结果为空
20
+ while ((matchList = MATCH_RULE.exec(code))) {
21
+ // 存入结果数组
22
+ result.push(matchList?.[1] || matchList?.[2]);
23
+ }
24
+ // 返回结果
25
+ return result;
26
+ };
27
+
28
+ module.exports = {
29
+ findCssImports,
30
+ };
@@ -0,0 +1,16 @@
1
+ const { fail } = require('./log');
2
+
3
+ function handleError(error, isDev = false) {
4
+ const errMsg = typeof error === 'object' ? error.message : error;
5
+ if (isDev) {
6
+ fail(errMsg);
7
+ } else {
8
+ fail(errMsg);
9
+ process.exit(1);
10
+ }
11
+ }
12
+
13
+ module.exports = {
14
+ handleError,
15
+ };
16
+