Skip to content

简介

核心工具模块。提供高层模块(FileLoader、ControllerLoader、ConfigLoader 等)使用的基础能力。包括:

  • FileLoader:通用文件加载器,扫描目录并根据目录结构将导出内容组织为嵌套对象,支持同步、异步和注册表加载模式。
  • Timing:性能计时器,记录框架阶段耗时。
  • 工具函数loadFileloadFileAsynccallFngetResolvedFilenameisBytecodeClassfilePatternsextensions

导入

CJS 和 ESM:

javascript
// ESM
import { FileLoader, FULLPATH, EXPORTS } from 'ee-core/core/loader/file_loader';
import { Timing } from 'ee-core/core/utils/timing';
import { loadFile, loadFileAsync, callFn, getResolvedFilename, isBytecodeClass, filePatterns, extensions } from 'ee-core/core/utils';
// CJS
const { FileLoader, FULLPATH, EXPORTS } = require('ee-core/core/loader/file_loader');
const { Timing } = require('ee-core/core/utils/timing');
const { loadFile, loadFileAsync, callFn, getResolvedFilename, isBytecodeClass, filePatterns, extensions } = require('ee-core/core/utils');

API

FULLPATH

说明:Symbol 常量(Symbol('LOADER_ITEM_FULLPATH'))。标记非原始导出的完整文件路径,用于调试和 IPC 路由。由 FileLoader._assignToTarget() 设置在导出对象上。 返回值symbol — FULLPATH symbol

EXPORTS

说明:Symbol 常量(Symbol('LOADER_ITEM_EXPORTS'))。标记非原始导出已被 FileLoader 处理。由 FileLoader._assignToTarget() 设置为 true返回值symbol — EXPORTS symbol


FileLoader 类

通用文件加载器,根据目录结构将文件导出内容组织为嵌套属性对象。三种加载方法:

  • parse():同步文件系统扫描 + require(),适用于 CJS dev 模式
  • parseFromRegistry():从预注册表加载,适用于 bundle 模式
  • parseAsync():异步文件系统扫描 + import(),适用于 ESM dev 模式

目录到属性的映射示例:

controller/user.js       -> target.controller.user
controller/admin/login.js -> target.controller.admin.login

属性命名由 caseStyle 控制:

  • 'camel':驼峰命名(默认)— user-info -> userInfo
  • 'lower':全小写 — 控制器使用
  • 'upper':首字母大写
  • 自定义函数:完全自定义转换逻辑

FileLoader.constructor(options)

说明:创建 FileLoader 实例。options.directory 必填;其他选项与默认值合并(caseStyle: 'camel'call: trueinitializer: nullinject: undefinedtarget: nullmatch: undefined)。 参数

参数类型必填说明
optionsFileLoaderOptions加载器配置
options.directorystring要扫描的目录路径
options.caseStyle'lower' | 'upper' | 'camel' | ((filepath: string) => string[])属性命名风格,默认 'camel'
options.initializer((obj: unknown, options: { pathName: string; path: string }) => unknown) | null自定义导出处理器,默认 null
options.callboolean是否自动调用函数导出,默认 true
options.injectunknown自动调用函数的注入参数
options.matchstring[] | undefined文件匹配模式(覆盖默认 filePatterns)
options.registryRegistryEntry[]bundle 模式的预注册条目

返回值FileLoader 实例 示例

javascript
import { FileLoader } from 'ee-core/core/loader/file_loader';

const loader = new FileLoader({
  directory: path.join(getElectronDir(), 'controller'),
  caseStyle: 'lower',
  initializer: (obj, options) => {
    if (isClass(obj)) {
      obj.prototype.pathName = options.pathName;
      return wrapClass(obj);
    }
    return obj;
  },
});
const result = loader.load();

FileLoader.load()

说明:加载文件并构建嵌套目标对象。当 options.registry 存在时使用注册表模式(bundle 模式),否则回退到文件系统扫描(dev 模式,通过 parse())。通过 _assignToTarget() 将所有加载项分配到嵌套对象。 参数:无 返回值Record<string, unknown> — 按目录结构组织的嵌套属性对象

FileLoader.loadAsync()

说明load() 的异步版本。使用 parseAsync(),其中用 fs.promises 扫描并用动态 import() 加载模块。适用于 ESM dev 模式。 参数:无 返回值Promise<Record<string, unknown>> — 按目录结构组织的嵌套属性对象

FileLoader.parse()

说明:从文件系统同步解析文件。使用 scanDirSync() 递归扫描和 require() 加载模块。支持 options.directory 为字符串或目录数组。 参数:无 返回值LoaderItem[] — 加载项数组,结构为 { fullpath, properties, exports }

FileLoader.parseFromRegistry()

说明:从预注册表解析模块。在 bundle 模式下,esbuild 插件将控制器/配置信息预注册到全局变量。此方法直接读取注册表,无需文件系统扫描。处理 ESM 互操作:带 __esModule 标记的模块提取 default 导出。 参数:无 返回值LoaderItem[] — 加载项数组,结构为 { fullpath, properties, exports }

FileLoader.parseAsync()

说明:从文件系统异步解析文件。使用 scanDirAsync() 和动态 import()。适用于 ESM dev 模式。 参数:无 返回值Promise<LoaderItem[]> — 加载项数组,结构为 { fullpath, properties, exports }


Timing 类

性能计时器,记录框架阶段耗时。由 ConfigLoaderControllerLoader 使用,记录如"加载配置"、"加载控制器"等阶段耗时。支持嵌套计时——重复调用 start() 同名项会自动先结束前一个。

javascript
import { Timing } from 'ee-core/core/utils/timing';

const timing = new Timing();
timing.start('Load Controller');
// ... 执行加载
timing.end('Load Controller');
const items = timing.toJSON(); // 获取所有计时记录

Timing.constructor()

说明:创建新的 Timing 实例并初始化,记录进程启动时间和脚本启动时间(如可用)。 参数:无 返回值Timing 实例

Timing.start(name, start)

说明:开始计时。如果同名计时项已存在,会先结束前一个。记录 process.pid 和顺序索引。 参数

参数类型必填说明
namestring计时项名称(如 'Load Controller')
startnumber自定义起始时间戳(毫秒);未提供时使用 Date.now()

返回值TimingItem \| undefined — 计时项对象;名称为空或计时禁用时返回 undefined

Timing.end(name)

说明:结束计时。计算 durationend - start 毫秒。如果指定名称的计时项不存在(即未先调用 start()),则抛出错误。 参数

参数类型必填说明
namestring计时项名称(须与之前的 start() 调用匹配)

返回值TimingItem \| undefined — 包含 duration 的计时项对象;名称为空或计时禁用时返回 undefined

Timing.enable()

说明:启用计时记录。 参数:无 返回值void

Timing.disable()

说明:禁用计时记录。后续所有 start()end() 调用返回 undefined参数:无 返回值void

Timing.clear()

说明:清除所有计时记录,重置内部 map 和有序列表。 参数:无 返回值void

Timing.toJSON()

说明:将所有计时记录导出为可 JSON 序列化的数组,按 start() 调用时的时间顺序排列。 参数:无 返回值TimingItem[] — 按时间顺序排列的计时项列表,每项包含 { name, start, end, duration, pid, index }


loadFile(filepath)

说明:同步加载文件。对于非 JS 文件(扩展名不在 Module._extensions 中),返回 Buffer 形式的文件内容。对于 JS/CJS/JSC 文件,使用 require() 加载模块。处理 ESM 互操作:带 __esModule 标记的模块提取 default 导出。通过已注册的扩展支持 bytenode .jsc参数

参数类型必填说明
filepathstring绝对文件路径

返回值unknown — 文件内容(非 JS 为 Buffer)或模块导出值 示例

javascript
import { loadFile } from 'ee-core/core/utils';

const exports = loadFile('/path/to/controller/user.js');

loadFileAsync(filepath)

说明:异步加载文件(ESM 支持)。与 loadFile 逻辑相同,但使用动态 import() 加载模块,使用 fs.promises.readFile() 读取非 JS/ESM 文件。同时支持 ESM 和 CJS 模块格式。 参数

参数类型必填说明
filepathstring绝对文件路径

返回值Promise<unknown> — 文件内容(非 JS 为 Buffer)或模块导出值

callFn(fn, args, ctx)

说明:带可选上下文绑定调用函数。如果提供 ctx,调用 fn.call(ctx, ...args);否则直接调用 fn(...args)。如果 fn 不是函数则返回 undefined。由 methodToMiddleware() 内部使用,在新建实例上调用控制器方法。 参数

参数类型必填说明
fn(...args: unknown[]) => unknown要调用的函数
argsunknown[]参数列表,默认 []
ctxunknown执行上下文(this 绑定)

返回值Promise<unknown> — 函数返回值;fn 不是函数时返回 undefined

getResolvedFilename(filepath, baseDir)

说明:将绝对文件路径转换为基于 baseDir 的相对路径,使用正斜杠作为分隔符。内部用于计算属性路径。 参数

参数类型必填说明
filepathstring绝对文件路径
baseDirstring基准目录

返回值string — 使用正斜杠分隔符的相对路径

isBytecodeClass(exports)

说明:判断导出是否为字节码类(来自 bytenode 编译的 .jsc 文件)。检查 String(exports) 是否包含 [class。处理 Node.js 中 bytenode 类显示为 [class XXX] 的情况。 参数

参数类型必填说明
exportsunknown要检查的导出值

返回值boolean — 是否为字节码类;null/undefined 时返回 false

filePatterns()

说明:获取目录扫描支持的文件匹配模式。用于早期基于 globby 的扫描;现在框架内部使用 scanDirSync/scanDirAsync,但此函数仍保留以兼容。 参数:无 返回值string[] — 模式列表:['**/*.js', '**/*.jsc']

extensions

说明:Node.js 原生模块扩展映射(Module._extensions)。包含 .js.json.node 及 bytenode 注册的 .jsc。由 loadFileloadFileAsync 用于判断文件应以模块加载还是以原始内容读取。 返回值NodeJS.RequireExtensions — 扩展处理器映射