Skip to content

fix(bundler): restore tegg manifest runtime paths#5937

Open
killagu wants to merge 1 commit intonextfrom
agent/egg-dev/c4dbef28
Open

fix(bundler): restore tegg manifest runtime paths#5937
killagu wants to merge 1 commit intonextfrom
agent/egg-dev/c4dbef28

Conversation

@killagu
Copy link
Copy Markdown
Contributor

@killagu killagu commented May 7, 2026

Summary

  • restore tegg moduleReferences/moduleDescriptors to runtime output paths inside the generated bundled worker
  • keep decoratedFiles loading through the bundle module loader by runtime path while preserving original absolute aliases
  • add a regression covering bundled controller/service/repository decorated files and public metadata consumption

Tests

  • pnpm --filter @eggjs/egg-bundler exec vitest run test/EntryGenerator.test.ts -u
  • pnpm --filter @eggjs/egg-bundler run test
  • pnpm --filter @eggjs/egg-bundler run typecheck
  • pnpm --filter @eggjs/egg-bundler run lint
  • after commit hook: pnpm --filter @eggjs/egg-bundler exec vitest run test/EntryGenerator.test.ts
  • after commit hook: pnpm --filter @eggjs/egg-bundler run typecheck
  • after commit hook: pnpm --filter @eggjs/egg-bundler run lint

Summary by CodeRabbit

  • Bug Fixes

    • Fixed manifest path resolution for bundled modules to ensure correct runtime reference handling.
  • Tests

    • Added end-to-end test to verify proper manifest path restoration and module loading at runtime.

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

coderabbitai Bot commented May 7, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 87a5a1bd-f9dd-410a-9f4e-8e35c4e1d6a7

📥 Commits

Reviewing files that changed from the base of the PR and between 0ebb28e and 43440e8.

⛔ Files ignored due to path filters (1)
  • tools/egg-bundler/test/__snapshots__/EntryGenerator.worker.canonical.snap is excluded by !**/*.snap
📒 Files selected for processing (2)
  • tools/egg-bundler/src/lib/EntryGenerator.ts
  • tools/egg-bundler/test/EntryGenerator.test.ts

📝 Walkthrough

Walkthrough

The PR modifies EntryGenerator.ts to restore bundle-time manifest paths to runtime-relative paths before creating the ManifestStore. A new helper function rewrites manifest tegg.moduleReferences[*].path and tegg.moduleDescriptors[*].unitPath using the runtime __outputDir. The ManifestStore.setBundleStore(...) call now uses the restored __RUNTIME_MANIFEST_DATA instead of the original MANIFEST_DATA. Tests are updated to verify path restoration and runtime module resolution.

Changes

Runtime Manifest Path Restoration

Layer / File(s) Summary
Path Restoration Helper Functions
tools/egg-bundler/src/lib/EntryGenerator.ts
__restoreBundleRuntimePath helper function is added to transform tegg manifest path fields by resolving relative paths against the runtime output directory.
Manifest Store Integration
tools/egg-bundler/src/lib/EntryGenerator.ts
Restored manifest variable is created after alias resolution and passed to ManifestStore.setBundleStore() as __RUNTIME_MANIFEST_DATA instead of the original MANIFEST_DATA.
Test Assertion Update
tools/egg-bundler/test/EntryGenerator.test.ts
Existing runtime-hooks test updated to expect ManifestStore.fromBundle(__RUNTIME_MANIFEST_DATA...) instead of ManifestStore.fromBundle(MANIFEST_DATA...).
End-to-End Runtime Test
tools/egg-bundler/test/EntryGenerator.test.ts
New comprehensive test creates a tegg-style module with FooRepository, FooService, and FooController, verifies manifest paths are restored at runtime, and confirms bundled modules resolve and load correctly via __EGG_BUNDLE_MODULE_LOADER__.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • eggjs/egg#5932: Both PRs normalize/restore TEgg manifest paths (moduleReferences.path and moduleDescriptors.unitPath) so EntryGenerator and runtime Loader use matching runtime-relative paths.
  • eggjs/egg#5844: Both PRs work with ManifestStore data structures (manifest extensions like tegg.moduleReferences/moduleDescriptors) and this PR updates runtime restoration and ManifestStore API invocation.
  • eggjs/egg#5906: Both PRs modify egg-bundler's EntryGenerator and runtime manifest handling, changing the generated worker entry to restore bundle manifest paths and invoke ManifestStore APIs with runtime manifest data.

Suggested reviewers

  • gxkl
  • akitaSummer
  • fengmk2

Poem

🐰 A bundler's paths were tangled and worn,
So we restore them with care each dawn,
Runtime directories guide the way,
Manifest modules load and play,
All resolved before the light of day!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: restoring tegg manifest runtime paths in the bundler, which aligns with the primary modifications in EntryGenerator.ts and test coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/egg-dev/c4dbef28

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.18%. Comparing base (0ebb28e) to head (43440e8).

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5937      +/-   ##
==========================================
- Coverage   85.19%   85.18%   -0.01%     
==========================================
  Files         668      668              
  Lines       19288    19288              
  Branches     3784     3784              
==========================================
- Hits        16432    16431       -1     
- Misses       2464     2465       +1     
  Partials      392      392              

☔ 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.

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 implements runtime restoration of relative paths in the tegg manifest to absolute paths, enabling correct loading of bundled modules. It includes a new test case for verification. Feedback recommends optimizing the manifest cloning process in __restoreBundleManifest to avoid performance overhead from JSON serialization during application startup.

Comment on lines +281 to +297
const __restoreBundleManifest = (manifest: typeof MANIFEST_DATA) => {
const restored = JSON.parse(JSON.stringify(manifest));
const tegg = restored.extensions?.tegg;
if (tegg?.moduleReferences) {
tegg.moduleReferences = tegg.moduleReferences.map((ref) => ({
...ref,
path: __restoreBundleRuntimePath(ref.path),
}));
}
if (tegg?.moduleDescriptors) {
tegg.moduleDescriptors = tegg.moduleDescriptors.map((desc) => ({
...desc,
unitPath: __restoreBundleRuntimePath(desc.unitPath),
}));
}
return restored;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The __restoreBundleManifest function is executed at application startup. Using JSON.parse(JSON.stringify(manifest)) to deep clone the entire manifest can be quite inefficient, especially for large applications where the manifest might be several megabytes.

Since we only need to modify specific paths within the tegg extension, we can optimize this by using an early return if the extension is missing and performing a shallow clone of the top-level structure and the tegg extension specifically. This avoids the overhead of stringifying and re-parsing the whole object.

const __restoreBundleManifest = (manifest: typeof MANIFEST_DATA) => {
  const tegg = manifest.extensions?.tegg;
  if (!tegg) return manifest;
  const restoredTegg = { ...tegg };
  if (restoredTegg.moduleReferences) {
    restoredTegg.moduleReferences = restoredTegg.moduleReferences.map((ref: any) => ({
      ...ref,
      path: __restoreBundleRuntimePath(ref.path),
    }));
  }
  if (restoredTegg.moduleDescriptors) {
    restoredTegg.moduleDescriptors = restoredTegg.moduleDescriptors.map((desc: any) => ({
      ...desc,
      unitPath: __restoreBundleRuntimePath(desc.unitPath),
    }));
  }
  return {
    ...manifest,
    extensions: {
      ...manifest.extensions,
      tegg: restoredTegg,
    },
  };
};

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

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 43440e8
Status: ✅  Deploy successful!
Preview URL: https://1afb3faf.egg-cci.pages.dev
Branch Preview URL: https://agent-egg-dev-c4dbef28.egg-cci.pages.dev

View logs

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 introduces a mechanism to restore bundle runtime paths within the Tegg manifest, ensuring that controller, service, and repository modules are correctly loaded using runtime paths. The changes include a new helper function __restoreBundleManifest and corresponding updates to the manifest loading logic in EntryGenerator.ts, along with a new test case to verify the path restoration. The review comment correctly identifies a performance concern regarding the use of JSON.parse(JSON.stringify()) for deep cloning the manifest and provides an optimized, more performant alternative for cloning only the necessary tegg extension data.

Comment on lines +281 to +297
const __restoreBundleManifest = (manifest: typeof MANIFEST_DATA) => {
const restored = JSON.parse(JSON.stringify(manifest));
const tegg = restored.extensions?.tegg;
if (tegg?.moduleReferences) {
tegg.moduleReferences = tegg.moduleReferences.map((ref) => ({
...ref,
path: __restoreBundleRuntimePath(ref.path),
}));
}
if (tegg?.moduleDescriptors) {
tegg.moduleDescriptors = tegg.moduleDescriptors.map((desc) => ({
...desc,
unitPath: __restoreBundleRuntimePath(desc.unitPath),
}));
}
return restored;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using JSON.parse(JSON.stringify(manifest)) to deep clone the entire manifest at runtime is inefficient, especially as the manifest (particularly fileDiscovery and resolveCache) can grow quite large in complex applications. Since only the tegg extension data requires path restoration, it is more performant to perform a shallow clone of the manifest and only update the specific tegg properties. This avoids the overhead of serializing and re-parsing the bulk of the manifest data during application startup.

const __restoreBundleManifest = (manifest: typeof MANIFEST_DATA) => {
  const tegg = manifest.extensions?.tegg as any;
  if (!tegg) return manifest;

  const restoredTegg = { ...tegg };
  if (tegg.moduleReferences) {
    restoredTegg.moduleReferences = tegg.moduleReferences.map((ref: any) => ({
      ...ref,
      path: __restoreBundleRuntimePath(ref.path),
    }));
  }
  if (tegg.moduleDescriptors) {
    restoredTegg.moduleDescriptors = tegg.moduleDescriptors.map((desc: any) => ({
      ...desc,
      unitPath: __restoreBundleRuntimePath(desc.unitPath),
    }));
  }

  return {
    ...manifest,
    extensions: {
      ...manifest.extensions,
      tegg: restoredTegg,
    },
  } as any;
};

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

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 43440e8
Status: ✅  Deploy successful!
Preview URL: https://e326a6f9.egg-v3.pages.dev
Branch Preview URL: https://agent-egg-dev-c4dbef28.egg-v3.pages.dev

View logs

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 introduces logic to restore runtime paths for the tegg extension in the bundle manifest, ensuring that module references and descriptors are correctly resolved relative to the output directory. It includes new helper functions for manifest restoration and a comprehensive test case to validate the loading of bundled modules. A review comment suggests optimizing the manifest cloning process by using object spreading instead of JSON.parse(JSON.stringify()) to improve performance during application startup.

Comment on lines +281 to +297
const __restoreBundleManifest = (manifest: typeof MANIFEST_DATA) => {
const restored = JSON.parse(JSON.stringify(manifest));
const tegg = restored.extensions?.tegg;
if (tegg?.moduleReferences) {
tegg.moduleReferences = tegg.moduleReferences.map((ref) => ({
...ref,
path: __restoreBundleRuntimePath(ref.path),
}));
}
if (tegg?.moduleDescriptors) {
tegg.moduleDescriptors = tegg.moduleDescriptors.map((desc) => ({
...desc,
unitPath: __restoreBundleRuntimePath(desc.unitPath),
}));
}
return restored;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using JSON.parse(JSON.stringify(manifest)) for deep cloning is inefficient, especially for large manifests which can be several megabytes in size. This adds unnecessary CPU and memory overhead during application startup. Since only the tegg extension paths need to be restored, a more efficient approach is to use object spreading to create a shallow copy of the manifest and only deep-clone the tegg extension object.

const __restoreBundleManifest = (manifest: typeof MANIFEST_DATA) => {
  const tegg = (manifest.extensions as any)?.tegg;
  if (!tegg) return manifest;
  return {
    ...manifest,
    extensions: {
      ...manifest.extensions,
      tegg: {
        ...tegg,
        moduleReferences: tegg.moduleReferences?.map((ref: any) => ({
          ...ref,
          path: __restoreBundleRuntimePath(ref.path),
        })),
        moduleDescriptors: tegg.moduleDescriptors?.map((desc: any) => ({
          ...desc,
          unitPath: __restoreBundleRuntimePath(desc.unitPath),
        })),
      },
    },
  };
};

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 fixes bundled-worker runtime behavior for Tegg by restoring moduleReferences/moduleDescriptors paths in the inlined manifest to runtime output paths, ensuring decorated modules are loaded via the bundle module loader at runtime.

Changes:

  • Restore Tegg moduleReferences[].path and moduleDescriptors[].unitPath to runtime (__outputDir-based) absolute paths inside the generated worker entry.
  • Keep existing absolute-alias behavior so original (bundle-time) absolute paths can still be resolved through the bundle loader.
  • Add a regression test and update the canonical worker snapshot to cover bundled controller/service/repository decorated files and public metadata consumption.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tools/egg-bundler/src/lib/EntryGenerator.ts Generates a runtime-restored manifest for Tegg paths before registering the bundle store.
tools/egg-bundler/test/EntryGenerator.test.ts Adds a runtime regression ensuring decorated files load via runtime paths and original absolute aliases still work.
tools/egg-bundler/test/snapshots/EntryGenerator.worker.canonical.snap Updates snapshot to reflect the new runtime manifest restoration logic in the generated worker.

const __APP_RESOLVE_CACHE_ALIASES: Array<[string, string]> = ${appResolveCacheAliases};
const __restoreBundleRuntimePath = (filepath: string) => {
if (!filepath || path.isAbsolute(filepath)) return filepath;
return path.resolve(__outputDir, filepath);
Comment on lines +282 to +296
const restored = JSON.parse(JSON.stringify(manifest));
const tegg = restored.extensions?.tegg;
if (tegg?.moduleReferences) {
tegg.moduleReferences = tegg.moduleReferences.map((ref) => ({
...ref,
path: __restoreBundleRuntimePath(ref.path),
}));
}
if (tegg?.moduleDescriptors) {
tegg.moduleDescriptors = tegg.moduleDescriptors.map((desc) => ({
...desc,
unitPath: __restoreBundleRuntimePath(desc.unitPath),
}));
}
return restored;
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