file-lane 2.0.2-beta.13 → 2.0.2-beta.14

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 CHANGED
@@ -1,13 +1,247 @@
1
- # `file-lane`
1
+ # 项目介绍
2
2
 
3
- 用于文件转换,可1个文件转换为1个文件,也可1转多、多转1
3
+ file-lane模块用于文件转换,可实现文件11的转换,也可实现1对多、多对1的文件转换。
4
4
 
5
- <img src="./doc/flow.jpg" style="max-width: 1000px; width: 100%"/>
5
+ <img src="./doc/flow-detail.png" style="max-width: 1000px; width: 100%"/>
6
6
 
7
- ## Usage
7
+ ## 安装使用
8
+
9
+ - 安装
10
+
11
+ `npm i file-lane`
12
+
13
+ - 快速上手
14
+
15
+ ```javascript
16
+ const { FileLane } = require('file-lane')
17
+ const { UxLoader } = require('aiot-toolkit/aiotpack')
18
+ const Path = require('path')
19
+
20
+ const projectPath = Path.join(__dirname, '../testProject')
21
+
22
+ // 定义项目转换的配置参数,output和module为必要配置内容
23
+ const projectConfig = {
24
+ // output指定转换后项目的存储位置
25
+ get output() {
26
+ const name = Path.basename(projectPath)
27
+ const result = `../.temp_${name}`
28
+ return result
29
+ },
30
+ // 转换过程中使用的转换模块配置
31
+ module: {
32
+ rules: [
33
+ {
34
+ test: [/.+\.ux$/],
35
+ exclude: [/app\.ux/],
36
+ loader: [UxLoader]
37
+ }
38
+ ]
39
+ }
40
+ }
41
+
42
+ // 开始执行文件转换
43
+ new FileLane(projectConfig).start()
44
+ // 开启watch模式
45
+ // new FileLane(projectConfig).start({ watch: true })
46
+ ```
47
+
48
+ ## 参数配置
49
+
50
+ - 必填参数
51
+ - [output](#output)
52
+ - [module](#module)
53
+ - 可选参数
54
+ - [fileCollector](#fileCollector)
55
+ - [include](#include)
56
+ - [exclude](#exclude)
57
+ - [plugins](#plugins)
58
+ - [preWorks](#preWorks)
59
+ - [followWorks](#followWorks)
60
+ - [watchIgnores](#watchIgnores)
61
+
62
+ <a id="output">output</a>
63
+
64
+ 描述: 输出目录
65
+
66
+ 参数类型: string
67
+
68
+ 示例:
69
+
70
+ ```
71
+ 'temp_project'
72
+ ```
73
+
74
+ <a id="module">module</a>
75
+
76
+ 描述: 文件转换规则集
77
+
78
+ 参数类型: { rules: IRule[] } // IRule:转换规则
79
+
80
+ ```javascript
81
+ interface IRule {
82
+ // 配置文件
83
+ test: MatchType
84
+
85
+ // 文件的 Loader,从前向后依次执行,前一个 loader 结果做为后一个 loader 的入参
86
+ loader: ILoaderClass[]
87
+ exclude?: MatchType
88
+ include?: MatchType
89
+ }
90
+ ```
91
+
92
+ 示例:
8
93
 
9
94
  ```
10
- const fileLane = require('file-lane');
95
+ {
96
+ rules: [
97
+ {
98
+ test: [/.+\.ux$/],
99
+ exclude: [/app\.ux/],
100
+ loader: [UxLoader]
101
+ }
102
+ ]
103
+ }
104
+
105
+ ```
106
+
107
+ <a id="fileCollector">fileCollector</a>
108
+
109
+ 描述: 文件收集器,输入文件路径,返回待合并的文件路径,常用于多转1,默认值为直接使用源文件
110
+
111
+ 参数类型:
112
+
113
+ ```
114
+ (file: string) => string[]
115
+ ```
116
+
117
+ 示例:
118
+
119
+ ```javascript
120
+ // src/a.hml -->[src/a.hml, src/a.js, src/a.css]
121
+ (file: string) => {
122
+ const fileList = [file]
123
+ const { dir, name, ext } = path.parse(file)
124
+
125
+ if (ext === '.hml') {
126
+ ['.js', '.css'].map((item) => {
127
+ const collectFile = path.join(dir, `${name}${item}`)
128
+ // 若路径真实存在,则push到文件列表中
129
+ if (fs.existsSync(collectFile)) {
130
+ fileList.push(collectFile)
131
+ }
132
+ })
133
+ return fileList
134
+ }
135
+ }
136
+ ```
137
+
138
+ <a id="include">include</a>
139
+
140
+ 描述: 指定文件范围
141
+
142
+ 参数类型:
143
+
144
+ ```
145
+ OneMatchType | OneMatchType[]
146
+ ```
147
+
148
+ 示例:
149
+
150
+ ```javascript
151
+ // 匹配包含有src字符串的文件
152
+ include = ['src']
153
+ ```
154
+
155
+ <a id="exclude">exclude</a>
156
+
157
+ 描述: 需排除的文件范围
158
+
159
+ 参数类型:
160
+
161
+ ```
162
+ OneMatchType | OneMatchType[]
163
+ ```
164
+
165
+ 示例:
166
+
167
+ ```javascript
168
+ // 排除路径中包含有node_modules字符串的文件
169
+ exclude = [/node_modules/]
170
+ ```
171
+
172
+ <a id="plugins">plugins</a>
173
+
174
+ 描述: 插件,在每个文件转换完成前后,所有文件转换完成前后,在打包完成前后会触发
175
+
176
+ 参数类型:
177
+
178
+ ```
179
+ IPlugin[]
180
+ ```
181
+
182
+ 示例:
183
+
184
+ ```
185
+
186
+ ```
187
+
188
+ <a id="preWorks">preWorks</a>
189
+
190
+ 描述: 前置工作,所有文件转换前的工作
191
+
192
+ 参数类型:
193
+
194
+ ```
195
+ PreWork[]
196
+ ```
197
+
198
+ 示例:
199
+
200
+ ```javascript
201
+ preWorks = [validateManifest]
202
+
203
+ const validateManifest: PreWork<IJavascriptCompileOption> = async (context) => {
204
+ // 校验manifest.json文件的内容
205
+ }
206
+ ```
207
+
208
+ <a id="followWorks">followWorks</a>
209
+
210
+ 描述: 后续工作,所有文件转换后的工作
211
+
212
+ 参数类型:
213
+
214
+ ```
215
+ FollowWoker<O>[]
216
+ ```
217
+
218
+ 示例:
219
+
220
+ ```javascript
221
+ followWorks = [
222
+ {
223
+ worker: toRpk,
224
+ workerDescribe: 'follow work'
225
+ }
226
+ ]
227
+
228
+ const toRpk: FollowWork<IJavascriptCompileOption> = async (context, config, compilerOption) => {
229
+ // 生成rpk逻辑
230
+ }
231
+ ```
232
+
233
+ <a id="watchIgnores">watchIgnores</a>
234
+
235
+ 描述: 配置watch时忽略的文件或者文件夹
236
+
237
+ 参数类型:
238
+
239
+ ```
240
+ MatchType
241
+ ```
242
+
243
+ 示例:
11
244
 
12
- // TODO: DEMONSTRATE API
245
+ ```javascript
246
+ watchIgnores = [/node_modules/, '/build/', '/dist/']
13
247
  ```
package/lib/FileLane.d.ts CHANGED
@@ -20,7 +20,9 @@ declare class FileLane<O = any> {
20
20
  * @param compilerOption 编译参数,不同语言的项目具有的参数不同,即使同一项目开发者也会设置不同的参数
21
21
  */
22
22
  constructor(config: IFileLaneConfig<O>, projectPath?: string, compilerOption?: O | undefined, events?: {
23
- onBuildSuccess?: (() => void) | undefined;
23
+ onBuildSuccess?: ((data: {
24
+ costTime: number;
25
+ }) => void) | undefined;
24
26
  } | undefined);
25
27
  /**
26
28
  * 运行
@@ -57,13 +59,21 @@ declare class FileLane<O = any> {
57
59
  private findLoader;
58
60
  private triggerPlugins;
59
61
  /**
60
- * 运行转换初始的任务
62
+ * start开始时的准备工作
61
63
  */
62
- private runPreWorks;
64
+ private complyBeforeWorks;
63
65
  /**
64
- * 运行转换后续的任务
66
+ * start结束后的收尾工作
65
67
  */
66
- private runFollowWorks;
68
+ private complyAfterWork;
69
+ /**
70
+ * 执行项目转换的前置工作
71
+ */
72
+ private complyBeforeCompile;
73
+ /**
74
+ * 执行项目转换的后续工作
75
+ */
76
+ private complyAfterCompile;
67
77
  private watch;
68
78
  /**
69
79
  * 采集所有要处理的真实文件路径列表
@@ -76,7 +86,6 @@ declare class FileLane<O = any> {
76
86
  * @param onChange
77
87
  */
78
88
  private listenFileChange;
79
- private get outputPath();
80
89
  /**
81
90
  * 清除输出文件夹
82
91
  */
package/lib/FileLane.js CHANGED
@@ -58,7 +58,7 @@ class FileLane {
58
58
  shared_utils_1.ColorConsole.error(`### file-lane ### ${errorList.map((item, index) => `${index + 1}. ${item}`).join('\r\n')}`);
59
59
  return;
60
60
  }
61
- yield this.cleanOutput();
61
+ yield this.complyBeforeWorks();
62
62
  const fileList = this.collectFile();
63
63
  if (!fileList || !fileList.length) {
64
64
  return;
@@ -121,6 +121,7 @@ class FileLane {
121
121
  process.exit();
122
122
  }
123
123
  dispose() {
124
+ this.complyAfterWork();
124
125
  if (this.watcher) {
125
126
  this.watcher.close();
126
127
  }
@@ -132,9 +133,10 @@ class FileLane {
132
133
  build(fileList) {
133
134
  return __awaiter(this, void 0, void 0, function* () {
134
135
  const { onBuildSuccess } = this.events || {};
136
+ const t1 = Date.now();
135
137
  this.initCompilation();
136
138
  try {
137
- yield this.runPreWorks(fileList);
139
+ yield this.complyBeforeCompile(fileList);
138
140
  this.triggerPlugins(new CompilationEvent_1.default(CompilationEvent_1.default.PROJECT_START));
139
141
  for (let item of fileList) {
140
142
  this.triggerPlugins(new FileEvent_1.default(FileEvent_1.default.FILE_START_COMPILATION, FileLaneUtil_1.default.pathToFileParam(item)));
@@ -144,13 +146,13 @@ class FileLane {
144
146
  this.triggerPlugins(new CompilationEvent_1.default(CompilationEvent_1.default.PROJECT_END));
145
147
  // 执行extra
146
148
  this.triggerPlugins(new CompilationEvent_1.default(CompilationEvent_1.default.FLLOW_WORK_START));
147
- yield this.runFollowWorks();
149
+ yield this.complyAfterCompile();
148
150
  this.triggerPlugins(new CompilationEvent_1.default(CompilationEvent_1.default.FLLOW_WORK_END));
151
+ onBuildSuccess === null || onBuildSuccess === void 0 ? void 0 : onBuildSuccess({ costTime: Date.now() - t1 });
149
152
  shared_utils_1.ColorConsole.success({
150
153
  word: 'Success: build finish!',
151
154
  style: shared_utils_1.ColorConsole.getStyle(shared_utils_1.Loglevel.SUCCESS)
152
155
  });
153
- onBuildSuccess === null || onBuildSuccess === void 0 ? void 0 : onBuildSuccess();
154
156
  }
155
157
  catch (error) {
156
158
  console.log('FileLane error', error);
@@ -209,7 +211,7 @@ class FileLane {
209
211
  if (!fileList || !fileList.length) {
210
212
  return;
211
213
  }
212
- const buildPath = this.outputPath;
214
+ const buildPath = FileLaneUtil_1.default.getOutputPath(this.context);
213
215
  return Promise.all(fileList.map((item) => {
214
216
  const resolvePath = path_1.default.relative(this.context.projectPath, item.path);
215
217
  // 将相对路径与输出路径拼接,形成最新的文件路径
@@ -253,26 +255,52 @@ class FileLane {
253
255
  });
254
256
  }
255
257
  /**
256
- * 运行转换初始的任务
258
+ * start开始时的准备工作
257
259
  */
258
- runPreWorks(fileList) {
260
+ complyBeforeWorks() {
259
261
  return __awaiter(this, void 0, void 0, function* () {
260
- const { preWorks } = this.config;
261
- if (preWorks) {
262
- for (let item of preWorks) {
262
+ const { beforeWorks } = this.config;
263
+ if (beforeWorks) {
264
+ for (let item of beforeWorks) {
265
+ yield item(this.context);
266
+ }
267
+ }
268
+ });
269
+ }
270
+ /**
271
+ * start结束后的收尾工作
272
+ */
273
+ complyAfterWork() {
274
+ return __awaiter(this, void 0, void 0, function* () {
275
+ const { afterWorks } = this.config;
276
+ if (afterWorks) {
277
+ for (let item of afterWorks) {
278
+ yield item(this.context);
279
+ }
280
+ }
281
+ });
282
+ }
283
+ /**
284
+ * 执行项目转换的前置工作
285
+ */
286
+ complyBeforeCompile(fileList) {
287
+ return __awaiter(this, void 0, void 0, function* () {
288
+ const { beforeCompile } = this.config;
289
+ if (beforeCompile) {
290
+ for (let item of beforeCompile) {
263
291
  yield item(this.context, fileList, this.config, this.compilerOption);
264
292
  }
265
293
  }
266
294
  });
267
295
  }
268
296
  /**
269
- * 运行转换后续的任务
297
+ * 执行项目转换的后续工作
270
298
  */
271
- runFollowWorks() {
299
+ complyAfterCompile() {
272
300
  return __awaiter(this, void 0, void 0, function* () {
273
- const { followWorks } = this.config;
274
- if (followWorks) {
275
- for (let item of followWorks) {
301
+ const { afterCompile } = this.config;
302
+ if (afterCompile) {
303
+ for (let item of afterCompile) {
276
304
  try {
277
305
  shared_utils_1.ColorConsole.info(`FollowWork: ${item.workerDescribe} start`);
278
306
  yield item.worker(this.context, this.config, this.compilerOption);
@@ -289,10 +317,11 @@ class FileLane {
289
317
  watch() {
290
318
  return __awaiter(this, void 0, void 0, function* () {
291
319
  // 监听文件变化,并触发 build
292
- this.listenFileChange(() => __awaiter(this, void 0, void 0, function* () {
293
- const fileList = this.collectFile();
320
+ const onChange = (changedFileList) => __awaiter(this, void 0, void 0, function* () {
321
+ const fileList = this.config.collectFile ? this.config.collectFile() : this.collectFile();
294
322
  yield this.build(fileList);
295
- }));
323
+ });
324
+ this.listenFileChange(onChange);
296
325
  });
297
326
  }
298
327
  /**
@@ -333,7 +362,7 @@ class FileLane {
333
362
  });
334
363
  const handler = (filePath) => {
335
364
  const { exclude, include } = this.config;
336
- // 判断是否为删除,执行onChange回调
365
+ // 执行onChange回调
337
366
  if (shared_utils_1.FileUtil.include(filePath, include, exclude)) {
338
367
  throttledOnChange([filePath]);
339
368
  }
@@ -365,16 +394,12 @@ class FileLane {
365
394
  }
366
395
  this.watcher = watcher;
367
396
  }
368
- get outputPath() {
369
- const { output, projectPath } = this.context;
370
- return path_1.default.join(projectPath, output);
371
- }
372
397
  /**
373
398
  * 清除输出文件夹
374
399
  */
375
400
  cleanOutput() {
376
401
  return __awaiter(this, void 0, void 0, function* () {
377
- yield (0, del_1.default)(this.outputPath, { force: true });
402
+ yield (0, del_1.default)(FileLaneUtil_1.default.getOutputPath(this.context), { force: true });
378
403
  });
379
404
  }
380
405
  /**
@@ -21,6 +21,16 @@ export interface IRule {
21
21
  * IFileLaneConfig
22
22
  */
23
23
  export default interface IFileLaneConfig<O = any> {
24
+ /**
25
+ * 项目文件采集器
26
+ *
27
+ * @param entryFileList 输入的文件列表
28
+ *
29
+ * @returns 返回项目中所有待处理的文件路径
30
+ *
31
+ * @description 用于采集所有要处理的真实文件路径列表,或者输入文件列表中要处理的真实文件路径列表
32
+ */
33
+ collectFile?: (entryFileList?: string[]) => string[];
24
34
  /**
25
35
  * 文件收集器
26
36
  *
@@ -68,21 +78,25 @@ export default interface IFileLaneConfig<O = any> {
68
78
  */
69
79
  plugins?: IPlugin[];
70
80
  /**
71
- * 前置工作
72
- *
73
- * @param context 上下文
74
- * @param fileList 待转换的文件列表
75
- * @returns
81
+ * 启动阶段的准备工作
76
82
  */
77
- preWorks?: PreWork[];
83
+ beforeWorks?: BeforeWork[];
78
84
  /**
79
- * 转换结束后续的工作
85
+ * 收尾阶段的工作
86
+ */
87
+ afterWorks?: AfterWork[];
88
+ /**
89
+ * 项目转换的前置工作
90
+ */
91
+ beforeCompile?: PreWork[];
92
+ /**
93
+ * 项目转换的后续工作
80
94
  *
81
95
  * xts--[zip]
82
96
  * ux--[webpack, zip]
83
97
  * uxInspect--[webpack, zipPhone, zipWatch, zipTv]
84
98
  */
85
- followWorks?: FollowWoker<O>[];
99
+ afterCompile?: FollowWoker<O>[];
86
100
  /**
87
101
  * 配置watch时忽略的文件或者文件夹
88
102
  */
@@ -93,5 +107,11 @@ type FollowWoker<O> = {
93
107
  workerDescribe?: string;
94
108
  };
95
109
  export type FollowWork<O = any> = (context: IFileLaneContext, config?: IFileLaneConfig, compilerOption?: O) => Promise<any>;
96
- export type PreWork<O = any> = (context: IFileLaneContext, fileList: string[], config: IFileLaneConfig, compilerOption?: O) => Promise<any>;
110
+ /**
111
+ * context 上下文
112
+ * fileList 待转换的文件列表
113
+ */
114
+ export type PreWork<O = any> = (context: IFileLaneContext, fileList: string[], config: IFileLaneConfig, compilerOption: O) => Promise<any>;
115
+ export type BeforeWork = (context: IFileLaneContext) => Promise<any>;
116
+ export type AfterWork = (context: IFileLaneContext) => Promise<any>;
97
117
  export {};
@@ -13,5 +13,6 @@ declare class FileLaneUtil {
13
13
  static pathToFileParam(path: string, readContent?: boolean): IFileParam;
14
14
  static createContext(output: string, projectPath?: string): IFileLaneContext;
15
15
  static checkError(message: string): void;
16
+ static getOutputPath(context: IFileLaneContext): string;
16
17
  }
17
18
  export default FileLaneUtil;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const shared_utils_1 = require("@aiot-toolkit/shared-utils");
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const path_1 = __importDefault(require("path"));
8
9
  /**
9
10
  * FileLaneUtil
10
11
  */
@@ -49,5 +50,9 @@ class FileLaneUtil {
49
50
  shared_utils_1.ColorConsole.throw(`### file-lane ### watch error ${message}`);
50
51
  }
51
52
  }
53
+ static getOutputPath(context) {
54
+ const { output, projectPath } = context;
55
+ return path_1.default.join(projectPath, output);
56
+ }
52
57
  }
53
58
  exports.default = FileLaneUtil;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file-lane",
3
- "version": "2.0.2-beta.13",
3
+ "version": "2.0.2-beta.14",
4
4
  "description": "File conversion tool, can be one-to-one, one to N, N to one",
5
5
  "keywords": [
6
6
  "file",
@@ -20,15 +20,14 @@
20
20
  "test": "node ./__tests__/file-lane.test.js"
21
21
  },
22
22
  "dependencies": {
23
- "@aiot-toolkit/shared-utils": "2.0.2-beta.13",
24
- "chokidar": "^3.5.3",
23
+ "@aiot-toolkit/shared-utils": "2.0.2-beta.14",
24
+ "chokidar": "^3.6.0",
25
25
  "del": "^4.1.0",
26
26
  "fs-extra": "^11.2.0",
27
27
  "lodash": "^4.17.21"
28
28
  },
29
29
  "devDependencies": {
30
- "@types/archiver": "^5.3.2",
31
30
  "@types/fs-extra": "^11.0.4"
32
31
  },
33
- "gitHead": "30bf14ae958b66937da1b79dcfcd7c436e08af50"
32
+ "gitHead": "c6093733d0267d2d1359fec0af8f7a253955e3e3"
34
33
  }