Skip to content

feat(tegg): load modules through loader fs#5954

Open
killagu wants to merge 5 commits into
nextfrom
agent/egg-dev/0f525f9a
Open

feat(tegg): load modules through loader fs#5954
killagu wants to merge 5 commits into
nextfrom
agent/egg-dev/0f525f9a

Conversation

@killagu
Copy link
Copy Markdown
Contributor

@killagu killagu commented May 28, 2026

Summary

  • route tegg module discovery through injected @eggjs/loader-fs and pass app.loader.loaderFS from the tegg plugin
  • keep LoaderUtil bundle-loader fallback behavior while using @eggjs/utils import semantics for normal imports
  • route controller discovery through LoaderFS and app loader manifest collection for bundled app/controller discovery

Tests

  • pnpm exec vitest run tegg/core/loader/test/Loader.test.ts tegg/core/loader/test/ModuleLoaderManifest.test.ts tegg/core/loader/test/LoaderFactoryManifest.test.ts tegg/plugin/controller/test/lib/EggControllerLoader.test.ts --testTimeout 20000 --hookTimeout 20000
  • pnpm --filter @eggjs/tegg-loader typecheck
  • pnpm --filter @eggjs/controller-plugin typecheck
  • pnpm --filter @eggjs/tegg-plugin typecheck
  • pnpm exec oxlint --type-aware --type-check --quiet tegg/core/loader/src/LoaderFactory.ts tegg/core/loader/src/LoaderUtil.ts tegg/core/loader/src/impl/ModuleLoader.ts tegg/core/loader/test/LoaderFactoryManifest.test.ts tegg/core/loader/test/ModuleLoaderManifest.test.ts tegg/plugin/controller/src/app.ts tegg/plugin/controller/src/lib/EggControllerLoader.ts tegg/plugin/controller/test/lib/EggControllerLoader.test.ts tegg/plugin/tegg/src/lib/EggModuleLoader.ts

Summary by CodeRabbit

  • Tests

    • Added/expanded tests for module and controller discovery, manifest-driven discovery, bundled-module loading, and CommonJS default-export handling; tests verify filesystem-backed discovery calls.
  • Refactor

    • Loaders and controller loaders now accept injectable filesystem abstractions and optional manifest-based discovery to make file discovery configurable and testable.
  • Bug Fixes

    • Improved import fallback and export normalization for more reliable loading of CJS and bundled modules.
  • Chores

    • Updated package dependencies to include a workspace filesystem loader and removed direct globby usage.

Review Change Stack

Copilot AI review requested due to automatic review settings May 28, 2026 15:59
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Threads an injectable LoaderFS through loader creation and controller discovery, refactors LoaderUtil module import and export normalization, updates package deps, and adds tests plus a CJS fixture.

Changes

LoaderFS Abstraction Implementation

Layer / File(s) Summary
LoaderOptions contract and LoaderFactory wiring
tegg/core/loader/src/LoaderFactory.ts
Adds LoaderOptions with optional loaderFS. Updates LoaderCreator and LoaderFactory.createLoader()/loadApp() to accept and forward options and pass loaderFS into ModuleLoader constructors or loader creators.
ModuleLoader filesystem injection
tegg/core/loader/src/impl/ModuleLoader.ts
ModuleLoader stores an injected LoaderFS (default RealLoaderFS) and uses loaderFS.glob() scoped to moduleDir instead of globby. Adds options-aware createModuleLoader() overload.
LoaderUtil import fallback & export normalization
tegg/core/loader/src/LoaderUtil.ts
Refactors loadFile() to prefer importModule(..., { importDefaultOnly: false }) or importFallback() when needed; adds importFallback() (Windows file:// handling) and normalizeExports() to wrap class default exports and coerce non-object returns.
Core loader tests, fixture and package deps
tegg/core/loader/test/*, tegg/core/loader/package.json
Adds tests (RecordingLoaderFS) to assert loaderFS propagation and glob cwd usage, adds a CJS fixture for default-exported prototype class, and updates package.json to add @eggjs/loader-fs and replace globby with @eggjs/utils.

EggControllerLoader Filesystem Integration

Layer / File(s) Summary
EggControllerLoader filesystem and manifest support
tegg/plugin/controller/src/lib/EggControllerLoader.ts
Constructor accepts loaderFS and optional manifest. Discovery delegates to manifest.globFiles() when present or to loaderFS.glob() (cwd=controllerDir). Paths are joined to controllerDir; discovery errors yield empty list.
EggControllerLoader test coverage
tegg/plugin/controller/test/lib/EggControllerLoader.test.ts
Adds tests that verify discovery uses loaderFS.glob() by default, uses manifest.globFiles() when provided, and falls back correctly when manifest lacks globFiles. Uses RecordingLoaderFS to capture glob calls and resets global bundle loader between tests.
Controller loader app initialization
tegg/plugin/controller/src/app.ts
Instantiates EggControllerLoader with { loaderFS: this.app.loader.loaderFS, manifest: this.app.loader.manifest }.
Controller plugin package dependencies
tegg/plugin/controller/package.json
Adds @eggjs/loader-fs, removes globby, and updates a path-to-regexp catalog reference.

EggModuleLoader LoaderFS Propagation

Layer / File(s) Summary
EggModuleLoader loaderFS propagation
tegg/plugin/tegg/src/lib/EggModuleLoader.ts
Passes this.app.loader.loaderFS into LoaderFactory.loadApp() and LoaderFactory.createLoader() to enable end-to-end loaderFS usage when building the app graph and loading modules.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • eggjs/egg#5867: Related changes to importModule/native dynamic import handling used by LoaderUtil fallback.
  • eggjs/egg#5943: Introduces a manifest-backed LoaderFS that pairs with this PR's LoaderFS wiring and normalization.
  • eggjs/egg#5932: Directly related LoaderUtil modifications around bundle loader branching and import fallback.

Suggested reviewers

  • akitaSummer
  • jerryliang64
  • gxkl

"A rabbit hops through the loader maze, 🐇
Injecting filesystems in nimble ways,
No globby tangles left to fight,
Tests record each glob call right,
Tiny paws tidy the loader days."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing module loading through an injected filesystem abstraction (loader fs), which is the central feature across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/egg-dev/0f525f9a

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors file discovery across the loaders by replacing direct globby usage with a customizable LoaderFS abstraction from @eggjs/loader-fs and integrating manifest-backed discovery. It also updates module loading to utilize @eggjs/utils. The feedback highlights a potential issue in EggControllerLoader.ts where a missing globFiles method on a defined manifest object would cause a silent failure due to an overly broad try-catch block; a defensive check is recommended to prevent this.

Comment thread tegg/plugin/controller/src/lib/EggControllerLoader.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 91.89189% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.32%. Comparing base (b015dce) to head (adbd7b0).

Files with missing lines Patch % Lines
tegg/core/loader/src/LoaderUtil.ts 81.25% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5954      +/-   ##
==========================================
+ Coverage   85.30%   85.32%   +0.02%     
==========================================
  Files         670      670              
  Lines       19552    19569      +17     
  Branches     3863     3872       +9     
==========================================
+ Hits        16678    16697      +19     
+ Misses       2481     2480       -1     
+ Partials      393      392       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 28, 2026

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: adbd7b0
Status: ✅  Deploy successful!
Preview URL: https://94eb4ae0.egg-cci.pages.dev
Branch Preview URL: https://agent-egg-dev-0f525f9a.egg-cci.pages.dev

View logs

@killagu killagu force-pushed the agent/egg-dev/0f525f9a branch from b02d496 to 13fa530 Compare May 28, 2026 16:03
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 28, 2026

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: adbd7b0
Status: ✅  Deploy successful!
Preview URL: https://314c0cfb.egg-v3.pages.dev
Branch Preview URL: https://agent-egg-dev-0f525f9a.egg-v3.pages.dev

View logs

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR routes tegg module and controller discovery through the shared LoaderFS abstraction so bundled/manifest-backed apps can reuse Egg’s injected loader filesystem instead of direct globby access.

Changes:

  • Adds optional loaderFS plumbing through LoaderFactory, ModuleLoader, tegg plugin module loading, and controller loading.
  • Updates LoaderUtil.loadFile to use @eggjs/utils import semantics while preserving bundle-loader fallback behavior.
  • Adds tests covering loaderFS-backed module/controller discovery and manifest-backed controller discovery.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tegg/plugin/tegg/src/lib/EggModuleLoader.ts Passes app.loader.loaderFS into tegg module loading paths.
tegg/plugin/controller/src/lib/EggControllerLoader.ts Uses LoaderFS and optional manifest-backed discovery for controllers.
tegg/plugin/controller/src/app.ts Registers controller loader with app loaderFS and manifest.
tegg/core/loader/src/LoaderFactory.ts Adds loader options and forwards loaderFS to created loaders.
tegg/core/loader/src/impl/ModuleLoader.ts Replaces direct globby use with injected LoaderFS.glob.
tegg/core/loader/src/LoaderUtil.ts Switches normal imports to importModule and preserves bundle fallback import behavior.
tegg/core/loader/package.json Adds loader-fs/utils dependencies and removes direct globby dependency.
tegg/plugin/controller/package.json Adds loader-fs dependency and removes direct globby dependency.
tegg/core/loader/test/ModuleLoaderManifest.test.ts Adds coverage for ModuleLoader loaderFS discovery.
tegg/core/loader/test/LoaderFactoryManifest.test.ts Adds coverage for LoaderFactory passing loaderFS.
tegg/plugin/controller/test/lib/EggControllerLoader.test.ts Adds coverage for controller loaderFS and manifest-backed discovery.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tegg/core/loader/src/LoaderUtil.ts`:
- Around line 84-87: The imported value from importModule(filePath, {
importDefaultOnly: false }) can be a bare CommonJS default (a function/class),
so before the subsequent Object.keys(exports) in loadFile(), normalize exports:
if exports is null or not an object (typeof exports !== 'object') or if it has
only a non-object default, wrap it into an object like { default: exports } (or
{ default: exports.default } as appropriate) so that default-exported protos are
discoverable; adjust the code around the exports assignment (the importModule
branch in LoaderUtil.ts) to perform this normalization before any
Object.keys(exports) usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 345d6fd8-8ae0-4ea0-8a5d-e0a58baaf742

📥 Commits

Reviewing files that changed from the base of the PR and between b015dce and b02d496.

📒 Files selected for processing (11)
  • tegg/core/loader/package.json
  • tegg/core/loader/src/LoaderFactory.ts
  • tegg/core/loader/src/LoaderUtil.ts
  • tegg/core/loader/src/impl/ModuleLoader.ts
  • tegg/core/loader/test/LoaderFactoryManifest.test.ts
  • tegg/core/loader/test/ModuleLoaderManifest.test.ts
  • tegg/plugin/controller/package.json
  • tegg/plugin/controller/src/app.ts
  • tegg/plugin/controller/src/lib/EggControllerLoader.ts
  • tegg/plugin/controller/test/lib/EggControllerLoader.test.ts
  • tegg/plugin/tegg/src/lib/EggModuleLoader.ts

Comment thread tegg/core/loader/src/LoaderUtil.ts
@killagu killagu force-pushed the agent/egg-dev/0f525f9a branch from 13fa530 to 6070490 Compare May 28, 2026 16:10
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Copilot AI review requested due to automatic review settings May 28, 2026 16:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tegg/plugin/controller/test/lib/EggControllerLoader.test.ts (1)

10-10: ⚡ Quick win

Consider importing global types for consistency.

Line 10 uses (globalThis as any) to access __EGG_BUNDLE_MODULE_LOADER__, while the ModuleLoaderManifest test file imports @eggjs/typings/global for type safety. Consider adding the same type import here for consistency:

import type {} from '`@eggjs/typings/global`';

This eliminates the need for the as any cast and ensures TypeScript is aware of the global declaration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tegg/plugin/controller/test/lib/EggControllerLoader.test.ts` at line 10, Add
a global type import to the top of the test file by adding `import type {} from
'`@eggjs/typings/global`';` and then remove the unsafe cast by replacing
`(globalThis as any).__EGG_BUNDLE_MODULE_LOADER__ = undefined;` with a direct
access `globalThis.__EGG_BUNDLE_MODULE_LOADER__ = undefined;` so TypeScript
recognizes the global declaration for `__EGG_BUNDLE_MODULE_LOADER__`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tegg/core/loader/test/ModuleLoaderManifest.test.ts`:
- Line 91: The test assertion compares requestedFiles (which
LoaderUtil.loadFile() normalizes to use forward slashes) against serviceFile and
repoFile (built with path.join, which on Windows uses backslashes), causing
platform-dependent failures; update the test so serviceFile and repoFile are
normalized to the same form as requestedFiles before asserting (e.g., call the
same normalization used by LoaderUtil.loadFile() or replace backslashes with
forward slashes) so that the comparison of requestedFiles, serviceFile, and
repoFile succeeds cross-platform.

In `@tegg/plugin/controller/test/lib/EggControllerLoader.test.ts`:
- Line 8: The test suite description string is wrong: change the describe(...)
call that currently reads 'plugin/controller/test/lib/EggModuleLoader.test.ts'
to 'plugin/controller/test/lib/EggControllerLoader.test.ts' so the describe
matches the actual test file/name and the class under test
(EggControllerLoader); update the describe argument where it appears in the test
file.

---

Nitpick comments:
In `@tegg/plugin/controller/test/lib/EggControllerLoader.test.ts`:
- Line 10: Add a global type import to the top of the test file by adding
`import type {} from '`@eggjs/typings/global`';` and then remove the unsafe cast
by replacing `(globalThis as any).__EGG_BUNDLE_MODULE_LOADER__ = undefined;`
with a direct access `globalThis.__EGG_BUNDLE_MODULE_LOADER__ = undefined;` so
TypeScript recognizes the global declaration for `__EGG_BUNDLE_MODULE_LOADER__`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b527eebc-4fc4-45a1-b979-7475b99fc9f0

📥 Commits

Reviewing files that changed from the base of the PR and between 6070490 and 702258d.

📒 Files selected for processing (2)
  • tegg/core/loader/test/ModuleLoaderManifest.test.ts
  • tegg/plugin/controller/test/lib/EggControllerLoader.test.ts

Comment thread tegg/core/loader/test/ModuleLoaderManifest.test.ts Outdated
Comment thread tegg/plugin/controller/test/lib/EggControllerLoader.test.ts Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Copilot AI review requested due to automatic review settings May 28, 2026 17:28
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Comment on lines +43 to +45
const moduleDescriptors = await LoaderFactory.loadApp(this.app.moduleReferences, loadAppManifest, {
loaderFS: this.app.loader.loaderFS,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants