@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.
- package/README.md +18 -2
- package/dist/index.cjs.js +1852 -1050
- package/package.json +24 -6
- package/src/config/constant.js +5 -2
- package/src/config/defaultTmsConfig.js +9 -10
- package/src/entry.js +48 -8
- package/src/gulp/build.js +5 -0
- package/src/gulp/compile.js +87 -0
- package/src/gulp/dev.js +102 -0
- package/src/gulp/plugins/less.js +116 -0
- package/src/gulp/plugins/mpCommonDep.js +131 -0
- package/src/gulp/plugins/mpJsonDep.js +108 -0
- package/src/gulp/plugins/mpWxmlDep.js +194 -0
- package/src/gulp/plugins/postcss-font-base64.js +72 -0
- package/src/gulp/plugins/replaceEnv.js +29 -0
- package/src/gulp/plugins/utils/pluginError.js +25 -0
- package/src/index.js +24 -9
- package/src/init.js +0 -5
- package/src/scripts/run/build/index.js +5 -4
- package/src/scripts/run/dev/index.js +30 -13
- package/src/scripts/run/index.js +30 -25
- package/src/scripts/run/init/index.js +31 -41
- package/src/scripts/run/install/index.js +19 -29
- package/src/utils/buildAppJson.js +100 -23
- package/src/utils/checkDependencies.js +6 -6
- package/src/utils/cloneModules.js +39 -13
- package/src/utils/findCssImport.js +30 -0
- package/src/utils/handleError.js +16 -0
- package/src/utils/io.js +85 -0
- package/src/utils/mpCiUtils.js +0 -1
- package/src/utils/npmUtils.js +77 -37
- package/src/utils/tkitUtils.js +90 -16
- package/src/utils/widgets.js +11 -14
- package/CHANGELOG.md +0 -0
- package/rollup.config.js +0 -179
- 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,108 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
const through = require('through2');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { ext, fileInDir, diffContentCopyFile } = require('../../utils/io');
|
|
5
|
+
const { resolve } = require('../../utils/widgets');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const { pluginError } = require('./utils/pluginError');
|
|
8
|
+
const { dfsFindCommonDep } = require('./mpCommonDep');
|
|
9
|
+
|
|
10
|
+
function mpJsonDep(
|
|
11
|
+
tmsConfig,
|
|
12
|
+
module,
|
|
13
|
+
extensions = ['.json'],
|
|
14
|
+
filesExt = ['.wxml', '.json', '.js', '.ts', '.wxss', '.less'],
|
|
15
|
+
isWatch,
|
|
16
|
+
) {
|
|
17
|
+
const stream = through.obj(function (file, enc, cb) {
|
|
18
|
+
// 当前分析的文件的路径
|
|
19
|
+
const anaFileOriginFile = file.history[0];
|
|
20
|
+
const anaFileRelativeModule = path.relative(resolve(module.from), anaFileOriginFile);
|
|
21
|
+
const anaFileDestFile = resolve(tmsConfig.outputDir, module.to, anaFileRelativeModule);
|
|
22
|
+
|
|
23
|
+
if (file.isBuffer()) {
|
|
24
|
+
const copyModules = new Map();
|
|
25
|
+
let contents = String(file.contents);
|
|
26
|
+
try {
|
|
27
|
+
contents = JSON.parse(contents);
|
|
28
|
+
if (contents.usingComponents) {
|
|
29
|
+
Object.keys(tmsConfig.dependencies).forEach((includeName) => {
|
|
30
|
+
const includePath = tmsConfig.dependencies[includeName];
|
|
31
|
+
Object.keys(contents.usingComponents).forEach((componentKey) => {
|
|
32
|
+
const componentPath = contents.usingComponents[componentKey];
|
|
33
|
+
if (componentPath.indexOf(includeName) > -1) {
|
|
34
|
+
const depOriginPath = path.join(path.dirname(anaFileOriginFile), componentPath);
|
|
35
|
+
// 被依赖文件加上后缀
|
|
36
|
+
const { ext: extAlias, file: depOriginFile, extPath } = ext(depOriginPath, extensions);
|
|
37
|
+
|
|
38
|
+
const isFileInDir = fileInDir(includePath, depOriginFile);
|
|
39
|
+
if (!isFileInDir) {
|
|
40
|
+
pluginError(
|
|
41
|
+
new Error(`${anaFileOriginFile}引用的路径${depOriginFile}不在${includePath}不在文件夹内, 请检查应用路径`),
|
|
42
|
+
isWatch,
|
|
43
|
+
);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// eslint-disable-next-line
|
|
48
|
+
const reg = new RegExp(`^(\.\.\/)+.*\/${includeName}\/(.*)`);
|
|
49
|
+
const regRes = componentPath.match(reg) || [];
|
|
50
|
+
if (regRes[2]) {
|
|
51
|
+
const depDestPath = resolve(tmsConfig.outputDir, module.to, includeName, regRes[2]);
|
|
52
|
+
const depDestFile = depDestPath.endsWith(extAlias) ? depDestPath : depDestPath + extPath;
|
|
53
|
+
|
|
54
|
+
if (!copyModules.has(depDestFile)) {
|
|
55
|
+
copyModules.set(depDestFile, {
|
|
56
|
+
depOriginFile,
|
|
57
|
+
depOriginExt: extAlias,
|
|
58
|
+
depDestFile,
|
|
59
|
+
beforeDepPath: componentPath,
|
|
60
|
+
afterDepPath: path.relative(path.dirname(anaFileDestFile), depDestPath).replace(/\\/g, '/'),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
} catch (e) {
|
|
69
|
+
pluginError(e, isWatch);
|
|
70
|
+
}
|
|
71
|
+
// console.log('json copyModules', copyModules);
|
|
72
|
+
copyModules.forEach(({ depOriginFile, depOriginExt, depDestFile, beforeDepPath, afterDepPath }) => {
|
|
73
|
+
// 拷贝当前依赖组件几个部分 wxml、wxss、wxs、json
|
|
74
|
+
filesExt.forEach((extKey) => {
|
|
75
|
+
const originFile = depOriginFile.replace(depOriginExt, extKey);
|
|
76
|
+
const destFile = depDestFile.replace(depOriginExt, extKey);
|
|
77
|
+
|
|
78
|
+
if (fs.existsSync(originFile)) {
|
|
79
|
+
diffContentCopyFile(originFile, destFile);
|
|
80
|
+
|
|
81
|
+
const extensionsFilter = ['.js', '.ts', '.wxss', '.less'];
|
|
82
|
+
if (extensionsFilter.indexOf(extKey) > -1) {
|
|
83
|
+
const defs = dfsFindCommonDep(originFile, destFile, extensionsFilter);
|
|
84
|
+
// console.log('json defs', defs);
|
|
85
|
+
defs.forEach((item) => {
|
|
86
|
+
diffContentCopyFile(item.depOriginFile, item.depDestFile);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
contents = typeof contents === 'object' ? JSON.stringify(contents, null, 2) : contents;
|
|
92
|
+
const reg = new RegExp(`['"]${beforeDepPath}["']`, 'g');
|
|
93
|
+
contents = contents.replace(reg, `"${afterDepPath}"`);
|
|
94
|
+
});
|
|
95
|
+
contents = typeof contents === 'object' ? JSON.stringify(contents, null, 2) : contents;
|
|
96
|
+
file.contents = Buffer.from(contents);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.push(file);
|
|
100
|
+
cb();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return stream;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
mpJsonDep,
|
|
108
|
+
};
|
|
@@ -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/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
-
const
|
|
2
|
+
const commander = require('commander');
|
|
3
3
|
const { log, suggestCommands } = require('./utils/widgets');
|
|
4
4
|
const { TMS_NAME } = require('./config/constant.js');
|
|
5
5
|
const commands = require('./entry');
|
|
@@ -7,20 +7,35 @@ const init = require('./init');
|
|
|
7
7
|
|
|
8
8
|
init();
|
|
9
9
|
|
|
10
|
+
const program = new commander.Command(TMS_NAME);
|
|
11
|
+
|
|
10
12
|
program
|
|
11
|
-
.version(`${TMS_NAME} ${require('../package.json').version}
|
|
13
|
+
.version(`${TMS_NAME} ${require('../package.json').version}`, '-v, -V, --version');
|
|
12
14
|
|
|
13
|
-
commands
|
|
14
|
-
|
|
15
|
+
function registerCommand(program, commands) {
|
|
16
|
+
commands.forEach((cmd) => {
|
|
17
|
+
if (cmd.type === 'child') {
|
|
18
|
+
const childProgram = new commander.Command(cmd.name);
|
|
19
|
+
cmd.usage && childProgram.usage(cmd.usage);
|
|
20
|
+
cmd.description && childProgram.description(cmd.description);
|
|
21
|
+
registerCommand(childProgram, cmd.commands);
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
program.addCommand(childProgram);
|
|
24
|
+
} else {
|
|
25
|
+
const command = program.command(cmd.command);
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
cmd.usage && command.usage(cmd.usage);
|
|
19
28
|
|
|
20
|
-
|
|
29
|
+
cmd.description && command.description(cmd.description);
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
cmd.options?.forEach(opt => command.option(...opt));
|
|
32
|
+
|
|
33
|
+
command.action(cmd.action);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
registerCommand(program, commands);
|
|
24
39
|
|
|
25
40
|
program.on('--help', () => {
|
|
26
41
|
log();
|
package/src/init.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const { exec } = require('shelljs');
|
|
2
1
|
const semver = require('semver');
|
|
3
2
|
const packageJson = require('../package.json');
|
|
4
3
|
const chalk = require('chalk');
|
|
@@ -29,10 +28,6 @@ function initCliContext() {
|
|
|
29
28
|
// 执行操作前检查node版本
|
|
30
29
|
// 旧版本node直接提示升级,退出脚本
|
|
31
30
|
checkNodeVersion(requiredVersion, packName);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// 执行前配置正确的npm源
|
|
35
|
-
exec('npm config set registry https://mirrors.tencent.com/npm/ --global', { silent: true });
|
|
36
31
|
}
|
|
37
32
|
|
|
38
33
|
module.exports = initCliContext;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
const shelljs = require('shelljs');
|
|
2
|
-
const webpackBuildServer = require('../../../webpack/buildServer');
|
|
3
2
|
const { resolve } = require('../../../utils/widgets');
|
|
4
3
|
const init = require('../init/index');
|
|
4
|
+
const gulpBuild = require('../../../gulp/build');
|
|
5
5
|
|
|
6
6
|
async function build(tmsConfig, targetModules, env) {
|
|
7
7
|
// 开始构建前,清理输出目录
|
|
8
|
-
await shelljs.rm('-rf', resolve(
|
|
8
|
+
await shelljs.rm('-rf', resolve(tmsConfig.outputDir));
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const isDev = false;
|
|
11
|
+
const { targetModules: newModules } = await init(tmsConfig, targetModules, isDev);
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
gulpBuild(tmsConfig, newModules, env);
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
module.exports = build;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
const
|
|
1
|
+
const gulpDev = require('../../../gulp/dev');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const { resolve } = require('../../../utils/widgets');
|
|
4
4
|
const init = require('../init/index');
|
|
5
|
-
const {
|
|
5
|
+
const { MODULE_CONFIG_FILENAME } = require('../../../config/constant');
|
|
6
6
|
const { tmsModulesMergeLocalModuleCfg } = require('../../../utils/tkitUtils');
|
|
7
7
|
const { checkDependencies } = require('../../../utils/checkDependencies');
|
|
8
8
|
const { fail } = require('../../../utils/log');
|
|
9
|
+
const shelljs = require('shelljs');
|
|
10
|
+
// const io = require('../../../utils/io');
|
|
9
11
|
|
|
10
|
-
function isInit(tmsConfig, targetModules, contextDir) {
|
|
12
|
+
function isInit(tmsConfig, targetModules, contextDir, isDev) {
|
|
11
13
|
// 判断是否存在dist目录
|
|
12
14
|
if (!fs.existsSync(contextDir)) {
|
|
13
15
|
return true;
|
|
@@ -33,8 +35,8 @@ function isInit(tmsConfig, targetModules, contextDir) {
|
|
|
33
35
|
if (!item.root) {
|
|
34
36
|
return true;
|
|
35
37
|
}
|
|
36
|
-
//
|
|
37
|
-
if (!fs.existsSync(`${contextDir}/${item.root}`)) {
|
|
38
|
+
// 判断dist目录是否有该模块
|
|
39
|
+
if (!fs.existsSync(`${contextDir}/${item.root}/${MODULE_CONFIG_FILENAME}`)) {
|
|
38
40
|
return true;
|
|
39
41
|
}
|
|
40
42
|
// 判断源码目录是否有该模块
|
|
@@ -45,22 +47,37 @@ function isInit(tmsConfig, targetModules, contextDir) {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
// 判断package.json的版本是否有新的版本
|
|
48
|
-
return checkDependencies(targetModules, resolve('./'), tmsConfig.
|
|
50
|
+
return checkDependencies(targetModules, resolve('./'), tmsConfig.outputDir, isDev);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 用户编译分包时,需要将dist中其他分包(主包不能删除)的内容删除,否则其他分包的内容混入到主包(导致主包的体积超2M)
|
|
54
|
+
function delOtherModule(tmsConfig, targetModules) {
|
|
55
|
+
const modules = tmsModulesMergeLocalModuleCfg(tmsConfig.modules, tmsConfig.appName);
|
|
56
|
+
const targetModulesName = targetModules.map(item => item.name);
|
|
57
|
+
modules.forEach((item) => {
|
|
58
|
+
if (item.root && targetModulesName.indexOf(item.name) === -1) {
|
|
59
|
+
const moduleRootDir = resolve(`dist/${item.root}`);
|
|
60
|
+
shelljs.rm('-rf', `${moduleRootDir}/*`, { silent: true });
|
|
61
|
+
// 解决微信开发者工具(dist/app.json: ["subpackages"][0]["root"] 字段需为 目录)错误 - 提前创建该目录
|
|
62
|
+
// io.ensureDirExist(moduleRootDir);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
async function dev(tmsConfig, targetModules, env) {
|
|
52
|
-
|
|
53
|
-
|
|
68
|
+
let newModules = targetModules;
|
|
69
|
+
const isDev = true;
|
|
54
70
|
|
|
55
71
|
// 判断是否进行init命令
|
|
56
|
-
if (isInit(tmsConfig,
|
|
57
|
-
// init
|
|
58
|
-
const initData = await init(tmsConfig,
|
|
72
|
+
if (isInit(tmsConfig, targetModules, resolve('dist'), isDev)) {
|
|
73
|
+
// init函数 下载第三方代码后,会将最新的tms.config.js的modules 合并 module.config.json的配置项返回
|
|
74
|
+
const initData = await init(tmsConfig, newModules, isDev);
|
|
59
75
|
newModules = initData.targetModules;
|
|
60
76
|
}
|
|
61
77
|
|
|
62
|
-
console.log('当前dev启动的有效模块', newModules.map(item => item.name));
|
|
63
|
-
|
|
78
|
+
console.log('当前dev启动的有效模块', newModules.map(item => item.name).sort());
|
|
79
|
+
delOtherModule(tmsConfig, newModules);
|
|
80
|
+
gulpDev(tmsConfig, newModules, env);
|
|
64
81
|
}
|
|
65
82
|
|
|
66
83
|
module.exports = dev;
|