file-lane 2.0.3-beta.7 → 2.0.3-beta.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/lib/FileLane.js +495 -512
- package/lib/FileLaneCompilation.js +24 -24
- package/lib/enum/FileLaneTriggerType.js +11 -7
- package/lib/event/CompilationEvent.js +13 -11
- package/lib/event/FileEvent.js +11 -9
- package/lib/event/IEventDispatcher.js +4 -1
- package/lib/event/asyncEvent/AsyncEventDispatcher.js +57 -64
- package/lib/event/asyncEvent/DataEvent.js +10 -6
- package/lib/index.js +70 -10
- package/lib/interface/IChangedFile.js +10 -7
- package/lib/interface/IFileLaneConfig.js +1 -2
- package/lib/interface/IFileLaneContext.js +1 -2
- package/lib/interface/IFileLaneEvents.js +1 -2
- package/lib/interface/IFileParam.js +1 -2
- package/lib/interface/ILoader.js +1 -2
- package/lib/interface/IPlugin.js +1 -2
- package/lib/utils/FileLaneUtil.js +54 -49
- package/package.json +3 -3
package/lib/FileLane.js
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const path_1 = __importDefault(require("path"));
|
|
20
|
-
const FileLaneCompilation_1 = __importDefault(require("./FileLaneCompilation"));
|
|
21
|
-
const CompilationEvent_1 = __importDefault(require("./event/CompilationEvent"));
|
|
22
|
-
const FileEvent_1 = __importDefault(require("./event/FileEvent"));
|
|
23
|
-
const FileLaneUtil_1 = __importDefault(require("./utils/FileLaneUtil"));
|
|
24
|
-
const IChangedFile_1 = require("./interface/IChangedFile");
|
|
25
|
-
const FileLaneTriggerType_1 = __importDefault(require("./enum/FileLaneTriggerType"));
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _sharedUtils = require("@aiot-toolkit/shared-utils");
|
|
8
|
+
var _chokidar = _interopRequireDefault(require("chokidar"));
|
|
9
|
+
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
10
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
|
+
var _path = _interopRequireDefault(require("path"));
|
|
12
|
+
var _FileLaneCompilation = _interopRequireDefault(require("./FileLaneCompilation"));
|
|
13
|
+
var _CompilationEvent = _interopRequireDefault(require("./event/CompilationEvent"));
|
|
14
|
+
var _FileEvent = _interopRequireDefault(require("./event/FileEvent"));
|
|
15
|
+
var _FileLaneUtil = _interopRequireDefault(require("./utils/FileLaneUtil"));
|
|
16
|
+
var _IChangedFile = require("./interface/IChangedFile");
|
|
17
|
+
var _FileLaneTriggerType = _interopRequireDefault(require("./enum/FileLaneTriggerType"));
|
|
18
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
26
19
|
/**
|
|
27
20
|
* FileLane
|
|
28
21
|
*
|
|
@@ -44,523 +37,513 @@ const FileLaneTriggerType_1 = __importDefault(require("./enum/FileLaneTriggerTyp
|
|
|
44
37
|
* @description
|
|
45
38
|
*/
|
|
46
39
|
class FileLane {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
40
|
+
// 创建监听实例
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 每次编译的数据对象
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
changeFileList = [];
|
|
47
|
+
triggerCount = 0;
|
|
48
|
+
building = false;
|
|
49
|
+
nextBuildParam = null;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 实例化FileLane
|
|
53
|
+
* @param config fileLane 配置
|
|
54
|
+
* @param projectPath 项目路径
|
|
55
|
+
* @param compilerOption 编译参数,不同语言的项目具有的参数不同,即使同一项目开发者也会设置不同的参数
|
|
56
|
+
* @param events 事件监听器
|
|
57
|
+
*/
|
|
58
|
+
constructor(config, projectPath, compilerOption, events) {
|
|
59
|
+
this.config = config;
|
|
60
|
+
this.compilerOption = compilerOption;
|
|
61
|
+
this.events = events;
|
|
62
|
+
this.context = _FileLaneUtil.default.createContext(config.output, projectPath);
|
|
63
|
+
this.addProcessListener();
|
|
64
|
+
}
|
|
65
|
+
addProcessListener() {
|
|
66
|
+
process.on('beforeExit', this.processBeforeExitHandler);
|
|
67
|
+
process.on('SIGINT', this.sigintHandler);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 运行
|
|
72
|
+
* @param params
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
async start(params) {
|
|
76
|
+
const errorList = this.validateConfig();
|
|
77
|
+
if (errorList && errorList.length) {
|
|
78
|
+
this.handlerLogs([{
|
|
79
|
+
level: _sharedUtils.Loglevel.ERROR,
|
|
80
|
+
message: `### file-lane ### ${errorList.map((item, index) => `${index + 1}. ${item}`).join('\r\n')}`
|
|
81
|
+
}], () => {
|
|
82
|
+
throw new Error(`validate error`);
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
71
85
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
86
|
+
await this.complyBeforeWorks();
|
|
87
|
+
const fileList = this.collectFile();
|
|
88
|
+
if (!fileList || !fileList.length) {
|
|
89
|
+
return;
|
|
75
90
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
* @param params
|
|
79
|
-
* @returns
|
|
80
|
-
*/
|
|
81
|
-
start(params) {
|
|
82
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
-
const errorList = this.validateConfig();
|
|
84
|
-
if (errorList && errorList.length) {
|
|
85
|
-
this.handlerLogs([
|
|
86
|
-
{
|
|
87
|
-
level: shared_utils_1.Loglevel.ERROR,
|
|
88
|
-
message: `### file-lane ### ${errorList.map((item, index) => `${index + 1}. ${item}`).join('\r\n')}`
|
|
89
|
-
}
|
|
90
|
-
], () => {
|
|
91
|
-
throw new Error(`validate error`);
|
|
92
|
-
});
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
yield this.complyBeforeWorks();
|
|
96
|
-
const fileList = this.collectFile();
|
|
97
|
-
if (!fileList || !fileList.length) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (params === null || params === void 0 ? void 0 : params.watch) {
|
|
101
|
-
this.watch();
|
|
102
|
-
}
|
|
103
|
-
yield this.build({
|
|
104
|
-
fileList,
|
|
105
|
-
trigger: FileLaneTriggerType_1.default.START
|
|
106
|
-
});
|
|
107
|
-
});
|
|
91
|
+
if (params?.watch) {
|
|
92
|
+
this.watch();
|
|
108
93
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
94
|
+
await this.build({
|
|
95
|
+
fileList,
|
|
96
|
+
trigger: _FileLaneTriggerType.default.START
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
validateConfig() {
|
|
100
|
+
const result = [];
|
|
101
|
+
// 校验上下文路径,路径是否真实存在,是否为文件夹
|
|
102
|
+
const projectPath = this.context.projectPath;
|
|
103
|
+
if (_fsExtra.default.existsSync(projectPath)) {
|
|
104
|
+
if (!_fsExtra.default.statSync(projectPath).isDirectory()) {
|
|
105
|
+
result.push(`ProjectPath is not a folder`);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
result.push(`ProjectPath is not a real path`);
|
|
109
|
+
}
|
|
110
|
+
if (!this.config) {
|
|
111
|
+
result.push(`Missing config`);
|
|
112
|
+
} else {
|
|
113
|
+
const {
|
|
114
|
+
output,
|
|
115
|
+
module
|
|
116
|
+
} = this.config;
|
|
117
|
+
if (!output) {
|
|
118
|
+
result.push(`Config missing output attribute`);
|
|
119
|
+
}
|
|
120
|
+
if (!module) {
|
|
121
|
+
result.push(`Config missing module attribute`);
|
|
122
|
+
} else {
|
|
123
|
+
if (!module.rules) {
|
|
124
|
+
result.push(`module missing rules attribute`);
|
|
125
|
+
} else if (!module.rules.length) {
|
|
126
|
+
result.push(`module.rules must have at least one item`);
|
|
127
|
+
} else {
|
|
128
|
+
module.rules.forEach((item, index) => {
|
|
129
|
+
if (!item.test) {
|
|
130
|
+
result.push(`rules[${index}] missing test attribute`);
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
else if (!module.rules.length) {
|
|
137
|
-
result.push(`module.rules must have at least one item`);
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
module.rules.forEach((item, index) => {
|
|
141
|
-
if (!item.test) {
|
|
142
|
-
result.push(`rules[${index}] missing test attribute`);
|
|
143
|
-
}
|
|
144
|
-
if (!item.loader) {
|
|
145
|
-
result.push(`rules[${index}] missing loader attribute`);
|
|
146
|
-
}
|
|
147
|
-
else if (!item.loader.length) {
|
|
148
|
-
result.push(`rules[${index}]'loader must have at least one item`);
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
}
|
|
132
|
+
if (!item.loader) {
|
|
133
|
+
result.push(`rules[${index}] missing loader attribute`);
|
|
134
|
+
} else if (!item.loader.length) {
|
|
135
|
+
result.push(`rules[${index}]'loader must have at least one item`);
|
|
152
136
|
}
|
|
137
|
+
});
|
|
153
138
|
}
|
|
154
|
-
|
|
139
|
+
}
|
|
155
140
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
processBeforeExitHandler = () => {
|
|
144
|
+
this.dispose();
|
|
145
|
+
};
|
|
146
|
+
sigintHandler = async () => {
|
|
147
|
+
await this.dispose();
|
|
148
|
+
process.exit();
|
|
149
|
+
};
|
|
150
|
+
async dispose() {
|
|
151
|
+
if (this.watcher) {
|
|
152
|
+
this.watcher.removeAllListeners();
|
|
153
|
+
await this.watcher.close();
|
|
165
154
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
155
|
+
await this.complyAfterWork();
|
|
156
|
+
await this.cleanOutput();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 触发编译
|
|
161
|
+
*
|
|
162
|
+
* 如果:在编译过程中,则记录统参数,待本次 build 完成后,开始下一次
|
|
163
|
+
* 否则:直接触发编译
|
|
164
|
+
*/
|
|
165
|
+
async triggerBuild(param) {
|
|
166
|
+
if (this.building) {
|
|
167
|
+
this.nextBuildParam = param;
|
|
168
|
+
} else {
|
|
169
|
+
this.build(param);
|
|
181
170
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
if (onBuildError) {
|
|
223
|
-
onBuildError === null || onBuildError === void 0 ? void 0 : onBuildError(error);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
shared_utils_1.ColorConsole.throw(`ERROR: `, { word: 'build error' }, `, ${error || 'unknown error'}`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
finally {
|
|
230
|
-
this.building = false;
|
|
231
|
-
if (this.nextBuildParam) {
|
|
232
|
-
this.build(this.nextBuildParam);
|
|
233
|
-
this.nextBuildParam = null;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
*
|
|
175
|
+
* @param fileList 原始文件列表
|
|
176
|
+
*/
|
|
177
|
+
async build(param) {
|
|
178
|
+
const {
|
|
179
|
+
fileList,
|
|
180
|
+
trigger
|
|
181
|
+
} = param;
|
|
182
|
+
const {
|
|
183
|
+
onBuildSuccess,
|
|
184
|
+
onBuildError,
|
|
185
|
+
onBuildStart
|
|
186
|
+
} = this.events || {};
|
|
187
|
+
const timeStart = Date.now();
|
|
188
|
+
this.initCompilation(trigger);
|
|
189
|
+
this.building = true;
|
|
190
|
+
onBuildStart?.();
|
|
191
|
+
try {
|
|
192
|
+
await this.complyBeforeCompile();
|
|
193
|
+
this.triggerPlugins(new _CompilationEvent.default(_CompilationEvent.default.PROJECT_START));
|
|
194
|
+
for (let item of fileList) {
|
|
195
|
+
this.triggerPlugins(new _FileEvent.default(_FileEvent.default.FILE_START_COMPILATION, _FileLaneUtil.default.pathToFileParam(item)));
|
|
196
|
+
await this.buildFile(item);
|
|
197
|
+
this.triggerPlugins(new _FileEvent.default(_FileEvent.default.FILE_END_COMPILATION, _FileLaneUtil.default.pathToFileParam(item)));
|
|
198
|
+
}
|
|
199
|
+
this.triggerPlugins(new _CompilationEvent.default(_CompilationEvent.default.PROJECT_END));
|
|
200
|
+
// 执行extra
|
|
201
|
+
this.triggerPlugins(new _CompilationEvent.default(_CompilationEvent.default.FLLOW_WORK_START));
|
|
202
|
+
await this.complyAfterCompile();
|
|
203
|
+
this.triggerPlugins(new _CompilationEvent.default(_CompilationEvent.default.FLLOW_WORK_END));
|
|
204
|
+
const costTime = Date.now() - timeStart;
|
|
205
|
+
if (onBuildSuccess) {
|
|
206
|
+
onBuildSuccess({
|
|
207
|
+
costTime,
|
|
208
|
+
info: this.compilation?.info
|
|
236
209
|
});
|
|
210
|
+
} else {
|
|
211
|
+
_sharedUtils.ColorConsole.success({
|
|
212
|
+
word: 'build success:'
|
|
213
|
+
}, `${costTime}ms`);
|
|
214
|
+
}
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (onBuildError) {
|
|
217
|
+
onBuildError?.(error);
|
|
218
|
+
} else {
|
|
219
|
+
_sharedUtils.ColorConsole.throw(`ERROR: `, {
|
|
220
|
+
word: 'build error'
|
|
221
|
+
}, `, ${error || 'unknown error'}`);
|
|
222
|
+
}
|
|
223
|
+
} finally {
|
|
224
|
+
this.building = false;
|
|
225
|
+
if (this.nextBuildParam) {
|
|
226
|
+
this.build(this.nextBuildParam);
|
|
227
|
+
this.nextBuildParam = null;
|
|
228
|
+
}
|
|
237
229
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
230
|
+
}
|
|
231
|
+
initCompilation(trigger) {
|
|
232
|
+
const {
|
|
233
|
+
plugins
|
|
234
|
+
} = this.config;
|
|
235
|
+
const compilation = new _FileLaneCompilation.default();
|
|
236
|
+
compilation.trigger = trigger;
|
|
237
|
+
compilation.triggerCount = ++this.triggerCount;
|
|
238
|
+
compilation.info.trigger = trigger;
|
|
239
|
+
plugins?.forEach(item => {
|
|
240
|
+
item.compilation = compilation;
|
|
241
|
+
item.apply();
|
|
242
|
+
});
|
|
243
|
+
this.compilation = compilation;
|
|
244
|
+
}
|
|
245
|
+
async buildFile(filePath) {
|
|
246
|
+
const fileList = await this.runLoaders(filePath);
|
|
247
|
+
await this.writeFiles(fileList);
|
|
248
|
+
}
|
|
249
|
+
async runLoaders(filePath) {
|
|
250
|
+
// 拾取要处理的虚拟文件
|
|
251
|
+
const {
|
|
252
|
+
fileCollector
|
|
253
|
+
} = this.config;
|
|
254
|
+
const collectedFileList = fileCollector ? fileCollector(filePath).map(item => _FileLaneUtil.default.pathToFileParam(item, true)) : [_FileLaneUtil.default.pathToFileParam(filePath, true)];
|
|
255
|
+
// 查找到匹配的 loader
|
|
256
|
+
const loaderList = this.findLoader(filePath);
|
|
257
|
+
// 循环loader,转换文件
|
|
258
|
+
let result = collectedFileList.concat();
|
|
259
|
+
for (let item of loaderList) {
|
|
260
|
+
// 转换 result 为 string 或流
|
|
261
|
+
result.forEach(fileItem => {
|
|
262
|
+
const {
|
|
263
|
+
content
|
|
264
|
+
} = fileItem;
|
|
265
|
+
if (content) {
|
|
266
|
+
if (!item.raw && typeof content !== 'string') {
|
|
267
|
+
fileItem.content = content.toString();
|
|
268
|
+
} else if (item.raw && !(content instanceof Buffer)) {
|
|
269
|
+
fileItem.content = Buffer.from(content);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
const loader = new item();
|
|
274
|
+
result = await this.runLoader(result, loader);
|
|
275
|
+
if (loader.logs) {
|
|
276
|
+
this.handlerLogs(loader.logs, () => {
|
|
277
|
+
throw new Error(`loader error: ${item.name}`);
|
|
247
278
|
});
|
|
248
|
-
|
|
279
|
+
}
|
|
249
280
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* 处理日志
|
|
286
|
+
* 1. 触发onLog事件
|
|
287
|
+
* 2. 如果有错误日志,则抛出错误
|
|
288
|
+
* @param logs
|
|
289
|
+
* @param onError
|
|
290
|
+
* @returns
|
|
291
|
+
*/
|
|
292
|
+
handlerLogs(logs, onError) {
|
|
293
|
+
if (!logs?.length) {
|
|
294
|
+
return;
|
|
255
295
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
// 查找到匹配的 loader
|
|
264
|
-
const loaderList = this.findLoader(filePath);
|
|
265
|
-
// 循环loader,转换文件
|
|
266
|
-
let result = collectedFileList.concat();
|
|
267
|
-
for (let item of loaderList) {
|
|
268
|
-
// 转换 result 为 string 或流
|
|
269
|
-
result.forEach((fileItem) => {
|
|
270
|
-
const { content } = fileItem;
|
|
271
|
-
if (content) {
|
|
272
|
-
if (!item.raw && typeof content !== 'string') {
|
|
273
|
-
fileItem.content = content.toString();
|
|
274
|
-
}
|
|
275
|
-
else if (item.raw && !(content instanceof Buffer)) {
|
|
276
|
-
fileItem.content = Buffer.from(content);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
const loader = new item();
|
|
281
|
-
result = yield this.runLoader(result, loader);
|
|
282
|
-
if (loader.logs) {
|
|
283
|
-
this.handlerLogs(loader.logs, () => {
|
|
284
|
-
throw new Error(`loader error: ${item.name}`);
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return result;
|
|
289
|
-
});
|
|
296
|
+
const onLog = this.events?.onLog;
|
|
297
|
+
if (onLog) {
|
|
298
|
+
onLog(logs);
|
|
299
|
+
} else {
|
|
300
|
+
logs.forEach(item => {
|
|
301
|
+
_sharedUtils.ColorConsole.logger(item);
|
|
302
|
+
});
|
|
290
303
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
* 2. 如果有错误日志,则抛出错误
|
|
295
|
-
* @param logs
|
|
296
|
-
* @param onError
|
|
297
|
-
* @returns
|
|
298
|
-
*/
|
|
299
|
-
handlerLogs(logs, onError) {
|
|
300
|
-
var _a;
|
|
301
|
-
if (!(logs === null || logs === void 0 ? void 0 : logs.length)) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
const onLog = (_a = this.events) === null || _a === void 0 ? void 0 : _a.onLog;
|
|
305
|
-
if (onLog) {
|
|
306
|
-
onLog(logs);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
logs.forEach((item) => {
|
|
310
|
-
shared_utils_1.ColorConsole.logger(item);
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
const hasError = logs.find((item) => item.level && [shared_utils_1.Loglevel.ERROR, shared_utils_1.Loglevel.THROW].includes(item.level));
|
|
314
|
-
if (hasError) {
|
|
315
|
-
onError === null || onError === void 0 ? void 0 : onError();
|
|
316
|
-
}
|
|
304
|
+
const hasError = logs.find(item => item.level && [_sharedUtils.Loglevel.ERROR, _sharedUtils.Loglevel.THROW].includes(item.level));
|
|
305
|
+
if (hasError) {
|
|
306
|
+
onError?.();
|
|
317
307
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
const buildPath = FileLaneUtil_1.default.getOutputPath(this.context);
|
|
324
|
-
if (!fs_extra_1.default.existsSync(buildPath)) {
|
|
325
|
-
shared_utils_1.FileUtil.mkdirSync(buildPath, { hidden: true });
|
|
326
|
-
}
|
|
327
|
-
return Promise.all(fileList.map((item) => {
|
|
328
|
-
const resolvePath = path_1.default.relative(this.context.projectPath, item.path);
|
|
329
|
-
// 将相对路径与输出路径拼接,形成最新的文件路径
|
|
330
|
-
const outputPath = path_1.default.join(buildPath, resolvePath);
|
|
331
|
-
return fs_extra_1.default.outputFile(outputPath, Buffer.from(item.content || ''));
|
|
332
|
-
}));
|
|
333
|
-
});
|
|
308
|
+
}
|
|
309
|
+
async writeFiles(fileList) {
|
|
310
|
+
if (!fileList || !fileList.length) {
|
|
311
|
+
return;
|
|
334
312
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
});
|
|
313
|
+
const buildPath = _FileLaneUtil.default.getOutputPath(this.context);
|
|
314
|
+
if (!_fsExtra.default.existsSync(buildPath)) {
|
|
315
|
+
_sharedUtils.FileUtil.mkdirSync(buildPath, {
|
|
316
|
+
hidden: true
|
|
317
|
+
});
|
|
341
318
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
319
|
+
return Promise.all(fileList.map(item => {
|
|
320
|
+
const resolvePath = _path.default.relative(this.context.projectPath, item.path);
|
|
321
|
+
// 将相对路径与输出路径拼接,形成最新的文件路径
|
|
322
|
+
const outputPath = _path.default.join(buildPath, resolvePath);
|
|
323
|
+
return _fsExtra.default.outputFile(outputPath, Buffer.from(item.content || ''));
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
async runLoader(fileList, loader) {
|
|
327
|
+
loader.context = this.context;
|
|
328
|
+
loader.compilerOption = this.compilerOption;
|
|
329
|
+
return loader.parser(fileList);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* 匹配符合条件的loader
|
|
334
|
+
* @param filePath
|
|
335
|
+
* @returns
|
|
336
|
+
*/
|
|
337
|
+
findLoader(filePath) {
|
|
338
|
+
const parse = _path.default.basename(filePath);
|
|
339
|
+
const rules = this.config.module.rules;
|
|
340
|
+
let loaders = [];
|
|
341
|
+
for (let rule of rules) {
|
|
342
|
+
// 1. 检查filePath是否符合规则test
|
|
343
|
+
if (_sharedUtils.FileUtil.match(parse, rule.test) && _sharedUtils.FileUtil.include(filePath, rule.include, rule.exclude)) {
|
|
344
|
+
// 2. 符合规则就添加到返回列表中
|
|
345
|
+
loaders.push(...rule.loader);
|
|
346
|
+
}
|
|
360
347
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* start开始时的准备工作
|
|
370
|
-
*/
|
|
371
|
-
complyBeforeWorks() {
|
|
372
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
373
|
-
const { beforeWorks } = this.config;
|
|
374
|
-
if (beforeWorks) {
|
|
375
|
-
for (let item of beforeWorks) {
|
|
376
|
-
yield item(this.context);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* start结束后的收尾工作
|
|
383
|
-
*/
|
|
384
|
-
complyAfterWork() {
|
|
385
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
386
|
-
const { afterWorks } = this.config;
|
|
387
|
-
if (afterWorks) {
|
|
388
|
-
for (let item of afterWorks) {
|
|
389
|
-
yield item(this.context);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
});
|
|
348
|
+
return loaders;
|
|
349
|
+
}
|
|
350
|
+
async triggerPlugins(event) {
|
|
351
|
+
if (this.compilation) {
|
|
352
|
+
return this.compilation.dispatch(event);
|
|
393
353
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* start开始时的准备工作
|
|
358
|
+
*/
|
|
359
|
+
async complyBeforeWorks() {
|
|
360
|
+
const {
|
|
361
|
+
beforeWorks
|
|
362
|
+
} = this.config;
|
|
363
|
+
if (beforeWorks) {
|
|
364
|
+
for (let item of beforeWorks) {
|
|
365
|
+
await item(this.context);
|
|
366
|
+
}
|
|
411
367
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
}
|
|
426
|
-
]);
|
|
427
|
-
yield item.worker({
|
|
428
|
-
context: this.context,
|
|
429
|
-
config: this.config,
|
|
430
|
-
compilerOption: this.compilerOption,
|
|
431
|
-
compalition: this.compilation
|
|
432
|
-
});
|
|
433
|
-
this.handlerLogs([
|
|
434
|
-
{
|
|
435
|
-
level: shared_utils_1.Loglevel.INFO,
|
|
436
|
-
message: `FollowWork: ${item.workerDescribe} end`
|
|
437
|
-
}
|
|
438
|
-
]);
|
|
439
|
-
}
|
|
440
|
-
catch (error) {
|
|
441
|
-
throw new Error(`FollowWork: ${item.workerDescribe} error: ${error}`);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
});
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* start结束后的收尾工作
|
|
372
|
+
*/
|
|
373
|
+
async complyAfterWork() {
|
|
374
|
+
const {
|
|
375
|
+
afterWorks
|
|
376
|
+
} = this.config;
|
|
377
|
+
if (afterWorks) {
|
|
378
|
+
for (let item of afterWorks) {
|
|
379
|
+
await item(this.context);
|
|
380
|
+
}
|
|
446
381
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* 执行项目转换的前置工作
|
|
386
|
+
*/
|
|
387
|
+
async complyBeforeCompile() {
|
|
388
|
+
const {
|
|
389
|
+
beforeCompile
|
|
390
|
+
} = this.config;
|
|
391
|
+
if (beforeCompile) {
|
|
392
|
+
for (let item of beforeCompile) {
|
|
393
|
+
await item({
|
|
394
|
+
context: this.context,
|
|
395
|
+
config: this.config,
|
|
396
|
+
compilerOption: this.compilerOption,
|
|
397
|
+
compalition: this.compilation
|
|
462
398
|
});
|
|
399
|
+
}
|
|
463
400
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* 执行项目转换的后续工作
|
|
405
|
+
*/
|
|
406
|
+
async complyAfterCompile() {
|
|
407
|
+
const {
|
|
408
|
+
afterCompile
|
|
409
|
+
} = this.config;
|
|
410
|
+
if (afterCompile) {
|
|
411
|
+
for (let item of afterCompile) {
|
|
412
|
+
try {
|
|
413
|
+
this.handlerLogs([{
|
|
414
|
+
level: _sharedUtils.Loglevel.INFO,
|
|
415
|
+
message: `FollowWork: ${item.workerDescribe} start`
|
|
416
|
+
}]);
|
|
417
|
+
await item.worker({
|
|
418
|
+
context: this.context,
|
|
419
|
+
config: this.config,
|
|
420
|
+
compilerOption: this.compilerOption,
|
|
421
|
+
compalition: this.compilation
|
|
422
|
+
});
|
|
423
|
+
this.handlerLogs([{
|
|
424
|
+
level: _sharedUtils.Loglevel.INFO,
|
|
425
|
+
message: `FollowWork: ${item.workerDescribe} end`
|
|
426
|
+
}]);
|
|
427
|
+
} catch (error) {
|
|
428
|
+
throw new Error(`FollowWork: ${item.workerDescribe} error: ${error}`);
|
|
479
429
|
}
|
|
480
|
-
|
|
481
|
-
// 1.取出projectPath
|
|
482
|
-
const projectPath = this.context.projectPath;
|
|
483
|
-
// 2. 循环文件夹,取出所有匹配的文件路径
|
|
484
|
-
files = shared_utils_1.FileUtil.readAlldirSync(projectPath, this.config.include, this.config.exclude);
|
|
485
|
-
}
|
|
486
|
-
return files;
|
|
430
|
+
}
|
|
487
431
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
.on('change', (path) => {
|
|
517
|
-
// 监听文件修改事件
|
|
518
|
-
handler(path, IChangedFile_1.HandlerType.CHANGE);
|
|
519
|
-
})
|
|
520
|
-
.on('unlink', (filePath) => {
|
|
521
|
-
// 监听文件删除事件
|
|
522
|
-
handler(filePath, IChangedFile_1.HandlerType.UNLINK);
|
|
523
|
-
});
|
|
524
|
-
})
|
|
525
|
-
.on('error', (error) => {
|
|
526
|
-
// 监听错误
|
|
527
|
-
FileLaneUtil_1.default.checkError(error.message);
|
|
528
|
-
watcher.close();
|
|
529
|
-
});
|
|
530
|
-
if (this.watcher) {
|
|
531
|
-
this.watcher.close();
|
|
432
|
+
}
|
|
433
|
+
async watch() {
|
|
434
|
+
// 监听文件变化,并触发 build
|
|
435
|
+
const onChange = async () => {
|
|
436
|
+
const fileList = this.config.collectFile ? this.config.collectFile(this.changeFileList) : this.collectFile();
|
|
437
|
+
// 开始编译前,记录列表置空
|
|
438
|
+
this.changeFileList = [];
|
|
439
|
+
await this.triggerBuild({
|
|
440
|
+
fileList,
|
|
441
|
+
trigger: _FileLaneTriggerType.default.UPDATE
|
|
442
|
+
});
|
|
443
|
+
};
|
|
444
|
+
this.listenFileChange(onChange);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* 采集所有要处理的真实文件路径列表
|
|
449
|
+
* @param entryFileList
|
|
450
|
+
* @returns
|
|
451
|
+
*/
|
|
452
|
+
collectFile(entryFileList) {
|
|
453
|
+
// 使用include projectPath获取所有要处理的真实文件
|
|
454
|
+
let files = [];
|
|
455
|
+
if (entryFileList) {
|
|
456
|
+
entryFileList.forEach(filePath => {
|
|
457
|
+
if (_sharedUtils.FileUtil.include(filePath, this.config.include, this.config.exclude)) {
|
|
458
|
+
_sharedUtils.ColorConsole.log(`### file-lane ### file change: ${filePath}`);
|
|
459
|
+
files.push(filePath);
|
|
532
460
|
}
|
|
533
|
-
|
|
461
|
+
});
|
|
462
|
+
} else {
|
|
463
|
+
// 1.取出projectPath
|
|
464
|
+
const projectPath = this.context.projectPath;
|
|
465
|
+
// 2. 循环文件夹,取出所有匹配的文件路径
|
|
466
|
+
files = _sharedUtils.FileUtil.readAlldirSync(projectPath, this.config.include, this.config.exclude);
|
|
534
467
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
468
|
+
return files;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* 监听文件变化
|
|
473
|
+
* @param onChange
|
|
474
|
+
*/
|
|
475
|
+
listenFileChange(onChange) {
|
|
476
|
+
const watcher = _chokidar.default.watch(this.context.projectPath, {
|
|
477
|
+
ignored: this.getIgnoreConfig()
|
|
478
|
+
});
|
|
479
|
+
const throttledOnChange = _lodash.default.throttle(onChange, 1000, {
|
|
480
|
+
leading: false,
|
|
481
|
+
trailing: true
|
|
482
|
+
});
|
|
483
|
+
const handler = (path, type) => {
|
|
484
|
+
const {
|
|
485
|
+
exclude,
|
|
486
|
+
include
|
|
487
|
+
} = this.config;
|
|
488
|
+
// 执行onChange回调
|
|
489
|
+
const validFile = _sharedUtils.FileUtil.include(path, include, exclude);
|
|
490
|
+
if (validFile) {
|
|
491
|
+
this.changeFileList.push({
|
|
492
|
+
path,
|
|
493
|
+
type
|
|
541
494
|
});
|
|
495
|
+
throttledOnChange();
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
watcher.on('ready', () => {
|
|
499
|
+
watcher.on('add', path => {
|
|
500
|
+
// 监听文件添加事件
|
|
501
|
+
handler(path, _IChangedFile.HandlerType.ADD);
|
|
502
|
+
}).on('change', path => {
|
|
503
|
+
// 监听文件修改事件
|
|
504
|
+
handler(path, _IChangedFile.HandlerType.CHANGE);
|
|
505
|
+
}).on('unlink', filePath => {
|
|
506
|
+
// 监听文件删除事件
|
|
507
|
+
handler(filePath, _IChangedFile.HandlerType.UNLINK);
|
|
508
|
+
});
|
|
509
|
+
}).on('error', error => {
|
|
510
|
+
// 监听错误
|
|
511
|
+
_FileLaneUtil.default.checkError(error.message);
|
|
512
|
+
watcher.close();
|
|
513
|
+
});
|
|
514
|
+
if (this.watcher) {
|
|
515
|
+
this.watcher.close();
|
|
542
516
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
ignoreList.push(
|
|
563
|
-
|
|
517
|
+
this.watcher = watcher;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* 清除输出文件夹
|
|
522
|
+
*/
|
|
523
|
+
async cleanOutput() {
|
|
524
|
+
return _sharedUtils.FileUtil.del(_FileLaneUtil.default.getOutputPath(this.context));
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* 1. 配置的忽略文件夹
|
|
528
|
+
* 2. 默认应该忽略的文件及文件夹
|
|
529
|
+
* @returns
|
|
530
|
+
*/
|
|
531
|
+
getIgnoreConfig() {
|
|
532
|
+
let ignoreList = [];
|
|
533
|
+
// 1.
|
|
534
|
+
if (this.config.watchIgnores) {
|
|
535
|
+
if (Array.isArray(this.config.watchIgnores)) {
|
|
536
|
+
ignoreList.push(...this.config.watchIgnores);
|
|
537
|
+
} else {
|
|
538
|
+
ignoreList.push(this.config.watchIgnores);
|
|
539
|
+
}
|
|
564
540
|
}
|
|
541
|
+
// 2. 忽略.开头的隐藏文件夹
|
|
542
|
+
ignoreList.push(/(^|[\/\\])\../);
|
|
543
|
+
|
|
544
|
+
// 3. 忽略output目录
|
|
545
|
+
ignoreList.push(_path.default.join(this.context.projectPath, this.config.output));
|
|
546
|
+
return ignoreList;
|
|
547
|
+
}
|
|
565
548
|
}
|
|
566
|
-
exports.default = FileLane;
|
|
549
|
+
var _default = exports.default = FileLane;
|