mm_machine 2.1.6 → 2.1.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.
Files changed (2) hide show
  1. package/item.js +133 -45
  2. package/package.json +3 -2
package/item.js CHANGED
@@ -1,6 +1,7 @@
1
- const util = require('util');
2
- const { conf } = require('mm_config');
3
- const { HotReload } = require('mm_hot_reload');
1
+ let util = require('util');
2
+ let { conf } = require('mm_config');
3
+ let Tpl = require('mm_tpl');
4
+ let { HotReload } = require('mm_hot_reload');
4
5
 
5
6
  // 初始化全局对象
6
7
  if (typeof global.$ === 'undefined') {
@@ -11,6 +12,10 @@ if (!$.mod) {
11
12
  $.mod = new HotReload();
12
13
  }
13
14
 
15
+ if (!$.tpl) {
16
+ $.tpl = new Tpl();
17
+ }
18
+
14
19
  /**
15
20
  * 增强require函数,支持热更新
16
21
  * @param {string} file 文件路径
@@ -61,7 +66,7 @@ class Item {
61
66
  // 描述, 用于描述该有什么用的
62
67
  description: '',
63
68
  // 文件路径, 当调用函数不存在时,会先从文件中加载
64
- func_file: './index.js',
69
+ main: './index.js',
65
70
  // 回调函数名 用于决定调用脚本的哪个函数
66
71
  func_name: '',
67
72
  // 排序
@@ -103,8 +108,8 @@ Item.prototype.log = function (level, message, ...args) {
103
108
  Item.prototype.setConfig = function (config) {
104
109
  if (!config) return;
105
110
 
106
- // 如果func_file改变,重置加载状态
107
- if (config.func_file !== this.config.func_file) {
111
+ // 如果main改变,重置加载状态
112
+ if (config.main !== this.config.main) {
108
113
  this.complete = false;
109
114
  }
110
115
 
@@ -124,9 +129,54 @@ Item.prototype.setConfigAfter = function () {
124
129
  * @param {string} file 目标文件路径
125
130
  */
126
131
  Item.prototype.newScript = function (file) {
127
- const template_file = './script.js'.fullname(this.dir_base);
128
- if (template_file.hasFile()) {
129
- template_file.copyFile(file);
132
+ this._createScriptFile(file, this.config, this.dir_base);
133
+ };
134
+
135
+
136
+ /**
137
+ * 创建脚本
138
+ * @param {string} file 文件路径
139
+ * @param {object} model 模板数据
140
+ * @param {string} tpl_dir 模板文件路径
141
+ * @returns {boolean} 创建是否成功
142
+ */
143
+ Item.prototype._createScriptFile = function (file, model = {}, tpl_dir = '') {
144
+ var tpl = this.getScriptTpl(tpl_dir);
145
+ var content = $.tpl.render(tpl, model);
146
+ file.saveText(content);
147
+ return file;
148
+ };
149
+
150
+ /**
151
+ * 获取脚本模板
152
+ * @param {string} tpl_dir 模板文件路径
153
+ * @returns {string} 脚本模板内容
154
+ */
155
+ Item.prototype.getScriptTpl = function (tpl_dir = '') {
156
+ var f = './script.tpl.js'.fullname(tpl_dir || this.dir_base);
157
+ if (f.hasFile()) {
158
+ return f.loadText();
159
+ } else {
160
+ return `module.exports = {
161
+ /**
162
+ * 初始化
163
+ */
164
+ async _init() {
165
+ this.log('debug', \`初始化!\`);
166
+ },
167
+ /**
168
+ * 销毁
169
+ */
170
+ async _destroy(...args) {
171
+ this.log('debug', \`销毁!\`);
172
+ },
173
+ /**
174
+ * 主要逻辑
175
+ */
176
+ async main(...args) {
177
+ // 主要代码写在这
178
+ }
179
+ }`;
130
180
  }
131
181
  };
132
182
 
@@ -143,7 +193,7 @@ Item.prototype._remove = function (module) {
143
193
  $.mod.unload(module);
144
194
  } else {
145
195
  // 移除模块缓存
146
- const filename = require.resolve(module);
196
+ let filename = require.resolve(module);
147
197
  if (require.cache[filename]) {
148
198
  require.cache[filename] = null;
149
199
  delete require.cache[filename];
@@ -161,9 +211,9 @@ Item.prototype._remove = function (module) {
161
211
  Item.prototype.unloadScript = function (file) {
162
212
  let target_file = file;
163
213
  if (!target_file) {
164
- const func_file = this.config.func_file;
165
- if (func_file) {
166
- target_file = func_file.fullname(this.dir);
214
+ let main = this.config.main;
215
+ if (main) {
216
+ target_file = main.fullname(this.dir);
167
217
  }
168
218
  }
169
219
 
@@ -208,13 +258,13 @@ Item.prototype.unloadAfter = async function (remove) {
208
258
  * @returns {object | null} 返回加载的模块对象
209
259
  */
210
260
  Item.prototype.loadScript = function (file, name = '') {
211
- const target_file = this._getScriptFile(file);
261
+ let target_file = this._getScriptFile(file);
212
262
  if (!target_file) return null;
213
263
 
214
- const target_name = this._getScriptName(name);
264
+ let target_name = this._getScriptName(name);
215
265
 
216
266
  try {
217
- const cs = this._loadScript(target_file, target_name);
267
+ let cs = this._loadScript(target_file, target_name);
218
268
  this._setMainMethod(cs, target_name);
219
269
  return cs;
220
270
  } catch (err) {
@@ -231,10 +281,10 @@ Item.prototype.loadScript = function (file, name = '') {
231
281
  Item.prototype._getScriptFile = function (file) {
232
282
  if (file) return file;
233
283
 
234
- const func_file = this.config.func_file;
235
- if (!func_file) return null;
284
+ let main = this.config.main;
285
+ if (!main) return null;
236
286
 
237
- const target_file = func_file.fullname(this.dir);
287
+ let target_file = main.fullname(this.dir);
238
288
  if (!target_file.hasFile()) {
239
289
  this.newScript(target_file);
240
290
  }
@@ -286,8 +336,46 @@ Item.prototype._setMainMethod = function (module, name) {
286
336
  * @param {string} file 目标文件路径
287
337
  */
288
338
  Item.prototype.newConfig = function (file) {
289
- const template_file = './config.tpl.json'.fullname(this.dir_base);
290
- template_file.copyFile(file);
339
+ if (!this.config.name) {
340
+ this.config.name = file.dirname().basename();
341
+ }
342
+ this._createConfigFile(file, this.config, this.dir_base);
343
+ };
344
+
345
+ Item.prototype._createConfigFile = function (file, model = {}, tpl_dir = '') {
346
+ var tpl = this.getConfigTpl(tpl_dir);
347
+ var content = $.tpl.render(tpl, model);
348
+ file.saveText(content);
349
+ return file;
350
+ };
351
+
352
+ /**
353
+ * 获取配置模板
354
+ * @param {string} tpl_dir 模板文件路径
355
+ * @returns {string} 配置模板内容
356
+ */
357
+ Item.prototype.getConfigTpl = function (tpl_dir = '') {
358
+ var f = './config.tpl.json'.fullname(tpl_dir || this.dir_base);
359
+ if (f.hasFile()) {
360
+ return f.loadText();
361
+ } else {
362
+ return `{
363
+ // 模块名称,必填
364
+ 'name': '\${name}',
365
+ // 模块标题,可选,默认"示例标题"
366
+ 'title': '\${title || "示例标题"}',
367
+ // 模块描述,可选,默认"示例描述"
368
+ 'description': '\${description || "示例描述"}',
369
+ // 主脚本文件路径,可选,默认"./index.js"
370
+ 'main': '\${main || "./index.js"}',
371
+ // 模块作用域,可选,默认"server"
372
+ 'scope': '\${scope || "server"}',
373
+ // 模块状态,可选,默认1
374
+ 'state': \${state || 1},
375
+ // 模块排序,可选,默认100
376
+ 'sort': \${sort || 100}
377
+ }`;
378
+ }
291
379
  };
292
380
 
293
381
  /**
@@ -298,7 +386,7 @@ Item.prototype.newConfig = function (file) {
298
386
  */
299
387
  Item.prototype.loadFile = function (file, name) {
300
388
  try {
301
- const full_path = file.fullname(this.dir);
389
+ let full_path = file.fullname(this.dir);
302
390
  let text = full_path.loadText();
303
391
 
304
392
  // 如果文件不存在,创建新的配置文件
@@ -309,8 +397,8 @@ Item.prototype.loadFile = function (file, name) {
309
397
 
310
398
  if (!text) return null;
311
399
 
312
- const config = this._loadHotReload(full_path);
313
- const final_config = this._findConfigByName(config, name);
400
+ let config = this._loadHotReload(full_path);
401
+ let final_config = this._findConfigByName(config, name);
314
402
 
315
403
  // 更新目录和文件名引用
316
404
  this.dir = full_path.dirname();
@@ -378,8 +466,8 @@ Item.prototype._reloadIfNeeded = function () {
378
466
  * 删除目录
379
467
  */
380
468
  Item.prototype.delDir = function () {
381
- const func_file = this.config.func_file;
382
- if (func_file && $.dir && $.dir.del) {
469
+ let main = this.config.main;
470
+ if (main && $.dir && $.dir.del) {
383
471
  $.dir.del(this.dir);
384
472
  }
385
473
  };
@@ -389,8 +477,8 @@ Item.prototype.delDir = function () {
389
477
  * @returns {string | null} 错误消息,如果没有错误则返回null
390
478
  */
391
479
  Item.prototype.removeFile = function () {
392
- const name = this.config.name;
393
- const file = this.filename;
480
+ let name = this.config.name;
481
+ let file = this.filename;
394
482
 
395
483
  let error_message = null;
396
484
  try {
@@ -415,13 +503,13 @@ Item.prototype.removeFile = function () {
415
503
  * @returns {string | null} 错误消息
416
504
  */
417
505
  Item.prototype._removeConfigFile = function (file, name) {
418
- const text = file.loadText();
506
+ let text = file.loadText();
419
507
  if (!text) {
420
508
  this.delDir();
421
509
  return null;
422
510
  }
423
511
 
424
- const config = text.toJson();
512
+ let config = text.toJson();
425
513
  if (Array.isArray(config)) {
426
514
  return this._removeArrayItem(file, config, name);
427
515
  }
@@ -438,7 +526,7 @@ Item.prototype._removeConfigFile = function (file, name) {
438
526
  * @returns {string | null} 错误消息
439
527
  */
440
528
  Item.prototype._removeArrayItem = function (file, config, name) {
441
- const index = config.findIndex((item) => item.name === name);
529
+ let index = config.findIndex((item) => item.name === name);
442
530
  if (index === -1) return null;
443
531
 
444
532
  this.delDir();
@@ -483,7 +571,7 @@ Item.prototype.loadConfig = async function (config_data, name) {
483
571
  */
484
572
  Item.prototype.loadBefore = async function () {
485
573
  try {
486
- const module = this.loadScript();
574
+ let module = this.loadScript();
487
575
  if (module) {
488
576
  this.complete = true;
489
577
  }
@@ -515,15 +603,15 @@ Item.prototype.save = function () {
515
603
  try {
516
604
  if (!this.filename) return;
517
605
 
518
- const full_path = this.filename.fullname(this.dir);
519
- const text = full_path.loadText();
606
+ let full_path = this.filename.fullname(this.dir);
607
+ let text = full_path.loadText();
520
608
 
521
609
  if (text && text.trim().startsWith('[')) {
522
610
  // 数组格式配置
523
- const config_array = text.toJson();
611
+ let config_array = text.toJson();
524
612
  if (Array.isArray(config_array)) {
525
613
  // 查找并更新现有配置项
526
- const existing_index = config_array.findIndex((item) => item.name === this.config.name);
614
+ let existing_index = config_array.findIndex((item) => item.name === this.config.name);
527
615
  if (existing_index !== -1) {
528
616
  config_array[existing_index] = this.config;
529
617
  } else {
@@ -568,7 +656,7 @@ Item.prototype.run = async function (...params) {
568
656
  * @returns {Promise<any>} 执行结果
569
657
  */
570
658
  Item.prototype.exec = async function (method, ...params) {
571
- const method_func = this._getMethod(method);
659
+ let method_func = this._getMethod(method);
572
660
  if (!method_func) return null;
573
661
 
574
662
  let result;
@@ -605,8 +693,8 @@ Item.prototype._getMethod = function (method) {
605
693
  * @returns {Promise<any>} 前置钩子结果
606
694
  */
607
695
  Item.prototype._execBefore = async function (method, params) {
608
- const before_method = `${method}Before`;
609
- const before_func = this._getMethod(before_method);
696
+ let before_method = `${method}Before`;
697
+ let before_func = this._getMethod(before_method);
610
698
 
611
699
  if (!before_func) return undefined;
612
700
 
@@ -630,8 +718,8 @@ Item.prototype._execBefore = async function (method, params) {
630
718
  * @returns {Promise<any>} 主方法结果
631
719
  */
632
720
  Item.prototype._execMain = async function (method_func, params, before_result) {
633
- const method_result = method_func.call(this._mod || this, ...params);
634
- const result = util.types.isPromise(method_result) ? await method_result : method_result;
721
+ let method_result = method_func.call(this._mod || this, ...params);
722
+ let result = util.types.isPromise(method_result) ? await method_result : method_result;
635
723
  return result;
636
724
  };
637
725
 
@@ -643,16 +731,16 @@ Item.prototype._execMain = async function (method_func, params, before_result) {
643
731
  * @returns {Promise<any>} 后置钩子结果
644
732
  */
645
733
  Item.prototype._execAfter = async function (method, params, main_result) {
646
- const after_method = `${method}After`;
647
- const after_func = this._getMethod(after_method);
734
+ let after_method = `${method}After`;
735
+ let after_func = this._getMethod(after_method);
648
736
 
649
737
  if (!after_func) return main_result;
650
738
 
651
739
  try {
652
- const after_result = after_func.call(this._mod || this, main_result, ...params);
740
+ let after_result = after_func.call(this._mod || this, main_result, ...params);
653
741
 
654
742
  if (util.types.isPromise(after_result)) {
655
- const resolved_result = await after_result;
743
+ let resolved_result = await after_result;
656
744
  return resolved_result !== undefined ? resolved_result : main_result;
657
745
  }
658
746
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_machine",
3
- "version": "2.1.6",
3
+ "version": "2.1.8",
4
4
  "description": "A flexible Node.js plugin mechanism system for dynamic loading, management and execution of modules. Supports hot reload, lifecycle management, and modern JavaScript features.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -32,6 +32,7 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "mm_config": "^2.2.3",
35
- "mm_hot_reload": "^1.2.0"
35
+ "mm_hot_reload": "^1.2.0",
36
+ "mm_tpl": "^2.4.7"
36
37
  }
37
38
  }