@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.
- package/README.md +18 -2
- package/dist/index.cjs.js +2286 -1258
- package/package.json +24 -8
- package/src/compile/build.js +5 -0
- package/src/compile/compile.js +90 -0
- package/src/compile/dev.js +129 -0
- package/src/compile/plugins/less.js +116 -0
- package/src/compile/plugins/mpCommonDep.js +131 -0
- package/src/compile/plugins/mpJsonDep.js +112 -0
- package/src/compile/plugins/mpWxmlDep.js +194 -0
- package/src/compile/plugins/postcss-font-base64.js +72 -0
- package/src/compile/plugins/replaceEnv.js +29 -0
- package/src/compile/plugins/utils/pluginError.js +25 -0
- package/src/config/constant.js +11 -10
- package/src/config/defaultTmsConfig.js +9 -10
- package/src/core/buildAppJson.js +166 -0
- package/src/{utils → core}/checkDependencies.js +6 -6
- package/src/core/cloneModules.js +203 -0
- package/src/core/handleError.js +18 -0
- package/src/core/isInIt.js +69 -0
- package/src/{utils/mpCiUtils.js → core/mpCi.js} +0 -1
- package/src/core/npm.js +218 -0
- package/src/core/symbolicLink.js +24 -0
- package/src/core/tmsMpconfig.js +234 -0
- package/src/entry.js +50 -8
- package/src/index.js +31 -15
- package/src/init.js +2 -7
- package/src/scripts/create/index.js +2 -2
- package/src/scripts/run/build/index.js +3 -3
- package/src/scripts/run/dev/index.js +27 -52
- package/src/scripts/run/index.js +70 -36
- package/src/scripts/run/init/index.js +40 -42
- package/src/scripts/run/install/index.js +21 -29
- package/src/utils/findCssImport.js +30 -0
- package/src/utils/global.js +19 -33
- package/src/utils/io.js +86 -0
- package/src/utils/log.js +3 -0
- package/src/utils/widgets.js +59 -51
- package/CHANGELOG.md +0 -0
- package/main.js +0 -3
- package/rollup.config.js +0 -179
- package/src/utils/buildAppJson.js +0 -144
- package/src/utils/cliUtils.js +0 -35
- package/src/utils/cloneModules.js +0 -90
- package/src/utils/npmUtils.js +0 -126
- package/src/utils/tkitUtils.js +0 -84
- package/src/webpack/base.js +0 -65
- package/src/webpack/build.js +0 -21
- package/src/webpack/buildServer.js +0 -34
- package/src/webpack/dev.js +0 -31
- package/src/webpack/devServer.js +0 -37
- package/src/webpack/plugins/entryExtractPlugin/index.js +0 -28
- package/src/webpack/utils.js +0 -244
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
const through = require('through2');
|
|
3
|
+
const htmlparser2 = require('htmlparser2');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { diffContentCopyFile, ext, fileInDir } = require('../../utils/io');
|
|
7
|
+
const { resolve } = require('../../utils/widgets');
|
|
8
|
+
const { dfsFindCommonDep } = require('./mpCommonDep');
|
|
9
|
+
const { pluginError } = require('./utils/pluginError');
|
|
10
|
+
|
|
11
|
+
// 处理后缀(源码引入依赖时,不带后缀的情况)
|
|
12
|
+
const extFile = function (name, file) {
|
|
13
|
+
const extMap = {
|
|
14
|
+
import: '.wxml',
|
|
15
|
+
include: '.wxml',
|
|
16
|
+
wxs: '.wxs',
|
|
17
|
+
};
|
|
18
|
+
let extObj = {};
|
|
19
|
+
|
|
20
|
+
if (Object.keys(extMap).indexOf(name) > -1 && !file.endsWith(extMap[name])) {
|
|
21
|
+
extObj = ext(file, [extMap[name]]);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
extPath: extObj.extPath || '',
|
|
25
|
+
ext: extObj.ext || '',
|
|
26
|
+
file: extObj.file || file,
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const dfsFindWxmlDep = function (anaFileOriginFile, anaFileDestFile, isWatch = true) {
|
|
31
|
+
const resDep = {
|
|
32
|
+
image: new Map(),
|
|
33
|
+
wxml: new Map(),
|
|
34
|
+
wxs: new Map(),
|
|
35
|
+
};
|
|
36
|
+
function dfs(anaFileOriginFile, anaFileDestFile) {
|
|
37
|
+
let contents = '';
|
|
38
|
+
try {
|
|
39
|
+
contents = fs.readFileSync(anaFileOriginFile, 'utf8');
|
|
40
|
+
} catch (e) {
|
|
41
|
+
pluginError(e, isWatch);
|
|
42
|
+
}
|
|
43
|
+
const parser = new htmlparser2.Parser({
|
|
44
|
+
onopentag(name, attributes) {
|
|
45
|
+
if (attributes?.src?.startsWith('.')) {
|
|
46
|
+
const depOriginPath = path.join(path.dirname(anaFileOriginFile), attributes.src);
|
|
47
|
+
// 被依赖文件加上后缀
|
|
48
|
+
const { ext, file: depOriginFile, extPath } = extFile(name, depOriginPath);
|
|
49
|
+
|
|
50
|
+
if (!fs.existsSync(depOriginFile)) {
|
|
51
|
+
pluginError(
|
|
52
|
+
new Error(`${anaFileOriginFile}引用的路径${depOriginFile}找不到应用文件,请检查引用路径`),
|
|
53
|
+
isWatch,
|
|
54
|
+
);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const depDestPath = path.join(path.dirname(anaFileDestFile), attributes.src);
|
|
59
|
+
const depDestFile = depDestPath.endsWith(ext) ? depDestPath : depDestPath + extPath;
|
|
60
|
+
|
|
61
|
+
// 收集wxml依赖
|
|
62
|
+
if (['import', 'include'].indexOf(name) > -1) {
|
|
63
|
+
resDep.wxml.set(depDestFile, {
|
|
64
|
+
anaFileOriginFile,
|
|
65
|
+
anaFileDestFile,
|
|
66
|
+
depDestFile,
|
|
67
|
+
depOriginFile,
|
|
68
|
+
});
|
|
69
|
+
dfs(depOriginFile, depDestFile);
|
|
70
|
+
}
|
|
71
|
+
// 收集image依赖
|
|
72
|
+
// if (name === 'image') {
|
|
73
|
+
// resDep.image.set(attributes.src, {
|
|
74
|
+
// anaFileOriginFile,
|
|
75
|
+
// anaFileDestFile,
|
|
76
|
+
// depDestFile,
|
|
77
|
+
// depOriginFile,
|
|
78
|
+
// });
|
|
79
|
+
// dfs(depOriginFile, depDestFile);
|
|
80
|
+
// }
|
|
81
|
+
// 收集wxs依赖
|
|
82
|
+
if (name === 'wxs') {
|
|
83
|
+
resDep.wxs.set(depDestFile, {
|
|
84
|
+
anaFileOriginFile,
|
|
85
|
+
anaFileDestFile,
|
|
86
|
+
depDestFile,
|
|
87
|
+
depOriginFile,
|
|
88
|
+
});
|
|
89
|
+
const defs = dfsFindCommonDep(depOriginFile, depDestFile, ['.wxs']);
|
|
90
|
+
defs.forEach((item, key) => {
|
|
91
|
+
resDep.wxs.set(key, item);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
parser.write(contents);
|
|
98
|
+
parser.end();
|
|
99
|
+
}
|
|
100
|
+
dfs(anaFileOriginFile, anaFileDestFile);
|
|
101
|
+
|
|
102
|
+
return resDep;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
function mpWxmlDep(tmsConfig, module, isWatch) {
|
|
106
|
+
const stream = through.obj(function (file, enc, cb) {
|
|
107
|
+
// 依赖分析的文件
|
|
108
|
+
const anaFileOriginFile = file.history[0];
|
|
109
|
+
const anaFileRelativeModule = path.relative(resolve(module.from), anaFileOriginFile);
|
|
110
|
+
const anaFileDestFile = resolve(tmsConfig.outputDir, module.to, anaFileRelativeModule);
|
|
111
|
+
|
|
112
|
+
if (file.isBuffer()) {
|
|
113
|
+
let contents = String(file.contents);
|
|
114
|
+
const copyModules = new Map();
|
|
115
|
+
const parser = new htmlparser2.Parser({
|
|
116
|
+
onopentag(name, attributes) {
|
|
117
|
+
const nameFilter = ['import', 'include', 'wxs'];
|
|
118
|
+
if (nameFilter.indexOf(name) > -1 && attributes.src) {
|
|
119
|
+
const depOriginPath = path.join(path.dirname(anaFileOriginFile), attributes.src);
|
|
120
|
+
// 处理后缀(源码引入依赖时,后缀不全的情况)
|
|
121
|
+
const { ext, file: depOriginFile, extPath } = extFile(name, depOriginPath);
|
|
122
|
+
|
|
123
|
+
Object.keys(tmsConfig.dependencies).forEach((includeName) => {
|
|
124
|
+
if (attributes.src.indexOf(includeName) > -1) {
|
|
125
|
+
const includePath = tmsConfig.dependencies[includeName];
|
|
126
|
+
|
|
127
|
+
if (!fileInDir(includePath, depOriginFile)) {
|
|
128
|
+
pluginError(
|
|
129
|
+
new Error(`${anaFileOriginFile}引用路径${depOriginFile}不在${includePath}不在文件夹内, 请检查应用路径`),
|
|
130
|
+
isWatch,
|
|
131
|
+
);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// eslint-disable-next-line
|
|
136
|
+
const reg = new RegExp(`^(\./\.\.\/)+.*\/${includeName}\/(.*)`);
|
|
137
|
+
const regRes = attributes.src.match(reg) || [];
|
|
138
|
+
if (regRes[2]) {
|
|
139
|
+
const depDestPath = resolve(tmsConfig.outputDir, module.to, includeName, regRes[2]);
|
|
140
|
+
const depDestFile = depDestPath.endsWith(ext) ? depDestPath : depDestPath + extPath;
|
|
141
|
+
if (!copyModules.has(depDestFile)) {
|
|
142
|
+
copyModules.set(depDestFile, {
|
|
143
|
+
depOriginFile,
|
|
144
|
+
depDestFile,
|
|
145
|
+
beforeDepPath: attributes.src,
|
|
146
|
+
afterDepPath: path.relative(path.dirname(anaFileDestFile), depDestFile).replace(/\\/g, '/'),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
parser.write(contents);
|
|
156
|
+
parser.end();
|
|
157
|
+
|
|
158
|
+
// console.log('wxml copyModules', copyModules);
|
|
159
|
+
copyModules.forEach(({ depOriginFile, depDestFile, beforeDepPath, afterDepPath }) => {
|
|
160
|
+
if (fs.existsSync(depOriginFile)) {
|
|
161
|
+
diffContentCopyFile(depOriginFile, depDestFile);
|
|
162
|
+
const reg = new RegExp(`['"]${beforeDepPath}["']`, 'g');
|
|
163
|
+
contents = contents.replace(reg, `"${afterDepPath}"`);
|
|
164
|
+
}
|
|
165
|
+
if (depOriginFile.endsWith('.wxml')) {
|
|
166
|
+
const defs = dfsFindWxmlDep(depOriginFile, depDestFile, isWatch);
|
|
167
|
+
// console.log('wxml defs', defs);
|
|
168
|
+
[...defs.wxml, ...defs.wxs].forEach(([, item]) => {
|
|
169
|
+
diffContentCopyFile(item.depOriginFile, item.depDestFile);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (depOriginFile.endsWith('.wxs')) {
|
|
173
|
+
const defs = dfsFindCommonDep(depOriginFile, depDestFile, ['.wxs'], isWatch);
|
|
174
|
+
// console.log('wxs defs', defs);
|
|
175
|
+
defs.forEach((item) => {
|
|
176
|
+
diffContentCopyFile(item.depOriginFile, item.depDestFile);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
file.contents = Buffer.from(contents);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
this.push(file);
|
|
185
|
+
cb();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
return stream;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
module.exports = {
|
|
192
|
+
mpWxmlDep,
|
|
193
|
+
dfsFindWxmlDep,
|
|
194
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
const postcss = require('postcss');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { fail } = require('../../utils/log');
|
|
6
|
+
|
|
7
|
+
module.exports = postcss.plugin('postcss-font-base64', (options) => {
|
|
8
|
+
options = {
|
|
9
|
+
...options,
|
|
10
|
+
...{
|
|
11
|
+
match: { Scrabble: ['fakefont'] },
|
|
12
|
+
format: ['eot', 'woff', 'woff2', 'ttf'],
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return function (css, result) {
|
|
17
|
+
css.walkAtRules('font-face', (fontFace) => {
|
|
18
|
+
const fileTypeRegex = getRegexStringForFileTypes(options.format);
|
|
19
|
+
|
|
20
|
+
fontFace.replaceValues(new RegExp(`url\\(["']?.+\\.${fileTypeRegex}["']?\\)`), (attr) => {
|
|
21
|
+
const fontRePath = attr.replace(/(url|'|"|\(|\)|\?#iefix)/g, '');
|
|
22
|
+
const fontAbPath = path.join(path.dirname(result.opts.from), fontRePath);
|
|
23
|
+
const res64 = base64Encode(fontAbPath);
|
|
24
|
+
const newUrlStr = 'url(data:'.concat(getMimeType(attr)).concat(';charset=utf-8;base64,')
|
|
25
|
+
.concat(res64)
|
|
26
|
+
.concat(')');
|
|
27
|
+
return res64 ? newUrlStr : attr;
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function getRegexStringForFileTypes(fileTypes) {
|
|
32
|
+
const regex = fileTypes.map(fileType => (
|
|
33
|
+
fileType === 'eot'
|
|
34
|
+
? fileType.concat('(\\?#iefix)?')
|
|
35
|
+
: fileType)).join('|');
|
|
36
|
+
return regex ? `(${regex})` : '';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// helper functions
|
|
40
|
+
function getMimeType(attribute) {
|
|
41
|
+
const formats = {
|
|
42
|
+
'.woff': 'application/font-woff',
|
|
43
|
+
'.woff2': 'font/woff2',
|
|
44
|
+
'.ttf': 'application/font-sfnt',
|
|
45
|
+
'.eot': 'application/vnd.ms-fontobject',
|
|
46
|
+
'.otf': 'application/font-sfnt',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
let match = '';
|
|
50
|
+
const extension = attribute.match(/\.[a-z]{3,4}/)[0];
|
|
51
|
+
|
|
52
|
+
if (extension in formats) {
|
|
53
|
+
match = formats[extension];
|
|
54
|
+
};
|
|
55
|
+
return match;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function base64Encode(file) {
|
|
59
|
+
if (fs.existsSync(file)) {
|
|
60
|
+
return readAndEncodeFile(file);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fail(`${file} does not exist.`);
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function readAndEncodeFile(file) {
|
|
68
|
+
const bitmap = fs.readFileSync(file);
|
|
69
|
+
return Buffer.from(bitmap).toString('base64');
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const through = require('through2');
|
|
2
|
+
function replaceEnv(reg = /process\.env(\.(\w*))?/g, envData) {
|
|
3
|
+
const stream = through.obj(function (file, enc, cb) {
|
|
4
|
+
if (file.isBuffer()) {
|
|
5
|
+
let contents = String(file.contents);
|
|
6
|
+
let resReg;
|
|
7
|
+
// eslint-disable-next-line
|
|
8
|
+
while ((resReg = reg.exec(contents)) !== null) {
|
|
9
|
+
const [reg1, reg2, reg3] = resReg;
|
|
10
|
+
if (reg1 && reg2 && reg3) {
|
|
11
|
+
const value = typeof envData[reg3] === 'object' ? JSON.stringify(envData[reg3]) : envData[reg3];
|
|
12
|
+
contents = contents.replace(reg1, value);
|
|
13
|
+
} else if (reg1 && !reg2 && !reg3) {
|
|
14
|
+
contents = contents.replace(reg1, JSON.stringify(envData));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// eslint-disable-next-line
|
|
19
|
+
file.contents = Buffer.from(contents);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.push(file);
|
|
23
|
+
cb();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return stream;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = replaceEnv;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
const { fail } = require('../../../utils/log');
|
|
3
|
+
|
|
4
|
+
function pluginError(error, isWatch) {
|
|
5
|
+
const errorOptions = { showStack: true };
|
|
6
|
+
|
|
7
|
+
errorOptions.error = error;
|
|
8
|
+
errorOptions.fileName = error.file;
|
|
9
|
+
errorOptions.lineNumber = error.line;
|
|
10
|
+
errorOptions.showProperties = false;
|
|
11
|
+
errorOptions.showStack = false;
|
|
12
|
+
|
|
13
|
+
const errMsg = error.message;
|
|
14
|
+
|
|
15
|
+
if (isWatch) {
|
|
16
|
+
fail(errMsg);
|
|
17
|
+
} else {
|
|
18
|
+
fail(errMsg);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
pluginError,
|
|
25
|
+
};
|
package/src/config/constant.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const os = require('os');
|
|
2
3
|
|
|
3
4
|
// 用户目录
|
|
4
|
-
const HOME_DIR =
|
|
5
|
+
const HOME_DIR = os.homedir();
|
|
5
6
|
|
|
6
7
|
// 所有文件的缓存目录
|
|
7
8
|
const CACHE_DIR = path.resolve(HOME_DIR, '.tmskit');
|
|
@@ -21,10 +22,14 @@ const TMS_NAME = 'tmskit';
|
|
|
21
22
|
// 脚手架的配置名称
|
|
22
23
|
const TMS_CONFIG_FILENAME = 'tms.config.js';
|
|
23
24
|
|
|
25
|
+
const TMS_PRIVATE_FILENAME = 'tms.private.config.js';
|
|
24
26
|
|
|
25
27
|
// 模块代码的默认在modules子目录
|
|
26
28
|
const DEFAULT_MODULE_DIR = 'modules';
|
|
27
29
|
|
|
30
|
+
// 模块代码的默认在modules子目录
|
|
31
|
+
const DEFAULT_CLOUD_MODULE_DIR = './cloud';
|
|
32
|
+
|
|
28
33
|
// 模块的配置文件的名称
|
|
29
34
|
const MODULE_CONFIG_FILENAME = 'module.config.json';
|
|
30
35
|
|
|
@@ -34,14 +39,7 @@ const DEFAULT_WEBPACK_ENTRY = {
|
|
|
34
39
|
};
|
|
35
40
|
|
|
36
41
|
// 默认从源码拷贝到编译后的配置
|
|
37
|
-
const DEFAULT_COPY_CONFIG = ['package.json', '
|
|
38
|
-
|
|
39
|
-
// 开发模式
|
|
40
|
-
const MODE = {
|
|
41
|
-
main: 'tkitmain',
|
|
42
|
-
all: 'all',
|
|
43
|
-
multi: 'multi',
|
|
44
|
-
};
|
|
42
|
+
const DEFAULT_COPY_CONFIG = ['package.json', 'sitemap.json'];
|
|
45
43
|
|
|
46
44
|
const ENV = {
|
|
47
45
|
dev: 'development',
|
|
@@ -49,6 +47,7 @@ const ENV = {
|
|
|
49
47
|
};
|
|
50
48
|
|
|
51
49
|
const TEMPLATE_TKIT_DIR = '_tmskit';
|
|
50
|
+
const MODULE_CONFIG_INVALID_KEY = ['entranceDeclare', 'entryPagePath'];
|
|
52
51
|
|
|
53
52
|
export {
|
|
54
53
|
HOME_DIR,
|
|
@@ -57,12 +56,14 @@ export {
|
|
|
57
56
|
TEMPLATE_PATH,
|
|
58
57
|
TMS_NAME,
|
|
59
58
|
TMS_CONFIG_FILENAME,
|
|
59
|
+
TMS_PRIVATE_FILENAME,
|
|
60
60
|
DEFAULT_MODULE_DIR,
|
|
61
61
|
MODULE_CONFIG_FILENAME,
|
|
62
62
|
DEFAULT_WEBPACK_ENTRY,
|
|
63
63
|
DEFAULT_COPY_CONFIG,
|
|
64
64
|
MODULE_CODE_DIR,
|
|
65
|
-
MODE,
|
|
66
65
|
ENV,
|
|
67
66
|
TEMPLATE_TKIT_DIR,
|
|
67
|
+
MODULE_CONFIG_INVALID_KEY,
|
|
68
|
+
DEFAULT_CLOUD_MODULE_DIR,
|
|
68
69
|
};
|
|
@@ -4,14 +4,13 @@ module.exports = {
|
|
|
4
4
|
envData: {},
|
|
5
5
|
// 模块配置信息
|
|
6
6
|
modules: [],
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
},
|
|
7
|
+
cloudDir: 'cloud',
|
|
8
|
+
// 第三方依赖代码需要拷贝到本项目的
|
|
9
|
+
dependencies: {},
|
|
10
|
+
/** 编译输出文件夹位置 */
|
|
11
|
+
outputDir: 'dist',
|
|
12
|
+
/** 源码监听路径 */
|
|
13
|
+
sourceDir: './',
|
|
14
|
+
/** 静态资源目录 */
|
|
15
|
+
static: [],
|
|
17
16
|
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成编译后的app.json
|
|
3
|
+
*/
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const { MODULE_CONFIG_FILENAME, MODULE_CONFIG_INVALID_KEY } = require('../config/constant');
|
|
6
|
+
const { getModuleConfig, getValidModules } = require('./tmsMpconfig');
|
|
7
|
+
const { fail } = require('../utils/log');
|
|
8
|
+
const { resolve, isObject } = require('../utils/widgets');
|
|
9
|
+
const { handleError } = require('./handleError');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 更新appJson里面的主包配置
|
|
13
|
+
* @param { object } appJson appJson信息
|
|
14
|
+
* @param { array } mainPackages 小程序主包信息
|
|
15
|
+
* @returns { object } appJson小程序主页配置信息
|
|
16
|
+
*/
|
|
17
|
+
function updateMainPackages(appJson, mainPackages = []) {
|
|
18
|
+
let foundMainPackages = appJson.subpackages.filter(subpackage => mainPackages.includes(subpackage.name));
|
|
19
|
+
if (foundMainPackages.length === 0) {
|
|
20
|
+
// 没找到主包
|
|
21
|
+
foundMainPackages = [appJson.subpackages[0]];
|
|
22
|
+
}
|
|
23
|
+
// 拼装 app.pages
|
|
24
|
+
foundMainPackages.forEach((subpackage) => {
|
|
25
|
+
if (!subpackage.pages || !subpackage.pages.length) {
|
|
26
|
+
fail(`主包 ${subpackage} 不能没有 pages`);
|
|
27
|
+
process.exit(-1);
|
|
28
|
+
}
|
|
29
|
+
subpackage.pages.forEach((page) => {
|
|
30
|
+
appJson.pages.push(`${subpackage.root}/${page}`);
|
|
31
|
+
});
|
|
32
|
+
if (subpackage.plugins) {
|
|
33
|
+
Object.assign(appJson.plugins, subpackage.plugins);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// 去掉 subpackages 中的主包配置
|
|
38
|
+
const foundMainPackageNames = foundMainPackages.map(item => item.name);
|
|
39
|
+
// eslint-disable-next-line
|
|
40
|
+
appJson.subpackages = appJson.subpackages.filter(subpackage => !foundMainPackageNames.includes(subpackage.name));
|
|
41
|
+
|
|
42
|
+
return appJson;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 获取app.json内容
|
|
46
|
+
* @param {string} sourceAppJsonPath app.json存在的源码路径
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
const getAppJsonContent = (sourceAppJsonPath) => {
|
|
50
|
+
if (!fs.existsSync(sourceAppJsonPath)) {
|
|
51
|
+
fail(`当前路径 ${sourceAppJsonPath} 没找到app.json`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const appJson = JSON.parse(fs.readFileSync(sourceAppJsonPath), 'utf-8');
|
|
55
|
+
// 加入默认值
|
|
56
|
+
appJson.subpackages = [];
|
|
57
|
+
appJson.pages = [];
|
|
58
|
+
// appJson.plugins = {};
|
|
59
|
+
delete appJson.entranceDeclare;
|
|
60
|
+
return appJson;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* 更新app.json中的subpackages
|
|
64
|
+
* @param {Object} appJson
|
|
65
|
+
* @param {Object} modulesConfig
|
|
66
|
+
*/
|
|
67
|
+
const updateSubpackages = (appJson, modulesConfig) => {
|
|
68
|
+
// eslint-disable-next-line
|
|
69
|
+
for (const name in modulesConfig) {
|
|
70
|
+
const moduleInfo = isObject(modulesConfig[name]) ? [modulesConfig[name]] : modulesConfig[name];
|
|
71
|
+
// 过滤 pages 为空的情况
|
|
72
|
+
const validModules = getValidModules(moduleInfo);
|
|
73
|
+
// eslint-disable-next-line
|
|
74
|
+
appJson.subpackages = appJson.subpackages.concat(validModules);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 处理合并subpackages后的appjson, 整理重复不合法的地方
|
|
80
|
+
* @param {Object} appJson appjson
|
|
81
|
+
*/
|
|
82
|
+
const fixAppJson = (appJson) => {
|
|
83
|
+
const { subpackages } = appJson;
|
|
84
|
+
const pluginsMap = {};
|
|
85
|
+
Object.keys(appJson.plugins || {}).forEach(key => pluginsMap[key] = ['app.json']);
|
|
86
|
+
const subps = subpackages.map((subp) => {
|
|
87
|
+
const invalidKeys = [];
|
|
88
|
+
Object.keys(subp).forEach((key) => {
|
|
89
|
+
if (key === 'dependencies') {
|
|
90
|
+
// eslint-disable-next-line
|
|
91
|
+
delete subp.dependencies;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (key === 'plugins') {
|
|
95
|
+
Object.keys(subp.plugins).forEach((pk) => {
|
|
96
|
+
pluginsMap[pk] ? pluginsMap[pk].push(`分包${subp.name}`) : pluginsMap[pk] = [`分包${subp.name}`];
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (MODULE_CONFIG_INVALID_KEY.indexOf(key) > -1) {
|
|
101
|
+
// 如果分包配置中有不支持的key,则错误提醒
|
|
102
|
+
invalidKeys.push(key);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (['requiredBackgroundModes', 'embeddedAppIdList'].indexOf(key) > -1) {
|
|
106
|
+
// 提到appjson最上层处理
|
|
107
|
+
const preVal = appJson[key];
|
|
108
|
+
// eslint-disable-next-line
|
|
109
|
+
preVal ? appJson[key] = Array.from(new Set(preVal
|
|
110
|
+
// eslint-disable-next-line
|
|
111
|
+
.slice(0).concat(subp[key]))) : appJson[key] = subp[key].slice(0);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
if (invalidKeys.length) {
|
|
116
|
+
fail(`不支持分包${subp?.name}配置${invalidKeys.join(',')}\n`);
|
|
117
|
+
}
|
|
118
|
+
// eslint-disable-next-line
|
|
119
|
+
invalidKeys.concat(['requiredBackgroundModes', 'embeddedAppIdList']).forEach(k => delete subp[k]);
|
|
120
|
+
return subp;
|
|
121
|
+
});
|
|
122
|
+
// 如果plugins重复,则错误提示
|
|
123
|
+
const pluginsErrMsg = Object.keys(pluginsMap).map((pk) => {
|
|
124
|
+
if (pluginsMap[pk].length > 1) {
|
|
125
|
+
return `${pluginsMap[pk].join(',')}重复配置plugin(${pk});`;
|
|
126
|
+
}
|
|
127
|
+
return '';
|
|
128
|
+
})
|
|
129
|
+
.reduce((pre, cur) => pre + cur, '');
|
|
130
|
+
if (pluginsErrMsg) {
|
|
131
|
+
fail(`plugins配置出现错误:${pluginsErrMsg}`);
|
|
132
|
+
}
|
|
133
|
+
// eslint-disable-next-line
|
|
134
|
+
appJson.subpackages = subps;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 动态生成编译后的app.json
|
|
139
|
+
* @param {object} tmsConfig
|
|
140
|
+
* @param {array} modules 用户要编译的模块列表
|
|
141
|
+
* @returns
|
|
142
|
+
*/
|
|
143
|
+
function buildOutputAppJson(tmsConfig, modules) {
|
|
144
|
+
try {
|
|
145
|
+
// 获取当前 modules 下的所有子模块的配置内容
|
|
146
|
+
const modulesConfig = getModuleConfig(modules, tmsConfig.appName, MODULE_CONFIG_FILENAME);
|
|
147
|
+
// 获取app.json的配置
|
|
148
|
+
const appJson = getAppJsonContent(resolve('./app.json'));
|
|
149
|
+
// 更新app.json中的subpackages
|
|
150
|
+
updateSubpackages(appJson, modulesConfig);
|
|
151
|
+
// 处理appJson中重复||冲突的地方
|
|
152
|
+
fixAppJson(appJson);
|
|
153
|
+
// 更新主包,需在subpackages处理完成后执行, pages/
|
|
154
|
+
updateMainPackages(appJson, tmsConfig.mainPackages);
|
|
155
|
+
|
|
156
|
+
fs.writeFileSync(resolve(`${tmsConfig.outputDir}/app.json`), JSON.stringify(appJson, null, 2), 'utf8');
|
|
157
|
+
|
|
158
|
+
return appJson;
|
|
159
|
+
} catch (e) {
|
|
160
|
+
handleError(`生成app.json出现错误: ${e}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = {
|
|
165
|
+
buildOutputAppJson,
|
|
166
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const semver = require('semver');
|
|
3
|
-
const { resolve } = require('
|
|
3
|
+
const { resolve } = require('../utils/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`);
|
|
@@ -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
|
-
|
|
46
|
+
const json = JSON.parse(packageJson);
|
|
47
|
+
dependencies = json?.dependencies ? json?.dependencies : {};
|
|
47
48
|
} catch (e) {
|
|
48
|
-
|
|
49
|
-
process.exit(1);
|
|
49
|
+
handleError(`解析${item.srcPackageDir}报错,请检查是否是正确的json配置项 ${e}`);
|
|
50
50
|
}
|
|
51
51
|
const dependenciesKeys = Object.keys(dependencies);
|
|
52
52
|
for (const key of dependenciesKeys) {
|