@eggjs/tegg-loader 4.0.2-beta.1 → 4.0.2-beta.11

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.
@@ -1,13 +1,36 @@
1
1
  import { EggLoadUnitTypeLike, Loader, ModuleReference } from "@eggjs/tegg-types";
2
+ import { LoaderFS } from "@eggjs/loader-fs";
2
3
  import { ModuleDescriptor } from "@eggjs/metadata";
3
4
 
4
5
  //#region src/LoaderFactory.d.ts
5
- type LoaderCreator = (unitPath: string) => Loader;
6
+ type LoaderCreator = (unitPath: string, loaderFS?: LoaderFS) => Loader;
7
+ interface ManifestModuleReference {
8
+ name: string;
9
+ path: string;
10
+ optional?: boolean;
11
+ loaderType?: string;
12
+ }
13
+ interface ManifestModuleDescriptor {
14
+ name: string;
15
+ unitPath: string;
16
+ optional?: boolean;
17
+ /** Files containing decorated classes, relative to unitPath */
18
+ decoratedFiles: string[];
19
+ }
20
+ /** Shape of the 'tegg' manifest extension stored via ManifestStore.setExtension() */
21
+ interface TeggManifestExtension {
22
+ moduleReferences: ManifestModuleReference[];
23
+ moduleDescriptors: ManifestModuleDescriptor[];
24
+ }
25
+ declare const TEGG_MANIFEST_KEY = "tegg";
26
+ interface LoadAppManifest {
27
+ moduleDescriptors: ManifestModuleDescriptor[];
28
+ }
6
29
  declare class LoaderFactory {
7
30
  private static loaderCreatorMap;
8
- static createLoader(unitPath: string, type: EggLoadUnitTypeLike): Loader;
31
+ static createLoader(unitPath: string, type: EggLoadUnitTypeLike, loaderFS?: LoaderFS): Loader;
9
32
  static registerLoader(type: EggLoadUnitTypeLike, creator: LoaderCreator): void;
10
- static loadApp(moduleReferences: readonly ModuleReference[]): Promise<ModuleDescriptor[]>;
33
+ static loadApp(moduleReferences: readonly ModuleReference[], manifest?: LoadAppManifest, loaderFS?: LoaderFS): Promise<ModuleDescriptor[]>;
11
34
  }
12
35
  //#endregion
13
- export { LoaderCreator, LoaderFactory };
36
+ export { LoadAppManifest, LoaderCreator, LoaderFactory, ManifestModuleDescriptor, ManifestModuleReference, TEGG_MANIFEST_KEY, TeggManifestExtension };
@@ -2,21 +2,33 @@ import { PrototypeUtil } from "@eggjs/core-decorator";
2
2
  import { EggLoadUnitType } from "@eggjs/tegg-types";
3
3
 
4
4
  //#region src/LoaderFactory.ts
5
+ const TEGG_MANIFEST_KEY = "tegg";
5
6
  var LoaderFactory = class LoaderFactory {
6
7
  static loaderCreatorMap = /* @__PURE__ */ new Map();
7
- static createLoader(unitPath, type) {
8
+ static createLoader(unitPath, type, loaderFS) {
8
9
  const creator = this.loaderCreatorMap.get(type);
9
10
  if (!creator) throw new Error(`not find creator for loader type ${type}`);
10
- return creator(unitPath);
11
+ return creator(unitPath, loaderFS);
11
12
  }
12
13
  static registerLoader(type, creator) {
13
14
  this.loaderCreatorMap.set(type, creator);
14
15
  }
15
- static async loadApp(moduleReferences) {
16
+ static async loadApp(moduleReferences, manifest, loaderFS) {
16
17
  const result = [];
17
18
  const multiInstanceClazzList = [];
19
+ const manifestMap = /* @__PURE__ */ new Map();
20
+ if (manifest?.moduleDescriptors) for (const desc of manifest.moduleDescriptors) manifestMap.set(desc.unitPath, desc);
21
+ let ModuleLoaderClass;
22
+ if (manifestMap.size > 0) ModuleLoaderClass = (await import("./impl/ModuleLoader.js")).ModuleLoader;
18
23
  for (const moduleReference of moduleReferences) {
19
- const loader = LoaderFactory.createLoader(moduleReference.path, moduleReference.loaderType || EggLoadUnitType.MODULE);
24
+ const manifestDesc = manifestMap.get(moduleReference.path);
25
+ const loaderType = moduleReference.loaderType || EggLoadUnitType.MODULE;
26
+ let loader;
27
+ if (manifestDesc && ModuleLoaderClass && loaderType === EggLoadUnitType.MODULE) loader = new ModuleLoaderClass(moduleReference.path, {
28
+ precomputedFiles: manifestDesc.decoratedFiles,
29
+ loaderFS
30
+ });
31
+ else loader = LoaderFactory.createLoader(moduleReference.path, loaderType, loaderFS);
20
32
  const res = {
21
33
  name: moduleReference.name,
22
34
  unitPath: moduleReference.path,
@@ -35,4 +47,4 @@ var LoaderFactory = class LoaderFactory {
35
47
  };
36
48
 
37
49
  //#endregion
38
- export { LoaderFactory };
50
+ export { LoaderFactory, TEGG_MANIFEST_KEY };
@@ -5,6 +5,10 @@ import { isClass } from "is-type-of";
5
5
 
6
6
  //#region src/LoaderUtil.ts
7
7
  const Module = globalThis.module?.constructor?.length > 1 ? globalThis.module.constructor : BuiltinModule;
8
+ function createLoadError(filePath, e) {
9
+ const message = e instanceof Error ? e.message : String(e);
10
+ return new Error(`[tegg/loader] load ${filePath} failed: ${message}`, { cause: e });
11
+ }
8
12
  var LoaderUtil = class LoaderUtil {
9
13
  static config = {};
10
14
  static setConfig(config) {
@@ -12,7 +16,15 @@ var LoaderUtil = class LoaderUtil {
12
16
  }
13
17
  static supportExtensions() {
14
18
  const extensions = Object.keys(Module._extensions);
15
- if (process.env.VITEST === "true" && !extensions.includes(".ts")) extensions.push(".ts");
19
+ const nodeMajorVersion = parseInt(process.versions.node.split(".", 1)[0], 10);
20
+ if (process.env.EGG_TS_ENABLE !== "false" && (extensions.includes(".ts") || process.env.VITEST === "true" || process.env.EGG_TS_ENABLE === "true" || nodeMajorVersion >= 22)) {
21
+ for (const ext of [
22
+ ".ts",
23
+ ".mts",
24
+ ".cts"
25
+ ]) if (!extensions.includes(ext)) extensions.push(ext);
26
+ }
27
+ if (process.env.EGG_TS_ENABLE === "false") return extensions.filter((ext) => ext !== ".ts" && ext !== ".mts" && ext !== ".cts");
16
28
  return extensions;
17
29
  }
18
30
  static get extension() {
@@ -30,20 +42,27 @@ var LoaderUtil = class LoaderUtil {
30
42
  ];
31
43
  }
32
44
  static async loadFile(filePath) {
33
- if (process.platform === "win32") filePath = pathToFileURL(filePath).toString();
45
+ const originalFilePath = filePath;
34
46
  let exports;
35
47
  try {
36
- exports = await import(filePath);
48
+ exports = globalThis.__EGG_BUNDLE_MODULE_LOADER__?.(originalFilePath.split("\\").join("/"));
37
49
  } catch (e) {
38
- console.trace("[tegg/loader] loadFile %s error:", filePath);
39
- console.error(e);
40
- throw new Error(`[tegg/loader] load ${filePath} failed: ${e.message}`, { cause: e });
50
+ throw createLoadError(originalFilePath, e);
51
+ }
52
+ if (exports == null) {
53
+ if (process.platform === "win32") filePath = pathToFileURL(filePath).toString();
54
+ try {
55
+ exports = await import(filePath);
56
+ } catch (e) {
57
+ throw createLoadError(filePath, e);
58
+ }
41
59
  }
42
60
  const clazzList = [];
43
61
  const exportNames = Object.keys(exports);
44
62
  for (const exportName of exportNames) {
45
63
  const clazz = exports[exportName];
46
64
  if (!(isClass(clazz) && (PrototypeUtil.isEggPrototype(clazz) || PrototypeUtil.isEggMultiInstancePrototype(clazz)))) continue;
65
+ PrototypeUtil.setFilePath(clazz, originalFilePath);
47
66
  clazzList.push(clazz);
48
67
  }
49
68
  return clazzList;
@@ -1,12 +1,21 @@
1
1
  import { EggProtoImplClass, Loader } from "@eggjs/tegg-types";
2
+ import { LoaderFS } from "@eggjs/loader-fs";
2
3
 
3
4
  //#region src/impl/ModuleLoader.d.ts
5
+ interface ModuleLoaderOptions {
6
+ /** Pre-computed file list from manifest (only decorated files) */
7
+ precomputedFiles?: string[];
8
+ /** File system abstraction used for discovery; manifest-backed in bundle mode */
9
+ loaderFS?: LoaderFS;
10
+ }
4
11
  declare class ModuleLoader implements Loader {
5
12
  private readonly moduleDir;
6
13
  private protoClazzList;
7
- constructor(moduleDir: string);
14
+ private readonly precomputedFiles?;
15
+ private readonly loaderFS;
16
+ constructor(moduleDir: string, options?: ModuleLoaderOptions);
8
17
  load(): Promise<EggProtoImplClass[]>;
9
- static createModuleLoader(path: string): ModuleLoader;
18
+ static createModuleLoader(path: string, loaderFS?: LoaderFS): ModuleLoader;
10
19
  }
11
20
  //#endregion
12
- export { ModuleLoader };
21
+ export { ModuleLoader, ModuleLoaderOptions };
@@ -2,22 +2,32 @@ import { LoaderFactory } from "../LoaderFactory.js";
2
2
  import { LoaderUtil } from "../LoaderUtil.js";
3
3
  import path from "node:path";
4
4
  import { debuglog } from "node:util";
5
- import globby from "globby";
5
+ import { RealLoaderFS } from "@eggjs/loader-fs";
6
6
 
7
7
  //#region src/impl/ModuleLoader.ts
8
8
  const debug = debuglog("egg/tegg/loader/impl/ModuleLoader");
9
9
  var ModuleLoader = class ModuleLoader {
10
10
  moduleDir;
11
11
  protoClazzList;
12
- constructor(moduleDir) {
12
+ precomputedFiles;
13
+ loaderFS;
14
+ constructor(moduleDir, options = {}) {
13
15
  this.moduleDir = moduleDir;
16
+ this.precomputedFiles = options.precomputedFiles;
17
+ this.loaderFS = options.loaderFS ?? new RealLoaderFS();
14
18
  }
15
19
  async load() {
16
20
  if (this.protoClazzList) return this.protoClazzList;
17
21
  const protoClassList = [];
18
- const filePattern = LoaderUtil.filePattern();
19
- const files = await globby(filePattern, { cwd: this.moduleDir });
20
- debug("load files: %o, filePattern: %o, moduleDir: %o", files, filePattern, this.moduleDir);
22
+ let files;
23
+ if (this.precomputedFiles) {
24
+ files = this.precomputedFiles;
25
+ debug("load from manifest, files: %o, moduleDir: %o", files, this.moduleDir);
26
+ } else {
27
+ const filePattern = LoaderUtil.filePattern();
28
+ files = this.loaderFS.glob(filePattern, { cwd: this.moduleDir });
29
+ debug("load files: %o, filePattern: %o, moduleDir: %o", files, filePattern, this.moduleDir);
30
+ }
21
31
  for (const file of files) {
22
32
  const realPath = path.join(this.moduleDir, file);
23
33
  const fileClazzList = await LoaderUtil.loadFile(realPath);
@@ -26,8 +36,8 @@ var ModuleLoader = class ModuleLoader {
26
36
  this.protoClazzList = Array.from(new Set(protoClassList));
27
37
  return this.protoClazzList;
28
38
  }
29
- static createModuleLoader(path$1) {
30
- return new ModuleLoader(path$1);
39
+ static createModuleLoader(path$1, loaderFS) {
40
+ return new ModuleLoader(path$1, { loaderFS });
31
41
  }
32
42
  };
33
43
  LoaderFactory.registerLoader("MODULE", ModuleLoader.createModuleLoader);
@@ -1 +1 @@
1
- import { ModuleLoader } from "./ModuleLoader.js";
1
+ import { ModuleLoader, ModuleLoaderOptions } from "./ModuleLoader.js";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { LoaderCreator, LoaderFactory } from "./LoaderFactory.js";
1
+ import { LoadAppManifest, LoaderCreator, LoaderFactory, ManifestModuleDescriptor, ManifestModuleReference, TEGG_MANIFEST_KEY, TeggManifestExtension } from "./LoaderFactory.js";
2
2
  import { LoaderUtil } from "./LoaderUtil.js";
3
- import { ModuleLoader } from "./impl/ModuleLoader.js";
3
+ import { ModuleLoader, ModuleLoaderOptions } from "./impl/ModuleLoader.js";
4
4
  import "./impl/index.js";
5
- export { LoaderCreator, LoaderFactory, LoaderUtil, ModuleLoader };
5
+ export { LoadAppManifest, LoaderCreator, LoaderFactory, LoaderUtil, ManifestModuleDescriptor, ManifestModuleReference, ModuleLoader, ModuleLoaderOptions, TEGG_MANIFEST_KEY, TeggManifestExtension };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { LoaderFactory } from "./LoaderFactory.js";
1
+ import { LoaderFactory, TEGG_MANIFEST_KEY } from "./LoaderFactory.js";
2
2
  import { LoaderUtil } from "./LoaderUtil.js";
3
3
  import { ModuleLoader } from "./impl/ModuleLoader.js";
4
4
  import "./impl/index.js";
5
5
 
6
- export { LoaderFactory, LoaderUtil, ModuleLoader };
6
+ export { LoaderFactory, LoaderUtil, ModuleLoader, TEGG_MANIFEST_KEY };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eggjs/tegg-loader",
3
- "version": "4.0.2-beta.1",
3
+ "version": "4.0.2-beta.11",
4
4
  "description": "tegg default loader implement",
5
5
  "keywords": [
6
6
  "egg",
@@ -34,11 +34,12 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "globby": "^11.0.2",
38
37
  "is-type-of": "^2.2.0",
39
- "@eggjs/core-decorator": "4.0.2-beta.1",
40
- "@eggjs/tegg-types": "4.0.2-beta.1",
41
- "@eggjs/metadata": "4.0.2-beta.1"
38
+ "@eggjs/core-decorator": "4.0.2-beta.11",
39
+ "@eggjs/metadata": "4.0.2-beta.11",
40
+ "@eggjs/tegg-types": "4.0.2-beta.11",
41
+ "@eggjs/loader-fs": "1.0.0-beta.11",
42
+ "@eggjs/typings": "4.1.2-beta.11"
42
43
  },
43
44
  "devDependencies": {
44
45
  "@types/node": "^24.10.2",