-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(static): migrate @eggjs/static plugin to monorepo (#5547) #5548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds a new Egg static plugin (middleware, types, configs, boot), tests/fixtures, package/build tooling and docs; updates workspace/tsconfig and dependencies; replaces a generic defineConfig API with defineConfigFactory and adjusts related imports and tests. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant App as Egg App
participant Boot as AppBoot
participant Static as Static Middleware
participant Router as Router
rect rgba(230,245,255,0.8)
note over Boot,App: Startup — AppBoot.configWillLoad ensures "static" inserted before "bodyParser"
Boot->>App: configWillLoad()
end
C->>App: HTTP request
activate App
App->>Static: invoke static middleware
alt request path matches any configured prefix
Static->>Static: apply koa-range (conditional on prefix)
alt file found in current dir
Static-->>C: 200 or 206 (with Content-Range)
else try next configured dir
Static->>Static: next()
Static-->>App: when all dirs exhausted
end
else no prefix match / non-static route
App->>Router: forward request
Router-->>C: route response
end
deactivate App
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
There was a problem hiding this 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 migrates the @eggjs/static plugin from a separate repository into the main Egg.js monorepo under the plugins/ directory. The migration includes updating the build system to use tsdown, replacing ESLint with oxlint, and updating tests to use vitest.
Key changes:
- Migrated @eggjs/static plugin from external repository to plugins/static/ directory
- Updated build toolchain to use tsdown for unbundled ESM builds and oxlint for linting
- Updated package dependency management to use workspace references and pnpm catalog
Reviewed Changes
Copilot reviewed 38 out of 40 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| pnpm-workspace.yaml | Added koa-range and ylru dependencies to pnpm catalog |
| plugins/static/ | Complete plugin migration with source code, tests, and configuration |
| packages/egg/package.json | Updated @eggjs/static dependency to use workspace reference |
| packages/egg/src/lib/types.plugin.ts | Updated type imports for the migrated static plugin |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
plugins/static/src/types.ts
Outdated
| maxAge: number; | ||
| /** | ||
| * dynamic load file which not cached on initialization | ||
| * Default to `true |
Copilot
AI
Sep 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing closing backtick and quote in the comment. Should be 'Default to true'
| * Default to `true | |
| * Default to `true` |
Summary of ChangesHello @fengmk2, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## next #5548 +/- ##
==========================================
+ Coverage 76.50% 77.15% +0.64%
==========================================
Files 131 138 +7
Lines 4491 4649 +158
Branches 651 684 +33
==========================================
+ Hits 3436 3587 +151
- Misses 984 991 +7
Partials 71 71 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this 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 successfully migrates the @eggjs/static plugin into the monorepo, including its source code, tests, and configurations. The changes are well-structured and the new test suite using vitest is comprehensive. I have a couple of suggestions for the new middleware implementation to enhance type safety and improve user experience by warning about deprecated options. Overall, this is a solid contribution to the project's structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Nitpick comments (8)
plugins/static/test/fixtures/static-server-with-dirs/package.json (1)
1-3: Mark fixture package as private to avoid accidental publish/workspace pickup.Add "private": true to this fixture’s package.json.
Apply this diff:
{ + "private": true, "name": "static" }plugins/static/src/index.ts (1)
1-1: Re-export StaticConfig and StaticDirOptions
tsconfig uses NodeNext resolution, soimport './types.js'correctly picks uptypes.ts. Add:import './types.js'; +export type { StaticConfig, StaticDirOptions } from './types.js';plugins/static/test/fixtures/static-server/package.json (1)
1-3: Mark fixture package.json as private to avoid accidental publishAdd
"private": trueto prevent publishing test fixtures to npm.Apply this diff:
{ - "name": "static-server" + "name": "static-server", + "private": true }plugins/static/test/fixtures/static-server-with-dir/package.json (1)
1-3: Mark fixture package.json as privatePrevents accidental publish for test-only package.
Apply this diff:
{ - "name": "static" + "name": "static", + "private": true }plugins/static/test/fixtures/static-server-custom/package.json (1)
1-3: Mark fixture package.json as privateAvoid publishing fixtures to npm.
Apply this diff:
{ - "name": "static" + "name": "static", + "private": true }plugins/static/test/fixtures/static-server-dist/package.json (1)
1-3: Mark fixture package.json as privatePrevents accidental publish of test fixture.
Apply this diff:
{ - "name": "static" + "name": "static", + "private": true }plugins/static/src/config/config.prod.ts (1)
3-7: Do not cast partial overrides as fullStaticConfig.This object only sets two fields but is asserted as the complete
StaticConfig, masking typos or missing required fields (e.g.,dir). Please type it as aPartial<StaticConfig>instead of lying to the compiler.-import type { StaticConfig } from '../types.js'; - -export default { - static: { - maxAge: 31536000, - buffer: true, - } as StaticConfig, -}; +import type { StaticConfig } from '../types.js'; + +const staticProdConfig: Partial<StaticConfig> = { + maxAge: 31536000, + buffer: true, +}; + +export default { + static: staticProdConfig, +};plugins/static/src/config/config.default.ts (1)
5-18: Provide an explicit return type and avoid theas StaticConfigcastThe loose arrow function plus
as StaticConfigassertion hides future type drift and goes against our guideline to use explicit return types for exported APIs. Refactoring to name the function, declare its return type, and assign the static config through a typed variable keeps full type-check coverage without unchecked casts. As per coding guidelines.Apply this diff:
-export default (appInfo: EggAppInfo) => { - return { - static: { - prefix: '/public/', - dir: path.join(appInfo.baseDir, 'app/public'), - // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ], - dirs: undefined, - // support lazy load - dynamic: true, - preload: false, - buffer: false, - maxFiles: 1000, - } as StaticConfig, - }; -}; +export default function config(appInfo: EggAppInfo): { static: StaticConfig } { + const staticConfig: StaticConfig = { + prefix: '/public/', + dir: path.join(appInfo.baseDir, 'app/public'), + // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ], + dirs: undefined, + // support lazy load + dynamic: true, + preload: false, + buffer: false, + maxFiles: 1000, + }; + + return { + static: staticConfig, + }; +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (39)
packages/egg/package.json(1 hunks)packages/egg/src/lib/types.plugin.ts(1 hunks)plugins/static/.gitignore(1 hunks)plugins/static/CHANGELOG.md(1 hunks)plugins/static/LICENSE(1 hunks)plugins/static/README.md(1 hunks)plugins/static/package.json(1 hunks)plugins/static/src/app.ts(1 hunks)plugins/static/src/app/middleware/static.ts(1 hunks)plugins/static/src/config/config.default.ts(1 hunks)plugins/static/src/config/config.prod.ts(1 hunks)plugins/static/src/index.ts(1 hunks)plugins/static/src/types.ts(1 hunks)plugins/static/test/fixtures/static-server-custom/app/assets/foo.js(1 hunks)plugins/static/test/fixtures/static-server-custom/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-custom/package.json(1 hunks)plugins/static/test/fixtures/static-server-dist/app/assets/foo.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-dist/package.json(1 hunks)plugins/static/test/fixtures/static-server-with-dir/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/package.json(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/package.json(1 hunks)plugins/static/test/fixtures/static-server/app/controller/foo.js(1 hunks)plugins/static/test/fixtures/static-server/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server/app/router.js(1 hunks)plugins/static/test/fixtures/static-server/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server/package.json(1 hunks)plugins/static/test/static.test.ts(1 hunks)plugins/static/tsconfig.json(1 hunks)plugins/static/tsdown.config.ts(1 hunks)plugins/static/vitest.config.ts(1 hunks)pnpm-workspace.yaml(3 hunks)tsconfig.json(1 hunks)
👮 Files not reviewed due to content moderation or server errors (7)
- plugins/static/test/fixtures/static-server-custom/app/assets/foo.js
- plugins/static/LICENSE
- plugins/static/tsdown.config.ts
- plugins/static/test/fixtures/static-server-dist/config/plugin.js
- plugins/static/test/fixtures/static-server/config/config.default.js
- plugins/static/test/fixtures/static-server/app/router.js
- pnpm-workspace.yaml
🧰 Additional context used
📓 Path-based instructions (17)
**/test/fixtures/**
📄 CodeRabbit inference engine (AGENTS.md)
Put reusable test data under test/fixtures/
Files:
plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.jsplugins/static/test/fixtures/static-server-with-dir/app/public/foo.jsplugins/static/test/fixtures/static-server-custom/app/assets/foo.jsplugins/static/test/fixtures/static-server-with-dirs/config/plugin.jsplugins/static/test/fixtures/static-server-with-dir/package.jsonplugins/static/test/fixtures/static-server-custom/package.jsonplugins/static/test/fixtures/static-server/config/config.default.jsplugins/static/test/fixtures/static-server-dist/config/plugin.jsplugins/static/test/fixtures/static-server-with-dir/config/config.default.jsplugins/static/test/fixtures/static-server/app/router.jsplugins/static/test/fixtures/static-server-dist/app/assets/foo.jsplugins/static/test/fixtures/static-server-dist/config/config.default.jsplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/test/fixtures/static-server/package.jsonplugins/static/test/fixtures/static-server/app/public/foo.jsplugins/static/test/fixtures/static-server/app/controller/foo.jsplugins/static/test/fixtures/static-server-with-dirs/package.jsonplugins/static/test/fixtures/static-server-custom/config/config.default.jsplugins/static/test/fixtures/static-server-with-dir/config/plugin.jsplugins/static/test/fixtures/static-server-with-dirs/config/config.default.js
plugins/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
plugins/**/package.json: Plugin package.json must include peerDependencies { "egg": "workspace:" }
Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/.js
Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Files:
plugins/static/test/fixtures/static-server-with-dir/package.jsonplugins/static/test/fixtures/static-server-custom/package.jsonplugins/static/package.jsonplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/test/fixtures/static-server/package.jsonplugins/static/test/fixtures/static-server-with-dirs/package.json
{packages,plugins,tools}/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/package.json: All packages must provide a typecheck script using "tsc --noEmit"
All packages must use oxlint for linting with the command "oxlint --type-aware" (no ESLint configs)
Files:
plugins/static/test/fixtures/static-server-with-dir/package.jsonplugins/static/test/fixtures/static-server-custom/package.jsonplugins/static/package.jsonplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/test/fixtures/static-server/package.jsonpackages/egg/package.jsonplugins/static/test/fixtures/static-server-with-dirs/package.json
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable
Files:
plugins/static/src/config/config.default.tsplugins/static/src/index.tsplugins/static/src/app.tsplugins/static/tsdown.config.tsplugins/static/src/types.tsplugins/static/test/static.test.tsplugins/static/vitest.config.tsplugins/static/src/app/middleware/static.tsplugins/static/src/config/config.prod.tspackages/egg/src/lib/types.plugin.ts
{packages,plugins,tools}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/*.{ts,tsx}: Prefer interfaces over type aliases for object shapes in TypeScript
Use explicit return types for public APIs
Use readonly modifiers where appropriate
Avoid the any type; prefer unknown when the type is truly unknown
Files:
plugins/static/src/config/config.default.tsplugins/static/src/index.tsplugins/static/src/app.tsplugins/static/tsdown.config.tsplugins/static/src/types.tsplugins/static/test/static.test.tsplugins/static/vitest.config.tsplugins/static/src/app/middleware/static.tsplugins/static/src/config/config.prod.tspackages/egg/src/lib/types.plugin.ts
plugins/**/tsdown.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All plugins must use the standard tsdown config: entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true
Files:
plugins/static/tsdown.config.ts
{packages,plugins,tools}/**/tsdown.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Packages should use tsdown for builds (presence of tsdown.config.ts)
Files:
plugins/static/tsdown.config.ts
**/test/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites
Files:
plugins/static/test/static.test.ts
{packages,plugins,tools}/**/test/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test files should follow the pattern test/**/*.test.ts
Files:
plugins/static/test/static.test.ts
{packages,plugins,tools}/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Files:
plugins/static/test/static.test.ts
packages/*/package.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use "workspace:*" for internal workspace dependencies in package.json
Files:
packages/egg/package.json
plugins/**/vitest.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All new plugins must use Vitest and include vitest.config.ts
Files:
plugins/static/vitest.config.ts
{packages,plugins,tools,examples,site}/**/tsconfig.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools,examples,site}/**/tsconfig.json: All sub-project tsconfig.json files must extend the root tsconfig.json ("extends": "../../tsconfig.json")
Enable TypeScript strict mode in all packages (compilerOptions.strict: true)
Files:
plugins/static/tsconfig.json
{tsconfig.json,packages/*/tsconfig.json}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Enable strict TypeScript mode across all packages
Files:
tsconfig.json
tsconfig.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Root tsconfig.json must include all packages in the references array
Files:
tsconfig.json
pnpm-workspace.yaml
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"
Files:
pnpm-workspace.yaml
packages/**/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use TypeScript for all source files in packages (no JavaScript source files)
Files:
packages/egg/src/lib/types.plugin.ts
🧠 Learnings (28)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json must include peerDependencies { "egg": "workspace:*" }
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/*.ts : Re-export types thoughtfully to keep the public API stable
Applied to files:
plugins/static/src/index.tspackages/egg/src/lib/types.plugin.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.{ts,tsx} : Use explicit return types for public APIs
Applied to files:
plugins/static/src/index.tsplugins/static/src/types.tspackages/egg/src/lib/types.plugin.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/*.js
Applied to files:
plugins/static/package.jsonplugins/static/tsdown.config.tsplugins/static/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Applied to files:
plugins/static/package.jsonplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/test/fixtures/static-server-with-dirs/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json must include peerDependencies { "egg": "workspace:*" }
Applied to files:
plugins/static/package.jsonpackages/egg/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
Applied to files:
plugins/static/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/tsdown.config.ts : All plugins must use the standard tsdown config: entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true
Applied to files:
plugins/static/tsdown.config.tsplugins/static/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/tsdown.config.ts : Packages should use tsdown for builds (presence of tsdown.config.ts)
Applied to files:
plugins/static/tsdown.config.tsplugins/static/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsdown.config.ts : Each package must provide a tsdown.config.ts for unbundled ESM builds
Applied to files:
plugins/static/tsdown.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to plugins/**/vitest.config.ts : All new plugins must use Vitest and include vitest.config.ts
Applied to files:
plugins/static/tsdown.config.tsplugins/static/vitest.config.tsplugins/static/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.test.ts : In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/cookies/test/**/*.test.ts : cookies package uses Mocha; test files follow test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use Node.js built-in assert module for test assertions
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/package.json : Use "workspace:*" for internal workspace dependencies in package.json
Applied to files:
packages/egg/package.jsonpnpm-workspace.yaml
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to pnpm-workspace.yaml : Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"
Applied to files:
packages/egg/package.jsonpnpm-workspace.yaml
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Use pnpm catalog mode: external deps referenced as "catalog:" and internal workspace deps as "workspace:*"
Applied to files:
packages/egg/package.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to {packages,plugins,tools,examples,site}/**/tsconfig.json : All sub-project tsconfig.json files must extend the root tsconfig.json ("extends": "../../tsconfig.json")
Applied to files:
plugins/static/tsconfig.jsontsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsconfig.json : All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"
Applied to files:
plugins/static/tsconfig.jsontsconfig.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to {packages,plugins,tools,examples,site}/**/tsconfig.json : Enable TypeScript strict mode in all packages (compilerOptions.strict: true)
Applied to files:
plugins/static/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to tsconfig.json : Root tsconfig.json must include all packages in the references array
Applied to files:
tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to packages/{egg,core}/tsconfig.json : packages/egg and packages/core must have strict mode enabled in their tsconfig.json
Applied to files:
packages/egg/src/lib/types.plugin.ts
🧬 Code graph analysis (13)
plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js (1)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
exports(4-4)
plugins/static/src/config/config.default.ts (1)
plugins/static/src/types.ts (1)
StaticConfig(46-57)
plugins/static/test/fixtures/static-server-dist/config/plugin.js (1)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
exports(4-4)
plugins/static/test/fixtures/static-server-with-dir/config/config.default.js (1)
plugins/static/src/config/config.default.ts (1)
appInfo(5-19)
plugins/static/src/app.ts (1)
packages/core/src/egg.ts (1)
EggCore(95-543)
plugins/static/tsdown.config.ts (1)
packages/egg/src/lib/types.ts (1)
defineConfig(109-111)
plugins/static/src/types.ts (1)
packages/egg/src/lib/types.ts (1)
EggAppConfig(113-287)
plugins/static/test/static.test.ts (2)
scripts/version.js (2)
__filename(11-11)__dirname(12-12)packages/egg/test/utils.ts (1)
MockApplication(24-24)
plugins/static/vitest.config.ts (1)
packages/egg/src/lib/types.ts (1)
defineConfig(109-111)
plugins/static/src/app/middleware/static.ts (2)
plugins/static/src/types.ts (2)
StaticConfig(46-57)StaticDirOptions(3-39)packages/koa-static-cache/src/index.ts (1)
staticCache(139-321)
plugins/static/src/config/config.prod.ts (1)
plugins/static/src/types.ts (1)
StaticConfig(46-57)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (2)
plugins/static/test/fixtures/static-server-with-dir/config/config.default.js (1)
path(1-1)plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js (1)
path(1-1)
plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js (1)
plugins/static/src/config/config.default.ts (1)
appInfo(5-19)
🪛 GitHub Check: Test (ubuntu-latest, 22, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (macos-latest, 22, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 markdownlint-cli2 (0.18.1)
plugins/static/README.md
20-20: Bare URL used
(MD034, no-bare-urls)
22-22: Bare URL used
(MD034, no-bare-urls)
30-30: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
30-30: Hard tabs
Column: 1
(MD010, no-hard-tabs)
31-31: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
31-31: Hard tabs
Column: 1
(MD010, no-hard-tabs)
32-32: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
32-32: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
36-36: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
36-36: Hard tabs
Column: 1
(MD010, no-hard-tabs)
37-37: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
37-37: Hard tabs
Column: 1
(MD010, no-hard-tabs)
40-40: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
41-41: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
41-41: Hard tabs
Column: 1
(MD010, no-hard-tabs)
44-44: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
44-44: Hard tabs
Column: 1
(MD010, no-hard-tabs)
45-45: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
45-45: Hard tabs
Column: 1
(MD010, no-hard-tabs)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
- GitHub Check: Test (ubuntu-latest, 24, plugins)
- GitHub Check: Test (macos-latest, 24, plugins)
- GitHub Check: Test (windows-latest, 24, packages)
- GitHub Check: Test (ubuntu-latest, 22, packages)
- GitHub Check: Test (macos-latest, 24, packages)
- GitHub Check: Test (windows-latest, 22, packages)
- GitHub Check: Test (macos-latest, 22, tools)
- GitHub Check: Test (windows-latest, 24, plugins)
- GitHub Check: Test (windows-latest, 22, plugins)
- GitHub Check: Test (ubuntu-latest, 24, packages)
- GitHub Check: Test egg-bin (windows-latest, 24)
- GitHub Check: Test egg-bin (macos-latest, 22)
- GitHub Check: Test egg-bin (windows-latest, 22)
- GitHub Check: Test egg-bin (ubuntu-latest, 24)
- GitHub Check: Test egg-bin (macos-latest, 24)
- GitHub Check: Test egg-bin (ubuntu-latest, 22)
🔇 Additional comments (15)
plugins/static/.gitignore (1)
1-11: LGTM on ignore patternsIgnore list matches the plugin's workspace layout and keeps build artifacts, fixtures, and temp files out of VCS.
packages/egg/package.json (1)
133-133: Switch to workspace dependency aligns with the new plugin locationPointing
@eggjs/statictoworkspace:*keeps the core package synced with the in-repo plugin and matches our workspace policy. Based on learnings.plugins/static/test/fixtures/static-server/app/controller/foo.js (1)
3-7: LGTM for fixture handler.Simple CJS controller is fine for test fixtures; response fields are set correctly.
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
6-9: Summary mismatch: dynamic/preload/buffer not present.The AI summary mentions dynamic, preload, and buffer, but the code only sets prefix and dir. Confirm defaults suffice for this fixture or add explicit flags if tests expect them.
plugins/static/test/fixtures/static-server-with-dir/app/public/foo.js (1)
1-1: LGTM for static asset.Appropriate minimal test fixture asset.
plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js (1)
1-1: LGTM: plugin enabled for fixture.exports.static = true is correct for the fixture setup.
plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.js (1)
1-1: LGTM for static asset.Minimal fixture asset is fine.
plugins/static/CHANGELOG.md (1)
10-12: Node.js ≥22.18.0 requirement is consistent across CHANGELOG, package.json engines, and CI matrix.plugins/static/test/fixtures/static-server/app/public/foo.js (1)
1-1: LGTM for fixture assetSimple static asset is fine.
tsconfig.json (1)
56-60: Added plugins/static to TS project references — looks goodReference placement and JSON structure are correct.
packages/egg/src/lib/types.plugin.ts (1)
14-14: Add missing clean script in plugin package.jsonplugins/static/package.json: add
"clean": "rimraf dist"
under scripts to meet plugin standards.⛔ Skipped due to learnings
Learnt from: CR PR: eggjs/egg#0 File: CLAUDE.md:0-0 Timestamp: 2025-09-26T12:42:04.198Z Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)Learnt from: CR PR: eggjs/egg#0 File: CLAUDE.md:0-0 Timestamp: 2025-09-26T12:42:04.198Z Learning: Applies to plugins/**/package.json : Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/*.jsLearnt from: CR PR: eggjs/egg#0 File: CLAUDE.md:0-0 Timestamp: 2025-09-26T12:42:04.197Z Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.tsplugins/static/test/fixtures/static-server-dist/app/assets/foo.js (1)
1-1: Fixture asset looks goodThe minimal script is all this fixture needs—no issues spotted.
plugins/static/test/fixtures/static-server-with-dir/config/plugin.js (1)
1-1: Plugin flag wiring looks rightConfirming the fixture exposes the static plugin exactly as expected.
plugins/static/vitest.config.ts (1)
1-8: Vitest config matches project conventionsTimeout and test globs line up with the repo’s testing standards—looks good.
plugins/static/test/fixtures/static-server-dist/config/config.default.js (1)
1-8: Fixture config matches the expected dist/static layoutThe prefix, directory, and buffering options align with the other static server fixtures. Looks good to me.
| - prefix: `'/public/'` | ||
| - dir: `path.join(appInfo.baseDir, 'app/public')` | ||
| - dynamic: `true` | ||
| - preload: `false` | ||
| - maxAge: `31536000` in prod env, `0` in other envs | ||
| - buffer: `true` in prod env, `false` in other envs | ||
|
|
||
| `@eggjs/static` provides one more option: | ||
|
|
||
| - maxFiles: the maximum value of cache items, only effective when dynamic is true, default is `1000`. | ||
|
|
||
| **All static files in `$baseDir/app/public` can be visited with prefix `/public`, and all the files are lazy loaded.** | ||
|
|
||
| - In non-production environment, assets won't be cached, your modification can take effect immediately. | ||
| - In production environment, `@eggjs/static` will cache the assets after visited, you need to restart the process to update the assets. | ||
| - Dir default is `$baseDir/app/public` but you can also define **multiple directory** by use `dir: [dir1, dir2, ...]` or `dir: [dir1, { prefix: '/static2', dir: dir2 }]`, static server will use all these directories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix markdownlint violations in list indentation
Each list item here is preceded by a hard tab, so markdownlint reports MD010/MD007 failures and the docs lint step will keep failing. Please replace the tabs with spaces (two spaces after the hyphen is fine) so the list renders correctly and the lint job passes. Based on static analysis hints.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
30-30: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
30-30: Hard tabs
Column: 1
(MD010, no-hard-tabs)
31-31: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
31-31: Hard tabs
Column: 1
(MD010, no-hard-tabs)
32-32: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
32-32: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
36-36: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
36-36: Hard tabs
Column: 1
(MD010, no-hard-tabs)
37-37: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
37-37: Hard tabs
Column: 1
(MD010, no-hard-tabs)
40-40: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
41-41: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
41-41: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🤖 Prompt for AI Agents
In plugins/static/README.md around lines 27 to 42, several list items use hard
tabs before the hyphen which causes markdownlint MD010/MD007 failures; replace
each leading tab with spaces (use a single space or two spaces after the hyphen
for list content, e.g., "- prefix: ..." or "- prefix: ..." consistently) across
that block so the items are space-indented, and ensure nested/continued lines
follow standard Markdown list spacing to resolve the lint errors.
| const index = app.config.coreMiddleware.indexOf('bodyParser'); | ||
| if (index === -1) { | ||
| app.config.coreMiddleware.push('static'); | ||
| } else { | ||
| app.config.coreMiddleware.splice(index, 0, 'static'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent duplicate static middleware registrations
coreMiddleware may already contain 'static' (either from user config or legacy defaults). Injecting another 'static' entry without deduplication registers the middleware twice, so every non-static request now pays for two static passes and apps that already positioned the middleware correctly end up with redundant work. Please drop any existing 'static' entry before re‑inserting it ahead of bodyParser.
- const index = app.config.coreMiddleware.indexOf('bodyParser');
- if (index === -1) {
- app.config.coreMiddleware.push('static');
- } else {
- app.config.coreMiddleware.splice(index, 0, 'static');
- }
+ const middlewares = app.config.coreMiddleware;
+ const existingIndex = middlewares.indexOf('static');
+ if (existingIndex !== -1) {
+ middlewares.splice(existingIndex, 1);
+ }
+ const bodyParserIndex = middlewares.indexOf('bodyParser');
+ if (bodyParserIndex === -1) {
+ middlewares.push('static');
+ } else {
+ middlewares.splice(bodyParserIndex, 0, 'static');
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const index = app.config.coreMiddleware.indexOf('bodyParser'); | |
| if (index === -1) { | |
| app.config.coreMiddleware.push('static'); | |
| } else { | |
| app.config.coreMiddleware.splice(index, 0, 'static'); | |
| } | |
| const middlewares = app.config.coreMiddleware; | |
| const existingIndex = middlewares.indexOf('static'); | |
| if (existingIndex !== -1) { | |
| middlewares.splice(existingIndex, 1); | |
| } | |
| const bodyParserIndex = middlewares.indexOf('bodyParser'); | |
| if (bodyParserIndex === -1) { | |
| middlewares.push('static'); | |
| } else { | |
| middlewares.splice(bodyParserIndex, 0, 'static'); | |
| } |
🤖 Prompt for AI Agents
In plugins/static/src/app.ts around lines 11 to 16, the code can insert a
duplicate 'static' into app.config.coreMiddleware; before inserting, remove any
existing 'static' entries from coreMiddleware, then compute the index of
'bodyParser' and insert 'static' ahead of it (or push if bodyParser not
present). Ensure you remove all occurrences of 'static' (e.g., filter or loop to
splice) before performing the splice or push so the middleware is deduplicated
and only inserted once.
| if (newOptions.prefix) { | ||
| prefixes.push(newOptions.prefix); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore range support for empty-prefix static mounts.
Skipping falsy prefixes drops range handling when prefix is '', so assets mounted at root lose HTTP range functionality (regression from prior behavior). Normalize the prefix and always record it.
- if (newOptions.prefix) {
- prefixes.push(newOptions.prefix);
- }
+ const normalizedPrefix = (newOptions.prefix ?? '').replace(/\/*$/, '/');
+ prefixes.push(normalizedPrefix);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (newOptions.prefix) { | |
| prefixes.push(newOptions.prefix); | |
| } | |
| const normalizedPrefix = (newOptions.prefix ?? '').replace(/\/*$/, '/'); | |
| prefixes.push(normalizedPrefix); |
🤖 Prompt for AI Agents
In plugins/static/src/app/middleware/static.ts around lines 55 to 57, the code
skips falsy prefixes which drops support for an explicit empty-string prefix and
breaks range handling for assets mounted at root; instead, normalize the prefix
value to a string (e.g. default to '' when undefined/null) and always push that
normalized prefix into the prefixes array so empty-string mounts are preserved
and range handling remains enabled.
| prefix: string; | ||
| /** | ||
| * cache max age in `seconds` | ||
| * Default to `0` on development, `31536000` on production | ||
| */ | ||
| maxAge: number; | ||
| /** | ||
| * dynamic load file which not cached on initialization | ||
| * Default to `true | ||
| */ | ||
| dynamic: boolean; | ||
| /** | ||
| * caches the assets on initialization or not, | ||
| * always work together with `options.dynamic` | ||
| * Default to `false` | ||
| */ | ||
| preload: boolean; | ||
| /** | ||
| * buffer the file content or not | ||
| * Default to `false` on development, `true` on production | ||
| */ | ||
| buffer: boolean; | ||
| /** | ||
| * max files count in store | ||
| * Default to `1000` | ||
| */ | ||
| maxFiles: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep static config properties optional for consumers
By redeclaring prefix, maxAge, dynamic, preload, buffer, and maxFiles as required, the augmented EggAppConfig['static'] now forces every app to specify these fields explicitly even when relying on the documented defaults from @eggjs/koa-static-cache. This breaks existing TypeScript configs that only override a subset of options. Please leave these members optional (matching StaticCacheOptions) so downstream configs remain valid.
- prefix: string;
+ prefix?: string;
@@
- maxAge: number;
+ maxAge?: number;
@@
- dynamic: boolean;
+ dynamic?: boolean;
@@
- preload: boolean;
+ preload?: boolean;
@@
- buffer: boolean;
+ buffer?: boolean;
@@
- maxFiles: number;
+ maxFiles?: number;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| prefix: string; | |
| /** | |
| * cache max age in `seconds` | |
| * Default to `0` on development, `31536000` on production | |
| */ | |
| maxAge: number; | |
| /** | |
| * dynamic load file which not cached on initialization | |
| * Default to `true | |
| */ | |
| dynamic: boolean; | |
| /** | |
| * caches the assets on initialization or not, | |
| * always work together with `options.dynamic` | |
| * Default to `false` | |
| */ | |
| preload: boolean; | |
| /** | |
| * buffer the file content or not | |
| * Default to `false` on development, `true` on production | |
| */ | |
| buffer: boolean; | |
| /** | |
| * max files count in store | |
| * Default to `1000` | |
| */ | |
| maxFiles: number; | |
| prefix?: string; | |
| /** | |
| * cache max age in `seconds` | |
| * Default to `0` on development, `31536000` on production | |
| */ | |
| maxAge?: number; | |
| /** | |
| * dynamic load file which not cached on initialization | |
| * Default to `true | |
| */ | |
| dynamic?: boolean; | |
| /** | |
| * caches the assets on initialization or not, | |
| * always work together with `options.dynamic` | |
| * Default to `false` | |
| */ | |
| preload?: boolean; | |
| /** | |
| * buffer the file content or not | |
| * Default to `false` on development, `true` on production | |
| */ | |
| buffer?: boolean; | |
| /** | |
| * max files count in store | |
| * Default to `1000` | |
| */ | |
| maxFiles?: number; |
🤖 Prompt for AI Agents
In plugins/static/src/types.ts around lines 12 to 38, the properties prefix,
maxAge, dynamic, preload, buffer and maxFiles were declared as required which
forces downstream apps to specify them; change the declarations to be optional
to match @eggjs/koa-static-cache defaults — either mark each property with ? or
better reuse the upstream type (e.g. import StaticCacheOptions and make
EggAppConfig['static'] extend or be Partial<StaticCacheOptions> plus any
plugin-specific fields) so consumers can override only a subset of options.
| dir: [path.join(appInfo.baseDir, '/app/public'), path.join(appInfo.baseDir, '/dist/static')], | ||
| buffer: true, | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the leading slash when joining fixture dirs
path.join(appInfo.baseDir, '/app/public') treats the second argument as absolute, so the baseDir is dropped and we end up serving /app/public from the filesystem root. Same for the /dist/static join. That breaks the fixture and any tests relying on it.
Apply this diff:
- dir: [path.join(appInfo.baseDir, '/app/public'), path.join(appInfo.baseDir, '/dist/static')],
+ dir: [
+ path.join(appInfo.baseDir, 'app/public'),
+ path.join(appInfo.baseDir, 'dist/static'),
+ ],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| dir: [path.join(appInfo.baseDir, '/app/public'), path.join(appInfo.baseDir, '/dist/static')], | |
| buffer: true, | |
| }, | |
| dir: [ | |
| path.join(appInfo.baseDir, 'app/public'), | |
| path.join(appInfo.baseDir, 'dist/static'), | |
| ], | |
| buffer: true, | |
| }, |
🤖 Prompt for AI Agents
In plugins/static/test/fixtures/static-server-with-dir/config/config.default.js
around lines 8 to 10, the path.join calls use leading slashes which make the
second argument absolute and drop appInfo.baseDir; change
path.join(appInfo.baseDir, '/app/public') to path.join(appInfo.baseDir,
'app/public') and path.join(appInfo.baseDir, '/dist/static') to
path.join(appInfo.baseDir, 'dist/static') so the fixture serves from the
intended project-relative directories.
plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (4)
plugins/static/CHANGELOG.md (1)
29-46: Replace hard tabs in the summary listThe bullets under “Summary by CodeRabbit” are tab-indented, which violates the markdown style (MD007/MD010) and will keep markdownlint failing. Switch to space indentation.
-- - **New Features** -- - Updated package to `@eggjs/static` -- - Enhanced TypeScript support -- - Improved static file serving configuration -- -- - **Chores** -- - Updated GitHub Actions workflows -- - Modernized project configuration -- - Updated Node.js version support to 18.19.0, 20, and 22 -- -- - **Documentation** -- - Updated README with new package details -- - Simplified changelog and documentation -- -- - **Refactor** -- - Migrated from CommonJS to ES modules -- - Restructured project file organization +- **New Features** + - Updated package to `@eggjs/static` + - Enhanced TypeScript support + - Improved static file serving configuration + +- **Chores** + - Updated GitHub Actions workflows + - Modernized project configuration + - Updated Node.js version support to 18.19.0, 20, and 22 + +- **Documentation** + - Updated README with new package details + - Simplified changelog and documentation + +- **Refactor** + - Migrated from CommonJS to ES modules + - Restructured project file organizationplugins/static/src/config/config.prod.ts (1)
3-8: Avoid asserting a partial config as full StaticConfigThe
as StaticConfigassertion hides that this file only overrides a subset of fields (e.g., nodir). Usingsatisfies Partial<StaticConfig>keeps the override honest while preserving type safety.export default { static: { maxAge: 31536000, buffer: true, - } as StaticConfig, + } satisfies Partial<StaticConfig>, };plugins/static/README.md (1)
55-55: Make the support link descriptiveMarkdownlint flags “[here]” as non-descriptive. Please expand the anchor text so readers (and accessibility tools) know where it leads.
Apply this diff:
-Please open an issue [here](https://github.com/eggjs/egg/issues). +Please open an issue on the [eggjs/egg issue tracker](https://github.com/eggjs/egg/issues).Based on static analysis hints.
plugins/static/src/config/config.default.ts (1)
5-18: Add explicit return type to exported configThis default export is part of the plugin’s public surface, but it relies on inference plus an
ascast for typing. Declaring the return type directly improves readability and eliminates the cast.-export default (appInfo: EggAppInfo) => { - return { - static: { - prefix: '/public/', - dir: path.join(appInfo.baseDir, 'app/public'), - // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ], - dirs: undefined, - // support lazy load - dynamic: true, - preload: false, - buffer: false, - maxFiles: 1000, - } as StaticConfig, - }; -}; +export default (appInfo: EggAppInfo): { static: StaticConfig } => ({ + static: { + prefix: '/public/', + dir: path.join(appInfo.baseDir, 'app/public'), + // dirs: [ dir1, dir2 ] or [ dir1, { prefix: '/static2', dir: dir2 } ], + dirs: undefined, + // support lazy load + dynamic: true, + preload: false, + buffer: false, + maxFiles: 1000, + }, +});As per coding guidelines
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (40)
CLAUDE.md(2 hunks)packages/egg/package.json(1 hunks)packages/egg/src/lib/types.plugin.ts(1 hunks)plugins/static/.gitignore(1 hunks)plugins/static/CHANGELOG.md(1 hunks)plugins/static/LICENSE(1 hunks)plugins/static/README.md(1 hunks)plugins/static/package.json(1 hunks)plugins/static/src/app.ts(1 hunks)plugins/static/src/app/middleware/static.ts(1 hunks)plugins/static/src/config/config.default.ts(1 hunks)plugins/static/src/config/config.prod.ts(1 hunks)plugins/static/src/index.ts(1 hunks)plugins/static/src/types.ts(1 hunks)plugins/static/test/fixtures/static-server-custom/app/assets/foo.js(1 hunks)plugins/static/test/fixtures/static-server-custom/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-custom/package.json(1 hunks)plugins/static/test/fixtures/static-server-dist/app/assets/foo.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-dist/package.json(1 hunks)plugins/static/test/fixtures/static-server-with-dir/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/package.json(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/package.json(1 hunks)plugins/static/test/fixtures/static-server/app/controller/foo.js(1 hunks)plugins/static/test/fixtures/static-server/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server/app/router.js(1 hunks)plugins/static/test/fixtures/static-server/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server/package.json(1 hunks)plugins/static/test/static.test.ts(1 hunks)plugins/static/tsconfig.json(1 hunks)plugins/static/tsdown.config.ts(1 hunks)plugins/static/vitest.config.ts(1 hunks)pnpm-workspace.yaml(3 hunks)tsconfig.json(1 hunks)
👮 Files not reviewed due to content moderation or server errors (6)
- plugins/static/test/fixtures/static-server-with-dir/package.json
- plugins/static/.gitignore
- plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.js
- plugins/static/test/fixtures/static-server-custom/app/assets/foo.js
- plugins/static/test/fixtures/static-server/app/public/foo.js
- plugins/static/test/fixtures/static-server-dist/config/plugin.js
🧰 Additional context used
📓 Path-based instructions (17)
**/test/fixtures/**
📄 CodeRabbit inference engine (AGENTS.md)
Put reusable test data under test/fixtures/
Files:
plugins/static/test/fixtures/static-server-dist/config/config.default.jsplugins/static/test/fixtures/static-server/app/router.jsplugins/static/test/fixtures/static-server-with-dir/config/plugin.jsplugins/static/test/fixtures/static-server/package.jsonplugins/static/test/fixtures/static-server-with-dir/config/config.default.jsplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/test/fixtures/static-server-dist/config/plugin.jsplugins/static/test/fixtures/static-server-dist/app/assets/foo.jsplugins/static/test/fixtures/static-server-custom/config/config.default.jsplugins/static/test/fixtures/static-server-with-dirs/package.jsonplugins/static/test/fixtures/static-server-custom/package.jsonplugins/static/test/fixtures/static-server-with-dirs/config/plugin.jsplugins/static/test/fixtures/static-server/app/controller/foo.jsplugins/static/test/fixtures/static-server-with-dirs/app/public/foo.jsplugins/static/test/fixtures/static-server-with-dir/package.jsonplugins/static/test/fixtures/static-server-custom/app/assets/foo.jsplugins/static/test/fixtures/static-server/app/public/foo.jsplugins/static/test/fixtures/static-server-with-dirs/config/config.default.jsplugins/static/test/fixtures/static-server-with-dir/app/public/foo.jsplugins/static/test/fixtures/static-server/config/config.default.js
packages/*/package.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use "workspace:*" for internal workspace dependencies in package.json
Files:
packages/egg/package.json
{packages,plugins,tools}/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/package.json: All packages must provide a typecheck script using "tsc --noEmit"
All packages must use oxlint for linting with the command "oxlint --type-aware" (no ESLint configs)
Files:
packages/egg/package.jsonplugins/static/test/fixtures/static-server/package.jsonplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/package.jsonplugins/static/test/fixtures/static-server-with-dirs/package.jsonplugins/static/test/fixtures/static-server-custom/package.jsonplugins/static/test/fixtures/static-server-with-dir/package.json
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable
Files:
plugins/static/vitest.config.tsplugins/static/src/app.tsplugins/static/src/config/config.prod.tsplugins/static/test/static.test.tsplugins/static/src/types.tsplugins/static/src/index.tspackages/egg/src/lib/types.plugin.tsplugins/static/src/config/config.default.tsplugins/static/src/app/middleware/static.tsplugins/static/tsdown.config.ts
plugins/**/vitest.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All new plugins must use Vitest and include vitest.config.ts
Files:
plugins/static/vitest.config.ts
{packages,plugins,tools}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/*.{ts,tsx}: Prefer interfaces over type aliases for object shapes in TypeScript
Use explicit return types for public APIs
Use readonly modifiers where appropriate
Avoid the any type; prefer unknown when the type is truly unknown
Files:
plugins/static/vitest.config.tsplugins/static/src/app.tsplugins/static/src/config/config.prod.tsplugins/static/test/static.test.tsplugins/static/src/types.tsplugins/static/src/index.tspackages/egg/src/lib/types.plugin.tsplugins/static/src/config/config.default.tsplugins/static/src/app/middleware/static.tsplugins/static/tsdown.config.ts
plugins/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
plugins/**/package.json: Plugin package.json must include peerDependencies { "egg": "workspace:" }
Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/.js
Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Files:
plugins/static/test/fixtures/static-server/package.jsonplugins/static/test/fixtures/static-server-dist/package.jsonplugins/static/package.jsonplugins/static/test/fixtures/static-server-with-dirs/package.jsonplugins/static/test/fixtures/static-server-custom/package.jsonplugins/static/test/fixtures/static-server-with-dir/package.json
{packages,plugins,tools,examples,site}/**/tsconfig.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools,examples,site}/**/tsconfig.json: All sub-project tsconfig.json files must extend the root tsconfig.json ("extends": "../../tsconfig.json")
Enable TypeScript strict mode in all packages (compilerOptions.strict: true)
Files:
plugins/static/tsconfig.json
**/test/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites
Files:
plugins/static/test/static.test.ts
{packages,plugins,tools}/**/test/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test files should follow the pattern test/**/*.test.ts
Files:
plugins/static/test/static.test.ts
{packages,plugins,tools}/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Files:
plugins/static/test/static.test.ts
packages/**/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use TypeScript for all source files in packages (no JavaScript source files)
Files:
packages/egg/src/lib/types.plugin.ts
plugins/**/tsdown.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All plugins must use the standard tsdown config: entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true
Files:
plugins/static/tsdown.config.ts
{packages,plugins,tools}/**/tsdown.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Packages should use tsdown for builds (presence of tsdown.config.ts)
Files:
plugins/static/tsdown.config.ts
{tsconfig.json,packages/*/tsconfig.json}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Enable strict TypeScript mode across all packages
Files:
tsconfig.json
tsconfig.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Root tsconfig.json must include all packages in the references array
Files:
tsconfig.json
pnpm-workspace.yaml
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"
Files:
pnpm-workspace.yaml
🧠 Learnings (29)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json must include peerDependencies { "egg": "workspace:*" }
Applied to files:
packages/egg/package.jsonplugins/static/package.jsonpnpm-workspace.yaml
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/package.json : Use "workspace:*" for internal workspace dependencies in package.json
Applied to files:
packages/egg/package.jsonplugins/static/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to packages/{egg,core}/tsconfig.json : packages/egg and packages/core must have strict mode enabled in their tsconfig.json
Applied to files:
packages/egg/package.jsonpackages/egg/src/lib/types.plugin.tsplugins/static/package.jsonplugins/static/src/app/middleware/static.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Use pnpm catalog mode: external deps referenced as "catalog:" and internal workspace deps as "workspace:*"
Applied to files:
packages/egg/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to pnpm-workspace.yaml : Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"
Applied to files:
packages/egg/package.jsonpnpm-workspace.yaml
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to plugins/**/vitest.config.ts : All new plugins must use Vitest and include vitest.config.ts
Applied to files:
plugins/static/vitest.config.tsplugins/static/tsconfig.jsonplugins/static/tsdown.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.tsCLAUDE.md
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.test.ts : In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to {packages,plugins,tools,examples,site}/**/tsconfig.json : All sub-project tsconfig.json files must extend the root tsconfig.json ("extends": "../../tsconfig.json")
Applied to files:
plugins/static/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/tsdown.config.ts : All plugins must use the standard tsdown config: entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true
Applied to files:
plugins/static/tsconfig.jsonplugins/static/tsdown.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/*.js
Applied to files:
plugins/static/tsconfig.jsonplugins/static/package.jsonplugins/static/tsdown.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to {packages,plugins,tools,examples,site}/**/tsconfig.json : Enable TypeScript strict mode in all packages (compilerOptions.strict: true)
Applied to files:
plugins/static/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsconfig.json : All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"
Applied to files:
plugins/static/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/tsdown.config.ts : Packages should use tsdown for builds (presence of tsdown.config.ts)
Applied to files:
plugins/static/tsconfig.jsonplugins/static/tsdown.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.tsCLAUDE.md
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/cookies/test/**/*.test.ts : cookies package uses Mocha; test files follow test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use Node.js built-in assert module for test assertions
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/*.ts : Re-export types thoughtfully to keep the public API stable
Applied to files:
plugins/static/src/index.tspackages/egg/src/lib/types.plugin.tsplugins/static/tsdown.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.{ts,tsx} : Use explicit return types for public APIs
Applied to files:
packages/egg/src/lib/types.plugin.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
Applied to files:
plugins/static/package.jsonCLAUDE.md
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Applied to files:
plugins/static/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsdown.config.ts : Each package must provide a tsdown.config.ts for unbundled ESM builds
Applied to files:
plugins/static/tsdown.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to tsconfig.json : Root tsconfig.json must include all packages in the references array
Applied to files:
tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/egg/src/app/extend/** : Place framework extensions (context, helper, request, response) under packages/egg/src/app/extend/
Applied to files:
CLAUDE.md
🧬 Code graph analysis (12)
plugins/static/src/app.ts (1)
packages/core/src/egg.ts (1)
EggCore(95-543)
plugins/static/test/fixtures/static-server-with-dir/config/config.default.js (1)
plugins/static/src/config/config.default.ts (1)
appInfo(5-19)
plugins/static/src/config/config.prod.ts (1)
plugins/static/src/types.ts (1)
StaticConfig(46-57)
plugins/static/test/static.test.ts (2)
scripts/version.js (2)
__filename(11-11)__dirname(12-12)packages/egg/test/utils.ts (1)
MockApplication(24-24)
plugins/static/src/types.ts (1)
packages/egg/src/lib/types.ts (1)
EggAppConfig(113-287)
plugins/static/src/config/config.default.ts (1)
plugins/static/src/types.ts (1)
StaticConfig(46-57)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (2)
plugins/static/test/fixtures/static-server-with-dir/config/config.default.js (1)
path(1-1)plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js (1)
path(1-1)
plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js (1)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
exports(4-4)
plugins/static/src/app/middleware/static.ts (2)
plugins/static/src/types.ts (2)
StaticConfig(46-57)StaticDirOptions(3-39)packages/koa-static-cache/src/index.ts (1)
staticCache(139-321)
plugins/static/tsdown.config.ts (1)
packages/egg/src/lib/types.ts (1)
defineConfig(109-111)
plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js (1)
plugins/static/src/config/config.default.ts (1)
appInfo(5-19)
plugins/static/test/fixtures/static-server/config/config.default.js (1)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
exports(4-4)
🪛 markdownlint-cli2 (0.18.1)
plugins/static/README.md
55-55: Link text should be descriptive
(MD059, descriptive-link-text)
plugins/static/CHANGELOG.md
20-20: Bare URL used
(MD034, no-bare-urls)
22-22: Bare URL used
(MD034, no-bare-urls)
30-30: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
30-30: Hard tabs
Column: 1
(MD010, no-hard-tabs)
31-31: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
31-31: Hard tabs
Column: 1
(MD010, no-hard-tabs)
32-32: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
32-32: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
36-36: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
36-36: Hard tabs
Column: 1
(MD010, no-hard-tabs)
37-37: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
37-37: Hard tabs
Column: 1
(MD010, no-hard-tabs)
40-40: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
41-41: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
41-41: Hard tabs
Column: 1
(MD010, no-hard-tabs)
44-44: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
44-44: Hard tabs
Column: 1
(MD010, no-hard-tabs)
45-45: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
45-45: Hard tabs
Column: 1
(MD010, no-hard-tabs)
70-70: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
73-73: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
74-74: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
76-76: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
79-79: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
80-80: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
82-82: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
85-85: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
86-86: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
88-88: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
89-89: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
91-91: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
94-94: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
95-95: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
96-96: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
98-98: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
101-101: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
103-103: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
106-106: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
108-108: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
111-111: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
113-113: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
116-116: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
117-117: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
119-119: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
122-122: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
123-123: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
125-125: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
128-128: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
130-130: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
133-133: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
135-135: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
138-138: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
🪛 GitHub Check: Test (windows-latest, 22, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (windows-latest, 24, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (macos-latest, 22, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (ubuntu-latest, 22, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (macos-latest, 24, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (ubuntu-latest, 24, plugins)
plugins/static/test/static.test.ts
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test egg-bin (windows-latest, 22)
- GitHub Check: Test egg-bin (windows-latest, 24)
🔇 Additional comments (24)
plugins/static/tsconfig.json (1)
1-6: Config extends root as requiredExtending the root tsconfig and scoping
baseUrllocally matches the repo guidelines for plugin subprojects.plugins/static/test/fixtures/static-server-custom/package.json (1)
1-3: Fixture package metadata is fineThe minimal package manifest is sufficient for the fixture setup.
plugins/static/vitest.config.ts (1)
1-8: Vitest config aligns with discovery rulesIncluding the plugin test glob and extended timeout satisfies the testing guidelines.
pnpm-workspace.yaml (1)
44-170: Catalog additions look consistentAdding
@types/koa-range,koa-range, andylruto the catalog keeps dependency versions centralized as required.plugins/static/tsdown.config.ts (1)
1-10: Standard tsdown config in placeThe entry, unbundle, dts, and devExports settings match the mandated plugin build configuration.
plugins/static/test/fixtures/static-server/app/controller/foo.js (1)
1-7: Controller fixture behaves correctlyThe controller sets body, type, and status explicitly—ideal for the route fixture.
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
1-12: Custom static dir fixture is soundDeriving the static directory from
info.baseDirand exposing the custom prefix follows the pattern used elsewhere.plugins/static/test/fixtures/static-server-dist/config/config.default.js (1)
1-9: Dist static config mirrors expectationsReturning the static config with buffer enabled matches the dist-serving test scenario.
plugins/static/test/fixtures/static-server-with-dir/config/plugin.js (1)
1-1: LGTM – fixture toggles static plugin inlineEnabling the plugin via boolean keeps the fixture lean and aligns with Egg's plugin toggles.
CLAUDE.md (1)
42-61: Appreciate the CLAUDE.md updatesCalling out the new static plugin and its koa-static-cache dependency helps future AI assistance stay accurate.
plugins/static/test/fixtures/static-server-dist/package.json (1)
1-3: LGTM – fixture manifest stays minimalKeeping only the name keeps the fixture light and avoids needless dependencies.
plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js (1)
1-1: LGTM – fixture enables static pluginThe boolean toggle mirrors Egg’s built-in plugin enablement.
plugins/static/test/fixtures/static-server-with-dir/app/public/foo.js (1)
1-1: LGTM – fixture asset in placeThe stubbed console log is perfect for exercising the static directory lookup.
plugins/static/src/types.ts (1)
19-22: Close the unbalanced quote in the default descriptionThe trailing backtick/quote is still missing from the earlier review; fixing it keeps the JSDoc tidy.
- * Default to `true + * Default to `true`plugins/static/test/fixtures/static-server/app/router.js (1)
1-5: LGTM – fixture route wiring is clearMapping
/foo/barstraight tofoo.barkeeps the controller hookup explicit for the scenario under test.plugins/static/LICENSE (1)
1-21: MIT license header confirmedContent matches the canonical MIT template adopted across the repo.
packages/egg/package.json (1)
129-134: Internal deps switched to workspace scopeUsing
workspace:*keeps these packages aligned with internal builds and follows the workspace dependency convention.Based on learnings
plugins/static/test/fixtures/static-server/package.json (1)
1-3: Fixture metadata looks goodMinimal package name is sufficient for the fixture and matches existing patterns.
plugins/static/test/fixtures/static-server-with-dirs/package.json (1)
1-3: Fixture package json alignedNaming mirrors the other fixtures and keeps the setup light.
plugins/static/test/fixtures/static-server-dist/app/assets/foo.js (1)
1-1: Asset fixture acknowledgedThe simple script is enough to exercise static asset serving in tests.
tsconfig.json (1)
57-60: New project reference wired upAdding
plugins/staticensures the root build graph sees the new plugin package.plugins/static/test/fixtures/static-server/config/config.default.js (1)
1-3: Fixture config initializedProviding
keyskeeps the test app booting without warnings.plugins/static/src/index.ts (1)
1-1: Type augmentation import in placeSide-effect import guarantees the module augmentation is registered for consumers.
plugins/static/src/app/middleware/static.ts (1)
11-66: Tighten the app type instead of casting toany.Line 65 still drops to
as anyjust to reachcoreLogger. Please extend the signature to includecoreLogger(importing the proper logger type) and callapp.coreLogger.info(...)directly—noany. This keeps the middleware type-safe and aligns with our TypeScript guidelines. You’ll also need to add the relevant logger type dependency (e.g.,egg-logger) to devDependencies.-import type { EggCore, Context, Next } from '@eggjs/core'; +import type { EggCore, Context, Next } from '@eggjs/core'; +import type { EggLogger } from 'egg-logger'; @@ -export default (options: StaticConfig, app: EggCore) => { +export default (options: StaticConfig, app: EggCore & { coreLogger: EggLogger }) => { @@ - (app as any).coreLogger.info('[@eggjs/static] starting static serve %s -> %s', newOptions.prefix, newOptions.dir); + app.coreLogger.info('[@eggjs/static] starting static serve %s -> %s', newOptions.prefix, newOptions.dir);
| /// <reference types="@eggjs/static" /> | ||
| /// <reference types="@eggjs/onerror" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Triple-slash directives must come before imports
In TypeScript, triple-slash directives only take effect when they appear before any top-level statements (including import declarations). Because these directives come after several imports, they’re treated as regular comments and the intended type augmentations from @eggjs/static and @eggjs/onerror never load. Please move them to the top of the file (ahead of the imports) so the plugin config typings remain available.
+/// <reference types="@eggjs/static" />
+/// <reference types="@eggjs/onerror" />
// import plugins types
import '@eggjs/watcher';
import '@eggjs/jsonp';
@@
-import '@eggjs/view';
-
-/// <reference types="@eggjs/static" />
-/// <reference types="@eggjs/onerror" />
+import '@eggjs/view';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /// <reference types="@eggjs/static" /> | |
| /// <reference types="@eggjs/onerror" /> | |
| /// <reference types="@eggjs/static" /> | |
| /// <reference types="@eggjs/onerror" /> | |
| // import plugins types | |
| import '@eggjs/watcher'; | |
| import '@eggjs/jsonp'; | |
| import '@eggjs/view'; |
🤖 Prompt for AI Agents
In packages/egg/src/lib/types.plugin.ts around lines 13 to 14, the triple-slash
reference directives for @eggjs/static and @eggjs/onerror are placed after
top-level imports so they are treated as comments and their type augmentations
don’t load; move those two /// <reference types="..."> lines to the very top of
the file before any import or other top-level statements so TypeScript will
apply the directive-based typings for the plugin config.
| "devDependencies": { | ||
| "@eggjs/tsconfig": "workspace:*", | ||
| "@types/koa-compose": "catalog:", | ||
| "@types/koa-range": "catalog:", | ||
| "@eggjs/mock": "workspace:*", | ||
| "oxlint": "catalog:", | ||
| "tsdown": "catalog:", | ||
| "typescript": "catalog:", | ||
| "vitest": "catalog:" | ||
| }, | ||
| "scripts": { | ||
| "build": "tsdown", | ||
| "typecheck": "tsc --noEmit", | ||
| "lint": "oxlint --type-aware", | ||
| "lint:fix": "npm run lint -- --fix", | ||
| "test": "npm run lint:fix && vitest run", | ||
| "ci": "vitest run --coverage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Add the required clean script (and dependency).
Per the plugin package.json guidelines, every plugin must ship a clean script using rimraf dist. Please add both the script and the matching rimraf devDependency so the workflow is complete.
"devDependencies": {
"@eggjs/tsconfig": "workspace:*",
"@types/koa-compose": "catalog:",
"@types/koa-range": "catalog:",
"@eggjs/mock": "workspace:*",
"oxlint": "catalog:",
+ "rimraf": "catalog:",
"tsdown": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
},
"scripts": {
+ "clean": "rimraf dist",
"build": "tsdown",
"typecheck": "tsc --noEmit",
"lint": "oxlint --type-aware",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "devDependencies": { | |
| "@eggjs/tsconfig": "workspace:*", | |
| "@types/koa-compose": "catalog:", | |
| "@types/koa-range": "catalog:", | |
| "@eggjs/mock": "workspace:*", | |
| "oxlint": "catalog:", | |
| "tsdown": "catalog:", | |
| "typescript": "catalog:", | |
| "vitest": "catalog:" | |
| }, | |
| "scripts": { | |
| "build": "tsdown", | |
| "typecheck": "tsc --noEmit", | |
| "lint": "oxlint --type-aware", | |
| "lint:fix": "npm run lint -- --fix", | |
| "test": "npm run lint:fix && vitest run", | |
| "ci": "vitest run --coverage", | |
| "devDependencies": { | |
| "@eggjs/tsconfig": "workspace:*", | |
| "@types/koa-compose": "catalog:", | |
| "@types/koa-range": "catalog:", | |
| "@eggjs/mock": "workspace:*", | |
| "oxlint": "catalog:", | |
| "rimraf": "catalog:", | |
| "tsdown": "catalog:", | |
| "typescript": "catalog:", | |
| "vitest": "catalog:" | |
| }, | |
| "scripts": { | |
| "clean": "rimraf dist", | |
| "build": "tsdown", | |
| "typecheck": "tsc --noEmit", | |
| "lint": "oxlint --type-aware", | |
| "lint:fix": "npm run lint -- --fix", | |
| "test": "npm run lint:fix && vitest run", | |
| "ci": "vitest run --coverage", |
🤖 Prompt for AI Agents
In plugins/static/package.json around lines 50 to 66, the package is missing the
required clean script and its dependency; add "rimraf" as a devDependency
(matching the repository's versioning style, e.g., "catalog:" or the workspace
pattern used elsewhere) and add a "clean" script in "scripts" with the command
"rimraf dist" so the package conforms to the plugin package.json guidelines.
| private readonly app; | ||
| constructor(app: EggCore) { | ||
| this.app = app; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Annotate the app field with its type
Declaring the field without a type widens it to any, which undermines the type safety we get from typing the constructor parameter. Please annotate the property so the AppBoot implementation stays type-safe.
- private readonly app;
+ private readonly app: EggCore;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private readonly app; | |
| constructor(app: EggCore) { | |
| this.app = app; | |
| } | |
| private readonly app: EggCore; | |
| constructor(app: EggCore) { | |
| this.app = app; | |
| } |
🤖 Prompt for AI Agents
In plugins/static/src/app.ts around lines 4 to 7, the private readonly app field
is declared without a type (implicitly any); annotate it as private readonly
app: EggCore to match the constructor parameter and preserve type-safety, and
ensure EggCore is imported/available in this file if not already.
| const index = app.config.coreMiddleware.indexOf('bodyParser'); | ||
| if (index === -1) { | ||
| app.config.coreMiddleware.push('static'); | ||
| } else { | ||
| app.config.coreMiddleware.splice(index, 0, 'static'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent duplicate static middleware registrations
If a user already lists static in coreMiddleware, this logic will insert a second copy, causing the middleware to run twice on every request. Add a guard before the insertion to keep the list deduplicated.
- const index = app.config.coreMiddleware.indexOf('bodyParser');
- if (index === -1) {
- app.config.coreMiddleware.push('static');
- } else {
- app.config.coreMiddleware.splice(index, 0, 'static');
- }
+ const { coreMiddleware } = app.config;
+ if (coreMiddleware.includes('static')) return;
+ const index = coreMiddleware.indexOf('bodyParser');
+ if (index === -1) {
+ coreMiddleware.push('static');
+ } else {
+ coreMiddleware.splice(index, 0, 'static');
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const index = app.config.coreMiddleware.indexOf('bodyParser'); | |
| if (index === -1) { | |
| app.config.coreMiddleware.push('static'); | |
| } else { | |
| app.config.coreMiddleware.splice(index, 0, 'static'); | |
| } | |
| const { coreMiddleware } = app.config; | |
| if (coreMiddleware.includes('static')) return; | |
| const index = coreMiddleware.indexOf('bodyParser'); | |
| if (index === -1) { | |
| coreMiddleware.push('static'); | |
| } else { | |
| coreMiddleware.splice(index, 0, 'static'); | |
| } |
🤖 Prompt for AI Agents
In plugins/static/src/app.ts around lines 11 to 16, the code may insert a
duplicate 'static' entry into app.config.coreMiddleware; before pushing or
splicing, check whether app.config.coreMiddleware already contains 'static'
(e.g., use includes() or indexOf !== -1) and only perform the push/splice when
it is not present so the middleware list remains deduplicated.
| prefix: '/public', | ||
| dir: [path.join(appInfo.baseDir, '/app/public'), path.join(appInfo.baseDir, '/dist/static')], | ||
| buffer: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix static dir join to avoid escaping baseDir
Because the second argument to path.join starts with /, Node resolves it to an absolute path (e.g., /app/public), so the fixture stops reading from the intended appInfo.baseDir and may even try to create directories at the filesystem root. Please drop the leading slash on both entries so they stay under the fixture’s base directory.
Apply this diff:
- dir: [path.join(appInfo.baseDir, '/app/public'), path.join(appInfo.baseDir, '/dist/static')],
+ dir: [path.join(appInfo.baseDir, 'app/public'), path.join(appInfo.baseDir, 'dist/static')],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| prefix: '/public', | |
| dir: [path.join(appInfo.baseDir, '/app/public'), path.join(appInfo.baseDir, '/dist/static')], | |
| buffer: true, | |
| prefix: '/public', | |
| dir: [path.join(appInfo.baseDir, 'app/public'), path.join(appInfo.baseDir, 'dist/static')], | |
| buffer: true, |
🤖 Prompt for AI Agents
In plugins/static/test/fixtures/static-server-with-dir/config/config.default.js
around lines 7 to 9, the path.join calls use second arguments that start with a
leading slash so Node treats them as absolute paths; remove the leading '/' from
both '/app/public' and '/dist/static' so path.join(appInfo.baseDir,
'app/public') and path.join(appInfo.baseDir, 'dist/static') resolve under
appInfo.baseDir and the fixture reads/writes inside the fixture directory
instead of the filesystem root.
| path.join(appInfo.baseDir, '/app/public'), | ||
| { | ||
| prefix: '/static', | ||
| dir: path.join(appInfo.baseDir, '/dist/static'), | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix directory resolution
Line 9 and Line 12 pass absolute paths ('/app/public', '/dist/static') into path.join, which discards appInfo.baseDir and resolves to /app/public and /dist/static on the host filesystem. The fixture will never serve the intended assets. Please join relative segments so the baseDir is preserved.
- path.join(appInfo.baseDir, '/app/public'),
+ path.join(appInfo.baseDir, 'app/public'),
@@
- dir: path.join(appInfo.baseDir, '/dist/static'),
+ dir: path.join(appInfo.baseDir, 'dist/static'),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| path.join(appInfo.baseDir, '/app/public'), | |
| { | |
| prefix: '/static', | |
| dir: path.join(appInfo.baseDir, '/dist/static'), | |
| }, | |
| path.join(appInfo.baseDir, 'app/public'), | |
| { | |
| prefix: '/static', | |
| dir: path.join(appInfo.baseDir, 'dist/static'), | |
| }, |
🤖 Prompt for AI Agents
In plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js
around lines 9 to 13, the code uses path.join(appInfo.baseDir, '/app/public')
and path.join(appInfo.baseDir, '/dist/static') which discard appInfo.baseDir due
to the leading slash; change these to join relative segments so the baseDir is
preserved — e.g. path.join(appInfo.baseDir, 'app', 'public') and
path.join(appInfo.baseDir, 'dist', 'static') (or at minimum remove the leading
slashes: 'app/public' and 'dist/static') so the fixture serves assets from the
intended project directories.
| let app: MockApplication; | ||
| beforeEach(async () => { | ||
| app = mock.app({ | ||
| baseDir: 'static-server', | ||
| }); | ||
| await app.ready(); | ||
| }); | ||
|
|
||
| afterEach(() => app.close()); | ||
|
|
||
| it('should get exists js file', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard cleanup when setup fails
When mock.app fails (as seen in CI), app stays undefined and afterEach throws “Cannot read properties of undefined (reading 'close')”, masking the real failure. Make the cleanup async, check app before closing, and reset it afterwards; please apply the same pattern to the other suites in this file.
Apply this diff:
- let app: MockApplication;
+ let app: MockApplication | undefined;
@@
- afterEach(() => app.close());
+ afterEach(async () => {
+ if (app) {
+ await app.close();
+ app = undefined;
+ }
+ });Based on pipeline failure logs.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let app: MockApplication; | |
| beforeEach(async () => { | |
| app = mock.app({ | |
| baseDir: 'static-server', | |
| }); | |
| await app.ready(); | |
| }); | |
| afterEach(() => app.close()); | |
| it('should get exists js file', () => { | |
| let app: MockApplication | undefined; | |
| beforeEach(async () => { | |
| app = mock.app({ | |
| baseDir: 'static-server', | |
| }); | |
| await app.ready(); | |
| }); | |
| afterEach(async () => { | |
| if (app) { | |
| await app.close(); | |
| app = undefined; | |
| } | |
| }); | |
| it('should get exists js file', () => { |
🧰 Tools
🪛 GitHub Check: Test (windows-latest, 22, plugins)
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (windows-latest, 24, plugins)
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (macos-latest, 22, plugins)
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (ubuntu-latest, 22, plugins)
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (macos-latest, 24, plugins)
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🪛 GitHub Check: Test (ubuntu-latest, 24, plugins)
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
[failure] 24-24: test/static.test.ts > test/static.test.ts > serve public > should get exists js file
TypeError: Cannot read properties of undefined (reading 'close')
❯ test/static.test.ts:24:25
🤖 Prompt for AI Agents
In plugins/static/test/static.test.ts around lines 16 to 26, the afterEach
cleanup assumes app is defined which causes “Cannot read properties of undefined
(reading 'close')” when mock.app setup fails; make the teardown async, guard
that app is defined before calling await app.close(), and set app =
undefined/null after closing so subsequent tests/suites don't reuse a failed
instance; apply the same async guarded teardown pattern to the other test suites
in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
plugins/schedule/src/config/config.default.ts (1)
3-13: Restore static type checking for plugin configReplacing
defineConfigwithas PartialEggConfigstrips the compiler of any structural checks—future typos or wrong value shapes will now silently pass. Keep the runtime change (plain object export), but retain typing by binding the object toPartialEggConfig(or usingsatisfies). For example:-import { type PartialEggConfig } from 'egg'; - -export default { +import { type PartialEggConfig } from 'egg'; + +const config: PartialEggConfig = { customLogger: { scheduleLogger: { consoleLevel: 'NONE', file: 'egg-schedule.log', }, }, schedule: { directory: [], }, -} as PartialEggConfig; +}; + +export default config;This preserves the new style while keeping compile-time safety.
packages/egg/test/lib/core/loader/load_plugin.test.ts (1)
59-61: Make the assertion path-separator agnosticDropping the Windows guard lets us keep verifying the plugin path everywhere by splitting on
path.sepand checking for theonerrorsegment, instead of relying on a POSIX-only regex.- if (process.platform !== 'win32') { - assert.match(appLoader.plugins.onerror.path!, /\/onerror\//); - } + const onerrorPathSegments = appLoader.plugins.onerror.path!.split(path.sep); + assert(onerrorPathSegments.includes('onerror'));
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
packages/egg/test/__snapshots__/index.test.ts.snapis excluded by!**/*.snappackages/egg/test/lib/__snapshots__/define_config.test.ts.snapis excluded by!**/*.snappnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (21)
package.json(1 hunks)packages/egg/src/config/config.default.ts(1 hunks)packages/egg/src/lib/types.ts(1 hunks)packages/egg/test/lib/core/loader/load_plugin.test.ts(1 hunks)packages/egg/test/lib/define_config.test.ts(3 hunks)packages/extend2/package.json(0 hunks)plugins/development/package.json(0 hunks)plugins/schedule/src/config/config.default.ts(2 hunks)plugins/static/package.json(1 hunks)plugins/static/src/app.ts(1 hunks)plugins/static/src/app/middleware/static.ts(1 hunks)plugins/static/src/config/config.default.ts(1 hunks)plugins/static/src/config/config.prod.ts(1 hunks)plugins/static/src/index.ts(1 hunks)plugins/static/src/types.ts(1 hunks)plugins/static/test/fixtures/static-server-custom/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/config.default.js(1 hunks)plugins/static/test/static.test.ts(1 hunks)plugins/static/vitest.config.ts(1 hunks)plugins/watcher/package.json(0 hunks)tools/egg-bin/package.json(0 hunks)
💤 Files with no reviewable changes (4)
- plugins/development/package.json
- packages/extend2/package.json
- tools/egg-bin/package.json
- plugins/watcher/package.json
🚧 Files skipped from review as they are similar to previous changes (6)
- plugins/static/src/config/config.default.ts
- plugins/static/test/fixtures/static-server-custom/config/config.default.js
- plugins/static/src/app.ts
- plugins/static/test/fixtures/static-server-dist/config/config.default.js
- plugins/static/src/types.ts
- plugins/static/package.json
🧰 Additional context used
📓 Path-based instructions (9)
packages/**/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use TypeScript for all source files in packages (no JavaScript source files)
Files:
packages/egg/src/lib/types.tspackages/egg/src/config/config.default.ts
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable
Files:
packages/egg/src/lib/types.tspackages/egg/src/config/config.default.tspackages/egg/test/lib/define_config.test.tsplugins/static/src/app/middleware/static.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/schedule/src/config/config.default.tsplugins/static/test/static.test.tsplugins/static/vitest.config.tsplugins/static/src/index.tsplugins/static/src/config/config.prod.ts
{packages,plugins,tools}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/*.{ts,tsx}: Prefer interfaces over type aliases for object shapes in TypeScript
Use explicit return types for public APIs
Use readonly modifiers where appropriate
Avoid the any type; prefer unknown when the type is truly unknown
Files:
packages/egg/src/lib/types.tspackages/egg/src/config/config.default.tspackages/egg/test/lib/define_config.test.tsplugins/static/src/app/middleware/static.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/schedule/src/config/config.default.tsplugins/static/test/static.test.tsplugins/static/vitest.config.tsplugins/static/src/index.tsplugins/static/src/config/config.prod.ts
packages/egg/src/config/**
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Store default configurations and plugin configs under packages/egg/src/config/
Files:
packages/egg/src/config/config.default.ts
packages/**/test/**/*.test.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/**/test/**/*.test.ts: Name test files as test/**/*.test.ts and run them with Vitest
Use import { describe, it } from 'vitest' in tests
Use Node.js built-in assert module for test assertions
Files:
packages/egg/test/lib/define_config.test.tspackages/egg/test/lib/core/loader/load_plugin.test.ts
**/test/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites
Files:
packages/egg/test/lib/define_config.test.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.ts
{packages,plugins,tools}/**/test/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test files should follow the pattern test/**/*.test.ts
Files:
packages/egg/test/lib/define_config.test.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.ts
{packages,plugins,tools}/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Files:
packages/egg/test/lib/define_config.test.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.ts
plugins/**/vitest.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All new plugins must use Vitest and include vitest.config.ts
Files:
plugins/static/vitest.config.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts
Applied to files:
packages/egg/test/lib/define_config.test.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts
Applied to files:
packages/egg/test/lib/define_config.test.tsplugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests
Applied to files:
packages/egg/test/lib/define_config.test.tsplugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.test.ts : In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Applied to files:
packages/egg/test/lib/define_config.test.tsplugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to packages/{egg,core}/tsconfig.json : packages/egg and packages/core must have strict mode enabled in their tsconfig.json
Applied to files:
plugins/static/src/app/middleware/static.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use Node.js built-in assert module for test assertions
Applied to files:
packages/egg/test/lib/core/loader/load_plugin.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
Applied to files:
packages/egg/test/lib/core/loader/load_plugin.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to plugins/**/vitest.config.ts : All new plugins must use Vitest and include vitest.config.ts
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.tsplugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/cookies/test/**/*.test.ts : cookies package uses Mocha; test files follow test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/test/**/*.test.ts : Test files should follow the pattern test/**/*.test.ts
Applied to files:
plugins/static/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Applied to files:
package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/package.json : All packages must provide a typecheck script using "tsc --noEmit"
Applied to files:
package.json
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/*.ts : Re-export types thoughtfully to keep the public API stable
Applied to files:
plugins/static/src/index.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.{ts,tsx} : Use explicit return types for public APIs
Applied to files:
plugins/static/src/index.ts
🧬 Code graph analysis (7)
packages/egg/src/lib/types.ts (4)
packages/egg/src/lib/egg.ts (1)
config(564-566)packages/core/src/loader/egg_loader.ts (1)
config(1003-1007)packages/core/src/egg.ts (1)
config(307-309)packages/egg/src/lib/core/base_hook_class.ts (1)
config(19-21)
packages/egg/src/config/config.default.ts (1)
packages/egg/src/lib/types.ts (2)
defineConfigFactory(119-121)PartialEggConfig(86-86)
packages/egg/test/lib/define_config.test.ts (1)
packages/egg/src/lib/types.ts (1)
defineConfigFactory(119-121)
plugins/static/src/app/middleware/static.ts (2)
plugins/static/src/types.ts (2)
StaticConfig(46-57)StaticDirOptions(3-39)packages/koa-static-cache/src/index.ts (1)
staticCache(139-321)
plugins/schedule/src/config/config.default.ts (1)
packages/egg/src/lib/types.ts (1)
PartialEggConfig(86-86)
plugins/static/test/static.test.ts (1)
packages/supertest/src/test.ts (1)
expect(77-132)
plugins/static/src/config/config.prod.ts (1)
packages/egg/src/lib/types.ts (1)
PartialEggConfig(86-86)
🪛 GitHub Actions: CI
package.json
[error] 1-1: pnpm install --frozen-lockfile failed: lockfile is not up to date with package.json (specifiers in the lockfile don't match). 1 dependencies were added: rimraf@catalog.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Socket Security: Pull Request Alerts
🔇 Additional comments (2)
plugins/static/src/app/middleware/static.ts (1)
55-57: Restore range support for root prefixes. Line 55 skips falsy prefixes, so a configured empty-string prefix (mount at/) never reachesprefixes, and Range headers stop working for root static assets—a regression from prior behavior. Normalize the prefix and always record it before composing the middleware.- if (newOptions.prefix) { - prefixes.push(newOptions.prefix); - } + const normalizedPrefix = (newOptions.prefix ?? '').replace(/\/*$/, '/'); + prefixes.push(normalizedPrefix);plugins/static/test/static.test.ts (1)
13-22: Guard app teardown when setup failsLine 21 still blindly calls
app.close(). Whenmock.appthrows, the hook runs withappundefined and reproduces the CI failure (TypeError: Cannot read properties of undefined (reading 'close')). Please makeappoptional, guard before closing, reset it, and mirror the same guarded teardown across the other suites in this file so setup errors don’t mask root causes.- let app: MockApplication; + let app: MockApplication | undefined; @@ - afterAll(() => app.close()); + afterAll(async () => { + if (app) { + await app.close(); + app = undefined; + } + });Based on pipeline failure logs.
- Migrate @eggjs/static repository to plugins/static - Update version to 4.0.0-beta.11 - Replace ESLint with oxlint for linting - Add TypeScript type checking with tsc --noEmit - Configure tsdown for unbundled ESM build - Add peerDependencies for egg using workspace:* - Update tests to use vitest - Add koa-range and ylru to pnpm catalog 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
140cae9 to
5dfd58e
Compare
There was a problem hiding this 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)
plugins/static/CHANGELOG.md (1)
29-46: Replace the tab-indented bullet list with space-indented MarkdownThe sub-bullets inside the “Summary by CodeRabbit” block are prefixed with hard tabs, which trips markdownlint (MD010/MD007) and renders inconsistently on GitHub. Please swap the tabs for two-space indentation (or remove the autogenerated block if it’s not needed) so the list formats correctly and the lint job stays green.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
packages/egg/test/__snapshots__/index.test.ts.snapis excluded by!**/*.snappackages/egg/test/lib/__snapshots__/define_config.test.ts.snapis excluded by!**/*.snappnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (50)
CLAUDE.md(2 hunks)package.json(1 hunks)packages/egg/package.json(1 hunks)packages/egg/src/config/config.default.ts(1 hunks)packages/egg/src/lib/types.plugin.ts(1 hunks)packages/egg/src/lib/types.ts(1 hunks)packages/egg/test/lib/core/loader/load_plugin.test.ts(1 hunks)packages/egg/test/lib/define_config.test.ts(3 hunks)packages/extend2/package.json(0 hunks)plugins/development/package.json(0 hunks)plugins/schedule/src/config/config.default.ts(2 hunks)plugins/static/.gitignore(1 hunks)plugins/static/CHANGELOG.md(1 hunks)plugins/static/LICENSE(1 hunks)plugins/static/README.md(1 hunks)plugins/static/package.json(1 hunks)plugins/static/src/app.ts(1 hunks)plugins/static/src/app/middleware/static.ts(1 hunks)plugins/static/src/config/config.default.ts(1 hunks)plugins/static/src/config/config.prod.ts(1 hunks)plugins/static/src/index.ts(1 hunks)plugins/static/src/types.ts(1 hunks)plugins/static/test/fixtures/static-server-custom/app/assets/foo.js(1 hunks)plugins/static/test/fixtures/static-server-custom/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-custom/package.json(1 hunks)plugins/static/test/fixtures/static-server-dist/app/assets/foo.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-dist/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-dist/package.json(1 hunks)plugins/static/test/fixtures/static-server-with-dir/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-with-dir/package.json(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js(1 hunks)plugins/static/test/fixtures/static-server-with-dirs/package.json(1 hunks)plugins/static/test/fixtures/static-server/app/controller/foo.js(1 hunks)plugins/static/test/fixtures/static-server/app/public/foo.js(1 hunks)plugins/static/test/fixtures/static-server/app/router.js(1 hunks)plugins/static/test/fixtures/static-server/config/config.default.js(1 hunks)plugins/static/test/fixtures/static-server/package.json(1 hunks)plugins/static/test/static.test.ts(1 hunks)plugins/static/tsconfig.json(1 hunks)plugins/static/tsdown.config.ts(1 hunks)plugins/static/vitest.config.ts(1 hunks)plugins/watcher/package.json(0 hunks)pnpm-workspace.yaml(3 hunks)tools/egg-bin/package.json(0 hunks)tsconfig.json(1 hunks)
💤 Files with no reviewable changes (4)
- plugins/development/package.json
- plugins/watcher/package.json
- tools/egg-bin/package.json
- packages/extend2/package.json
✅ Files skipped from review due to trivial changes (7)
- CLAUDE.md
- plugins/static/test/fixtures/static-server/app/public/foo.js
- plugins/static/test/fixtures/static-server/package.json
- plugins/static/tsconfig.json
- plugins/static/LICENSE
- plugins/static/test/fixtures/static-server-dist/package.json
- plugins/static/test/fixtures/static-server-dist/app/assets/foo.js
🚧 Files skipped from review as they are similar to previous changes (23)
- plugins/static/test/fixtures/static-server-dist/config/plugin.js
- plugins/static/test/fixtures/static-server-with-dirs/package.json
- plugins/static/.gitignore
- plugins/static/test/fixtures/static-server/app/controller/foo.js
- plugins/static/tsdown.config.ts
- plugins/static/test/fixtures/static-server-with-dirs/config/plugin.js
- plugins/static/test/fixtures/static-server-with-dirs/app/public/foo.js
- packages/egg/src/config/config.default.ts
- plugins/static/test/fixtures/static-server-with-dir/config/plugin.js
- pnpm-workspace.yaml
- plugins/static/test/fixtures/static-server-custom/config/config.default.js
- packages/egg/package.json
- tsconfig.json
- plugins/static/package.json
- plugins/schedule/src/config/config.default.ts
- plugins/static/src/config/config.prod.ts
- plugins/static/test/fixtures/static-server-with-dir/config/config.default.js
- plugins/static/test/fixtures/static-server/app/router.js
- plugins/static/test/fixtures/static-server-custom/package.json
- plugins/static/test/fixtures/static-server-with-dir/app/public/foo.js
- plugins/static/src/types.ts
- plugins/static/src/app.ts
- plugins/static/test/fixtures/static-server-dist/config/config.default.js
🧰 Additional context used
📓 Path-based instructions (11)
**/test/fixtures/**
📄 CodeRabbit inference engine (AGENTS.md)
Put reusable test data under test/fixtures/
Files:
plugins/static/test/fixtures/static-server-custom/app/assets/foo.jsplugins/static/test/fixtures/static-server-with-dirs/config/config.default.jsplugins/static/test/fixtures/static-server-with-dir/package.jsonplugins/static/test/fixtures/static-server/config/config.default.js
packages/**/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use TypeScript for all source files in packages (no JavaScript source files)
Files:
packages/egg/src/lib/types.plugin.tspackages/egg/src/lib/types.ts
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable
Files:
packages/egg/src/lib/types.plugin.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/src/index.tsplugins/static/src/app/middleware/static.tsplugins/static/vitest.config.tsplugins/static/test/static.test.tspackages/egg/src/lib/types.tspackages/egg/test/lib/define_config.test.tsplugins/static/src/config/config.default.ts
{packages,plugins,tools}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/*.{ts,tsx}: Prefer interfaces over type aliases for object shapes in TypeScript
Use explicit return types for public APIs
Use readonly modifiers where appropriate
Avoid the any type; prefer unknown when the type is truly unknown
Files:
packages/egg/src/lib/types.plugin.tspackages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/src/index.tsplugins/static/src/app/middleware/static.tsplugins/static/vitest.config.tsplugins/static/test/static.test.tspackages/egg/src/lib/types.tspackages/egg/test/lib/define_config.test.tsplugins/static/src/config/config.default.ts
packages/**/test/**/*.test.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/**/test/**/*.test.ts: Name test files as test/**/*.test.ts and run them with Vitest
Use import { describe, it } from 'vitest' in tests
Use Node.js built-in assert module for test assertions
Files:
packages/egg/test/lib/core/loader/load_plugin.test.tspackages/egg/test/lib/define_config.test.ts
**/test/**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites
Files:
packages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
{packages,plugins,tools}/**/test/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test files should follow the pattern test/**/*.test.ts
Files:
packages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
{packages,plugins,tools}/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Files:
packages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
plugins/**/vitest.config.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All new plugins must use Vitest and include vitest.config.ts
Files:
plugins/static/vitest.config.ts
plugins/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
plugins/**/package.json: Plugin package.json must include peerDependencies { "egg": "workspace:" }
Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/.js
Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Files:
plugins/static/test/fixtures/static-server-with-dir/package.json
{packages,plugins,tools}/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/package.json: All packages must provide a typecheck script using "tsc --noEmit"
All packages must use oxlint for linting with the command "oxlint --type-aware" (no ESLint configs)
Files:
plugins/static/test/fixtures/static-server-with-dir/package.json
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json must include peerDependencies { "egg": "workspace:*" }
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to packages/{egg,core}/tsconfig.json : packages/egg and packages/core must have strict mode enabled in their tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.{ts,tsx} : Use explicit return types for public APIs
Applied to files:
packages/egg/src/lib/types.plugin.tsplugins/static/src/index.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to packages/{egg,core}/tsconfig.json : packages/egg and packages/core must have strict mode enabled in their tsconfig.json
Applied to files:
packages/egg/src/lib/types.plugin.tsplugins/static/src/app/middleware/static.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/*.ts : Re-export types thoughtfully to keep the public API stable
Applied to files:
packages/egg/src/lib/types.plugin.tsplugins/static/src/index.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)
Applied to files:
packages/egg/src/lib/types.plugin.tspackages/egg/test/lib/core/loader/load_plugin.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/*.ts : Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Applied to files:
packages/egg/src/lib/types.plugin.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/*.js
Applied to files:
packages/egg/src/lib/types.plugin.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts
Applied to files:
packages/egg/test/lib/core/loader/load_plugin.test.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to plugins/**/vitest.config.ts : All new plugins must use Vitest and include vitest.config.ts
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.test.ts : In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions
Applied to files:
plugins/static/vitest.config.tsplugins/static/test/static.test.tspackages/egg/test/lib/define_config.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/test/**/*.test.ts : Test files should follow the pattern test/**/*.test.ts
Applied to files:
plugins/static/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/cookies/test/**/*.test.ts : cookies package uses Mocha; test files follow test/**/*.test.ts
Applied to files:
plugins/static/test/static.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)
Applied to files:
package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/package.json : All packages must provide a typecheck script using "tsc --noEmit"
Applied to files:
package.json
🧬 Code graph analysis (6)
plugins/static/src/app/middleware/static.ts (2)
plugins/static/src/types.ts (2)
StaticConfig(46-57)StaticDirOptions(3-39)packages/koa-static-cache/src/index.ts (1)
staticCache(139-321)
plugins/static/test/static.test.ts (1)
packages/supertest/src/test.ts (1)
expect(77-132)
packages/egg/src/lib/types.ts (4)
packages/egg/src/lib/egg.ts (1)
config(564-566)packages/core/src/loader/egg_loader.ts (1)
config(1003-1007)packages/core/src/egg.ts (1)
config(307-309)packages/egg/src/lib/core/base_hook_class.ts (1)
config(19-21)
packages/egg/test/lib/define_config.test.ts (1)
packages/egg/src/lib/types.ts (1)
defineConfigFactory(119-121)
plugins/static/test/fixtures/static-server/config/config.default.js (1)
plugins/static/test/fixtures/static-server-custom/config/config.default.js (1)
exports(4-6)
plugins/static/src/config/config.default.ts (1)
packages/egg/src/lib/types.ts (2)
defineConfigFactory(119-121)PartialEggConfig(86-86)
🪛 markdownlint-cli2 (0.18.1)
plugins/static/README.md
55-55: Link text should be descriptive
(MD059, descriptive-link-text)
plugins/static/CHANGELOG.md
20-20: Bare URL used
(MD034, no-bare-urls)
22-22: Bare URL used
(MD034, no-bare-urls)
30-30: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
30-30: Hard tabs
Column: 1
(MD010, no-hard-tabs)
31-31: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
31-31: Hard tabs
Column: 1
(MD010, no-hard-tabs)
32-32: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
32-32: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
36-36: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
36-36: Hard tabs
Column: 1
(MD010, no-hard-tabs)
37-37: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
37-37: Hard tabs
Column: 1
(MD010, no-hard-tabs)
40-40: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
41-41: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
41-41: Hard tabs
Column: 1
(MD010, no-hard-tabs)
44-44: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
44-44: Hard tabs
Column: 1
(MD010, no-hard-tabs)
45-45: Unordered list indentation
Expected: 2; Actual: 1
(MD007, ul-indent)
45-45: Hard tabs
Column: 1
(MD010, no-hard-tabs)
70-70: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
73-73: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
74-74: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
76-76: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
79-79: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
80-80: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
82-82: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
85-85: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
86-86: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
88-88: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
89-89: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
91-91: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
94-94: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
95-95: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
96-96: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
98-98: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
101-101: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
103-103: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
106-106: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
108-108: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
111-111: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
113-113: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
116-116: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
117-117: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
119-119: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
122-122: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
123-123: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
125-125: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
128-128: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
130-130: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
133-133: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
135-135: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
138-138: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: Test (windows-latest, 24, packages)
- GitHub Check: Test (ubuntu-latest, 24, plugins)
- GitHub Check: Test (windows-latest, 22, packages)
- GitHub Check: Test (macos-latest, 24, plugins)
- GitHub Check: Test (windows-latest, 22, tools)
- GitHub Check: Test (macos-latest, 24, packages)
- GitHub Check: Test (windows-latest, 24, plugins)
- GitHub Check: Test (windows-latest, 22, plugins)
- GitHub Check: Test (macos-latest, 22, tools)
- GitHub Check: Test (ubuntu-latest, 22, plugins)
- GitHub Check: Test (ubuntu-latest, 24, packages)
- GitHub Check: Test (ubuntu-latest, 22, packages)
- GitHub Check: Test egg-bin (ubuntu-latest, 24)
- GitHub Check: Test egg-bin (ubuntu-latest, 22)
- GitHub Check: Test egg-bin (windows-latest, 24)
- GitHub Check: Test egg-bin (macos-latest, 24)
- GitHub Check: Test egg-bin (macos-latest, 22)
- GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (3)
packages/egg/src/lib/types.plugin.ts (1)
1-14: Move triple-slash references before the importsTriple-slash directives must be the very first top-level statements; where they sit now (after the imports) they’re ignored, so the static/onerror plugin augmentations never register. Please hoist them above the import block.
+/// <reference types="@eggjs/static" /> +/// <reference types="@eggjs/onerror" /> // import plugins types import '@eggjs/watcher'; import '@eggjs/jsonp'; import '@eggjs/i18n'; import '@eggjs/security'; import '@eggjs/session'; import '@eggjs/logrotator'; import '@eggjs/multipart'; import '@eggjs/view'; - -/// <reference types="@eggjs/static" /> -/// <reference types="@eggjs/onerror" />plugins/static/test/fixtures/static-server-with-dirs/config/config.default.js (1)
9-13: Fix absolute path joins so fixtures resolve correctlyLine 9 and Line 12 pass absolute segments (
'/app/public','/dist/static') intopath.join, which stripsappInfo.baseDirand resolves to/app/publicand/dist/staticon the host. The fixture never sees the intended assets. Drop the leading slash so the join stays under the fixture’s base directory.- path.join(appInfo.baseDir, '/app/public'), + path.join(appInfo.baseDir, 'app/public'), @@ - dir: path.join(appInfo.baseDir, '/dist/static'), + dir: path.join(appInfo.baseDir, 'dist/static'),packages/egg/src/lib/types.ts (1)
55-57: Restore range handling for root-mounted static assetsSkipping falsy prefixes drops the empty-string (
'') mount that serves files from the app root, so range requests stop working for that configuration. Normalize the prefix (as staticCache already does) and always record it so range support stays intact.- if (newOptions.prefix) { - prefixes.push(newOptions.prefix); - } + const normalizedPrefix = (newOptions.prefix ?? '').replace(/\/*$/, '/'); + prefixes.push(normalizedPrefix); + newOptions.prefix = normalizedPrefix;
| Please open an issue [here](https://github.com/eggjs/egg/issues). | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use descriptive link text to unblock markdownlint
Line 55 still uses “here” as the link label, which triggers markdownlint’s MD059 rule and will keep the docs lint job red. Please switch to descriptive text so the pipeline passes.
-Please open an issue [here](https://github.com/eggjs/egg/issues).
+Please open an issue on the [egg repository issue tracker](https://github.com/eggjs/egg/issues).Based on static analysis hints
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Please open an issue [here](https://github.com/eggjs/egg/issues). | |
| Please open an issue on the [egg repository issue tracker](https://github.com/eggjs/egg/issues). |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
55-55: Link text should be descriptive
(MD059, descriptive-link-text)
🤖 Prompt for AI Agents
In plugins/static/README.md around lines 55-56, the link text uses the
non-descriptive word "here" which violates markdownlint MD059; update the link
label to descriptive text (e.g., "open an issue" or "file an issue on GitHub")
by replacing the "[here](...)" with a meaningful phrase that clearly describes
the destination while keeping the same URL so the markdownlint rule passes.
| let app: MockApplication; | ||
| beforeAll(async () => { | ||
| app = mock.app({ | ||
| baseDir: getFixtures('static-server'), | ||
| }); | ||
| await app.ready(); | ||
| }); | ||
|
|
||
| afterAll(() => app.close()); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard teardown when app setup fails
If mock.app() throws (as happened in CI), app stays undefined and afterAll crashes while calling close(), hiding the real failure. Make the fixture variable optional, guard the close, and reset it afterwards; please mirror the same fix for the other suites in this file.
- let app: MockApplication;
+ let app: MockApplication | undefined;
@@
- afterAll(() => app.close());
+ afterAll(async () => {
+ if (app) {
+ await app.close();
+ app = undefined;
+ }
+ });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let app: MockApplication; | |
| beforeAll(async () => { | |
| app = mock.app({ | |
| baseDir: getFixtures('static-server'), | |
| }); | |
| await app.ready(); | |
| }); | |
| afterAll(() => app.close()); | |
| let app: MockApplication | undefined; | |
| beforeAll(async () => { | |
| app = mock.app({ | |
| baseDir: getFixtures('static-server'), | |
| }); | |
| await app.ready(); | |
| }); | |
| afterAll(async () => { | |
| if (app) { | |
| await app.close(); | |
| app = undefined; | |
| } | |
| }); |
🤖 Prompt for AI Agents
In plugins/static/test/static.test.ts around lines 13 to 22, the test fixture
variable `app` can remain undefined if mock.app() throws, causing afterAll to
crash on app.close(); make the fixture variable optional (e.g., let app?:
MockApplication), guard the teardown by checking if app is defined before
calling app.close(), and reset app to undefined after closing; apply the same
change to the other test suites in this file so all afterAll blocks safely
handle failed setup.

🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Tests
Chores