Skip to content

Commit 5aff2fd

Browse files
committed
feat(core): add manifest-backed loader fs
1 parent 0dec2c9 commit 5aff2fd

5 files changed

Lines changed: 508 additions & 6 deletions

File tree

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"get-ready": "catalog:",
5050
"globby": "catalog:",
5151
"is-type-of": "catalog:",
52+
"multimatch": "catalog:",
5253
"node-homedir": "catalog:",
5354
"performance-ms": "catalog:",
5455
"ready-callback": "catalog:",

packages/core/src/loader/egg_loader.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { isAsyncFunction, isClass, isGeneratorFunction, isObject, isPromise } fr
1313
import { homedir } from 'node-homedir';
1414
import { now, diff } from 'performance-ms';
1515
import { register as tsconfigPathsRegister } from 'tsconfig-paths';
16-
import { getParamNames, readJSONSync, readJSON, exists } from 'utility';
16+
import { getParamNames, readJSONSync } from 'utility';
1717

1818
import type { BaseContextClass } from '../base_context_class.ts';
1919
import type { Context, EggCore, MiddlewareFunc } from '../egg.ts';
@@ -24,7 +24,7 @@ import { sequencify } from '../utils/sequencify.ts';
2424
import { Timing } from '../utils/timing.ts';
2525
import { type ContextLoaderOptions, ContextLoader } from './context_loader.ts';
2626
import { type FileLoaderOptions, CaseStyle, FULLPATH, FileLoader } from './file_loader.ts';
27-
import { RealLoaderFS, type LoaderFS } from './loader_fs.ts';
27+
import { ManifestLoaderFS, RealLoaderFS, type LoaderFS } from './loader_fs.ts';
2828
import { ManifestStore, type StartupManifest } from './manifest.ts';
2929

3030
const debug = debuglog('egg/core/loader/egg_loader');
@@ -95,7 +95,10 @@ export class EggLoader {
9595
*/
9696
constructor(options: EggLoaderOptions) {
9797
this.options = options;
98-
this.loaderFS = this.options.loaderFS ?? new RealLoaderFS();
98+
const bundleStore = ManifestStore.getBundleStore();
99+
this.loaderFS =
100+
this.options.loaderFS ??
101+
(bundleStore?.baseDir === this.options.baseDir ? new ManifestLoaderFS(bundleStore) : new RealLoaderFS());
99102
assert(fs.existsSync(this.options.baseDir), `${this.options.baseDir} not exists`);
100103
assert(this.options.app, 'options.app is required');
101104
assert(this.options.logger, 'options.logger is required');
@@ -176,6 +179,9 @@ export class EggLoader {
176179
this.manifest =
177180
ManifestStore.load(this.options.baseDir, this.serverEnv, this.serverScope) ??
178181
ManifestStore.createCollector(this.options.baseDir);
182+
if (!this.options.loaderFS && !(this.loaderFS instanceof ManifestLoaderFS)) {
183+
this.loaderFS = new ManifestLoaderFS(this.manifest, this.loaderFS);
184+
}
179185
}
180186

181187
get app(): EggCore {
@@ -644,8 +650,8 @@ export class EggLoader {
644650
let pkg: any;
645651
let eggPluginConfig: any;
646652
const pluginPackage = path.join(plugin.path as string, 'package.json');
647-
if (await utils.existsPath(pluginPackage)) {
648-
pkg = await readJSON(pluginPackage);
653+
if (this.loaderFS.exists(pluginPackage)) {
654+
pkg = this.loaderFS.readJSON(pluginPackage);
649655
eggPluginConfig = pkg.eggPlugin;
650656
if (pkg.version) {
651657
plugin.version = pkg.version;
@@ -848,7 +854,7 @@ export class EggLoader {
848854
} else if (exports.require) {
849855
realPluginPath = path.join(pluginPath, exports.require);
850856
}
851-
if (exports.typescript && isSupportTypeScript() && !(await exists(realPluginPath))) {
857+
if (exports.typescript && isSupportTypeScript() && !this.loaderFS.exists(realPluginPath)) {
852858
// if require/import path not exists, use typescript path for development stage
853859
realPluginPath = path.join(pluginPath, exports.typescript);
854860
debug('[formatPluginPathFromPackageJSON] use typescript path %o', realPluginPath);
@@ -1796,6 +1802,7 @@ export class EggLoader {
17961802
*/
17971803
#collectConventionalDynamicFiles(manifest: StartupManifest): void {
17981804
for (const unit of this.getLoadUnits()) {
1805+
this.#collectConventionFile(manifest, path.join(unit.path, 'package.json'));
17991806
for (const load of CONVENTIONAL_MANIFEST_LOADS) {
18001807
const target = path.join(unit.path, ...load.path);
18011808
if (load.type === 'resolve') {
@@ -1838,6 +1845,19 @@ export class EggLoader {
18381845
return manifest.fileDiscovery[dirKey];
18391846
}
18401847

1848+
#collectConventionFile(manifest: StartupManifest, filepath: string): void {
1849+
const fileKey = this.#toManifestRel(filepath);
1850+
if (Object.values(manifest.resolveCache).includes(fileKey)) return;
1851+
if (!fs.existsSync(filepath) || !fs.statSync(filepath).isFile()) return;
1852+
1853+
const dirKey = this.#toManifestRel(path.dirname(filepath));
1854+
const basename = path.basename(filepath);
1855+
const files = manifest.fileDiscovery[dirKey] ?? [];
1856+
if (!files.includes(basename)) {
1857+
manifest.fileDiscovery[dirKey] = [...files, basename].sort();
1858+
}
1859+
}
1860+
18411861
#toManifestRel(filepath: string): string {
18421862
const rel = path.isAbsolute(filepath) ? path.relative(this.options.baseDir, filepath) : filepath;
18431863
return rel.replaceAll(path.sep, '/');

0 commit comments

Comments
 (0)