feat(tools): merge create-egg repository into monorepo#5511
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/updates package homepage metadata and workspace dependencies, removes a contributors block from one README, adds a new tools/create-egg CLI package (sources, templates, configs, tests), and includes TypeScript/test project references so tests under tools/** run. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant CLI as create-egg CLI
participant Prompts as Prompter
participant FS as Filesystem
participant PM as PackageManager
participant Git as Git (optional)
Dev->>CLI: Run `create-egg [--template|-t <name>] [target]`
CLI->>CLI: Parse args (template, help, overwrite)
alt help requested
CLI-->>Dev: Print usage and exit
else
CLI->>Prompts: Ask project name / target dir
Prompts-->>CLI: Answers
CLI->>FS: Check target dir
alt non-empty
CLI->>Prompts: Confirm overwrite/remove/ignore
Prompts-->>CLI: Choice
CLI->>FS: Apply choice (clean/continue/cancel)
end
CLI->>Prompts: Select template (if not provided)
Prompts-->>CLI: Template name
CLI->>FS: Create target dir
CLI->>FS: Copy template files and apply placeholders
CLI->>PM: Detect package manager (npm/yarn/pnpm/bun)
opt template custom command
CLI->>PM: Run custom init command
PM-->>CLI: Exit code
end
opt initialize git
CLI->>Git: git init
Git-->>CLI: Repo initialized
end
CLI-->>Dev: Print next steps (install, dev, test)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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). (7)
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 |
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## next #5511 +/- ##
=======================================
Coverage 76.31% 76.31%
=======================================
Files 113 113
Lines 5891 5891
Branches 1240 1240
=======================================
Hits 4496 4496
Misses 1218 1218
Partials 177 177 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
7bf8b69 to
f19750b
Compare
Merge the create-egg package from https://github.com/eggjs/create-egg into the monorepo at tools/create-egg. This consolidates the scaffolding tool with the main framework for easier maintenance. - Add create-egg package to tools/create-egg directory - Update dependencies to use pnpm workspace and catalog references - Add TypeScript configuration for consistency - Integrate with root tsconfig.json references - Update README to reflect modern scaffolding commands - Set Node.js requirement to >=20.19.0 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Pull Request Overview
This PR merges the create-egg package from its standalone repository into the monorepo at tools/create-egg. It adds a modern scaffolding tool that generates Egg.js project templates with updated dependencies and configurations.
- Adds the complete create-egg package to the monorepo with TypeScript support
- Updates vitest configuration to include tools directory while excluding egg-bin
- Integrates with the existing package structure using pnpm workspace and catalog references
Reviewed Changes
Copilot reviewed 76 out of 79 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| vitest.config.ts | Updates test configuration to include tools/* while excluding tools/egg-bin |
| tools/create-egg/ | Complete scaffolding tool with CLI, templates, and TypeScript configuration |
| pnpm-workspace.yaml | Adds new dependencies to catalog for create-egg package |
| Multiple package.json files | Updates homepage URLs to use 'next' branch instead of 'master' |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
| "@eggjs/tegg-eventbus-plugin": "^3.5.2", | ||
| "@eggjs/tegg-plugin": "^3.5.2", | ||
| "@eggjs/tegg-schedule-plugin": "^3.5.2", | ||
| "egg-scripts": "^2.17.0", |
There was a problem hiding this comment.
Duplicate dependency 'egg-scripts' is defined on both line 23 and line 31 with different versions (^3.1.0 and ^2.17.0). This will cause confusion and potential installation issues.
| "egg-scripts": "^2.17.0", |
|
|
||
| - Use `npm run lint` to check code style | ||
| - Use `npm test` to run unit test | ||
| - se `npm run clean` to clean compiled js at development mode once |
There was a problem hiding this comment.
Typo in the bullet point: 'se' should be 'Use' to match the pattern of other bullet points.
| - se `npm run clean` to clean compiled js at development mode once | |
| - Use `npm run clean` to clean compiled js at development mode once |
|
|
||
| - Use `npm run lint` to check code style | ||
| - Use `npm test` to run unit test | ||
| - se `npm run clean` to clean compiled js at development mode once |
There was a problem hiding this comment.
Typo in the bullet point: 'se' should be 'Use' to match the pattern of other bullet points.
| - se `npm run clean` to clean compiled js at development mode once | |
| - Use `npm run clean` to clean compiled js at development mode once |
|
|
||
| ### Requirement | ||
|
|
||
| - Node.js >= 18.x |
There was a problem hiding this comment.
Node.js version requirement is inconsistent with package.json which specifies '>=20.19.0'. The README should match the actual engine requirement.
| - Node.js >= 18.x | |
| - Node.js >= 20.19.0 |
|
|
||
| ### Requirement | ||
|
|
||
| - Node.js >= 20.x |
There was a problem hiding this comment.
Node.js version requirement should be more specific. The package.json specifies '>=20.19.0' so the README should reflect the exact requirement for consistency.
| - Node.js >= 20.x | |
| - Node.js >= 20.19.0 |
| }); | ||
|
|
||
| test('return help usage how to use create-egg with -h alias', () => { | ||
| const { stdout } = run(['--h'], { cwd: import.meta.dirname }); |
There was a problem hiding this comment.
The test is using '--h' which is not a valid help flag. It should be '-h' (single dash) to match the alias configuration in the CLI code.
| const { stdout } = run(['--h'], { cwd: import.meta.dirname }); | |
| const { stdout } = run(['-h'], { cwd: import.meta.dirname }); |
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/extend2/package.json (1)
5-7: Align Node engine to repo baseline (>=20.19.0).PR objective sets Node.js >=20.19.0, but this package still declares >=18.7.0. Suggest bumping to match the repo minimum.
"engines": { - "node": ">=18.7.0" + "node": ">= 20.19.0" },tools/create-egg/src/templates/tegg/_.gitignore (1)
1-22: Don’t ignore all .js files; remove duplicate logs/ and fix package-lock typotools/create-egg/src/templates/tegg/_.gitignore — lines: 1,7 (duplicate
logs/); 12 (*.js); 21 (.package-lock.jsontypo).Replace the global
*.js, dedupelogs/, add common build artifacts and tsbuildinfo. Apply:logs/ -npm-debug.log +npm-debug.log* node_modules/ coverage/ .idea/ run/ -logs/ +dist/ +build/ .DS_Store .vscode *.swp *.lock -*.js .eslintcache app/**/*.js test/**/*.js config/**/*.js app/**/*.map test/**/*.map config/**/*.map -.package-lock.json +tsconfig.tsbuildinfoAfter scaffolding, ensure
.eslintrc.js(if any) and runtime JS aren’t unintentionally ignored.pnpm-workspace.yaml (1)
8-156: Enforce catalog: for external deps in workspace package.jsonReplace literal semver/version strings with catalog: for external packages (use workspace: for internal workspace packages). Audit found multiple violations under packages/ and tools/ — update the package.json files below (examples):
- packages/core/test/fixtures/helloworld-ts/package.json
- packages/koa/example/cjs/package.json
- packages/mock/test/fixtures/apps/helloworld/package.json
- packages/utils/test/fixtures/egg-app/package.json
- tools/egg-bin/test/fixtures/example-ts-custom-compiler/package.json
- tools/egg-bin/test/fixtures/example-ts/package.json
- tools/egg-bin/test/fixtures/mocha-test-ts-esm/package.json
- tools/egg-bin/test/fixtures/test path with space/example-app/package.json
- tools/create-egg/src/templates/egg3-simple-js/package.json
- tools/create-egg/src/templates/egg3-tegg/package.json
- tools/create-egg/src/templates/tegg/package.json
Exclude vendor node_modules when applying changes; I can run the full audit and prepare a PR to convert these.
🧹 Nitpick comments (54)
tools/create-egg/CHANGELOG.md (8)
27-27: Remove accidental generator noise."fatal: No names found, cannot describe anything." looks like a changelog tool artifact; drop it.
-**features** - * [[`08e69e2`](http://github.com/eggjs/create-egg/commit/08e69e22dbe309af648d01c46882415ac4ee785a)] - feat: update egg-init@2 (#5) (TZ | 天猪 <<[email protected]>>),fatal: No names found, cannot describe anything. +**features** + * [[`08e69e2`](https://github.com/eggjs/create-egg/commit/08e69e22dbe309af648d01c46882415ac4ee785a)] - feat: update egg-init@2 (#5) (TZ | 天猪 <<[email protected]>>)
35-35: Fix typo: “fist” → “first”.- * feat: fist version (#1) + * feat: first version (#1)
21-21: Use HTTPS for GitHub links.Avoid plain HTTP in commit links.
- * [[`7fd4d4b`](http://github.com/eggjs/create-egg/commit/7fd4d4bb0a5eccf47f2a5cc624cb4acff7431025)] - fix: npm publish files (#6) (TZ | 天猪 <<[email protected]>>) + * [[`7fd4d4b`](https://github.com/eggjs/create-egg/commit/7fd4d4bb0a5eccf47f2a5cc624cb4acff7431025)] - fix: npm publish files (#6) (TZ | 天猪 <<[email protected]>>)
17-25: Normalize section headings for consistency.Mixing Setext and ATX styles hurts readability. Convert old entries to ATX like 3.0.0.
-2.0.1 / 2020-08-04 -================== +## 2.0.1 - 2020-08-04 @@ -2.0.0 / 2020-08-04 -================== +## 2.0.0 - 2020-08-04
32-33: Normalize 1.0.0 heading style.-1.0.0 / 2018-09-28 -================== +## 1.0.0 - 2018-09-28
20-30: Promote bolded category labels to headings.Align with 3.0.0’s “### Features” style.
-**fixes** +### Fixes @@ -**features** +### Features @@ -**others** +### Others
3-5: Clarify pre-/post-migration history.Add a one-liner noting entries below are from the old repo; new releases live on eggjs/egg.
> [!IMPORTANT] > Moving forwards we are using the GitHub releases page at <https://github.com/eggjs/egg/releases> in combination with [release.yml](https://github.com/eggjs/egg/actions/workflows/release.yml) for publishing releases and their changelogs. + +Historical entries below were migrated from the former repository (eggjs/create-egg).
1-37: EOF newline and general polish.Ensure the file ends with a newline (some linters flag this). No behavior impact.
tools/create-egg/src/templates/egg3-simple-js/.vscode/launch.json (2)
7-16: Improve debug ergonomics: skip Node internals and node_modulesAdd skipFiles (and optionally cwd) so stepping isn’t noisy.
{ "type": "node", "request": "launch", "name": "Egg Debug", "runtimeExecutable": "npm", "runtimeArgs": ["run", "dev", "--", "--inspect-brk"], + "skipFiles": ["<node_internals>/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}", "console": "integratedTerminal", "restart": true, "autoAttachChildProcesses": true },
17-24: Align test launch config with debugSurface test output in the terminal too. Consider non-breaking attach by default.
{ "type": "node", "request": "launch", "name": "Egg Test", "runtimeExecutable": "npm", - "runtimeArgs": ["run", "test:local", "--", "--inspect-brk"], + "runtimeArgs": ["run", "test:local", "--", "--inspect"], // use --inspect-brk if you prefer break-at-first-line + "skipFiles": ["<node_internals>/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", "autoAttachChildProcesses": true }tools/create-egg/src/templates/tegg/.vscode/launch.json (2)
7-16: Mirror debug QoL: skipFiles/cwdSame QoL as other templates to reduce stepping noise.
{ "type": "node", "request": "launch", "name": "Egg Debug", "runtimeExecutable": "npm", "runtimeArgs": ["run", "dev", "--", "--inspect-brk"], + "skipFiles": ["<node_internals>/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}", "console": "integratedTerminal", "restart": true, "autoAttachChildProcesses": true },
17-24: Terminal output for tests + optional non-breaking inspectKeep parity with debug config and avoid breaking on first line unless desired.
{ "type": "node", "request": "launch", "name": "Egg Test", "runtimeExecutable": "npm", - "runtimeArgs": ["run", "test:local", "--", "--inspect-brk"], + "runtimeArgs": ["run", "test:local", "--", "--inspect"], + "skipFiles": ["<node_internals>/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", "autoAttachChildProcesses": true }tools/create-egg/src/templates/egg3-tegg/.vscode/launch.json (2)
7-16: Apply the same debug QoL defaultsMatch other templates: skipFiles/cwd.
{ "type": "node", "request": "launch", "name": "Egg Debug", "runtimeExecutable": "npm", "runtimeArgs": ["run", "dev", "--", "--inspect-brk"], + "skipFiles": ["<node_internals>/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}", "console": "integratedTerminal", "restart": true, "autoAttachChildProcesses": true },
17-24: Paritize test launcher settingsSurface test logs in terminal and avoid break-on-first-line by default.
{ "type": "node", "request": "launch", "name": "Egg Test", "runtimeExecutable": "npm", - "runtimeArgs": ["run", "test:local", "--", "--inspect-brk"], + "runtimeArgs": ["run", "test:local", "--", "--inspect"], + "skipFiles": ["<node_internals>/**", "**/node_modules/**"], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", "autoAttachChildProcesses": true }tools/create-egg/src/templates/egg3-simple-js/.eslintignore (1)
1-1: Ignore common Egg runtime artifactsESLint doesn’t need to traverse run/ and logs/. Keep coverage/ as added.
coverage +run +logs +coverage/lcov-reporttools/create-egg/src/templates/egg3-simple-js/.eslintrc (1)
1-4: Add test overrides for Mocha globalsPrevents lint errors on describe/it in test files.
{ "extends": "eslint-config-egg", - "root": true + "root": true, + "overrides": [ + { + "files": ["test/**/*.test.js", "test/**/*.spec.js"], + "env": { "mocha": true } + } + ] }tools/create-egg/src/templates/egg3-simple-js/README.md (3)
5-9: State the Node.js requirement (>= 20.19.0) upfrontAligns docs with PR’s stated engine baseline.
## QuickStart + +Requirements + +- Node.js >= 20.19.0
13-17: Optionally include pnpm usage and clarify test debug scriptIf the generator emits a test:local script (used by launch.json), mention it here.
```bash -npm i -npm run dev +npm i # or: pnpm i / yarn +npm run dev # or: pnpm dev / yarn dev open http://localhost:7001/--- `26-30`: **Document the debug-friendly test script if present** Keep npm test, but add test:local for debug parity with launch.json. ```diff ### npm scripts - Use `npm run lint` to check code style. -- Use `npm test` to run unit test. +- Use `npm test` to run unit tests. +- Use `npm run test:local` to debug unit tests with the Node inspector (if available).tools/create-egg/src/templates/egg3-simple-js/_.gitignore (1)
5-7: Consider committing lockfiles for deterministic installsIgnoring npm/yarn/pnpm lockfiles hurts reproducibility for scaffolded apps. Templates generally benefit from checked‑in lockfiles.
Apply this diff to stop ignoring lockfiles:
-*-lock.json -*-lock.yaml -yarn.locktools/create-egg/src/templates/egg3-simple-js/package.json (1)
32-37: Repository URL is emptyEmpty repository.url can confuse npm init flows; either drop the block or use a placeholder.
Apply one of:
- Remove the repository block entirely, or
- Set to "url": "https://example.com/your-repo" as a placeholder string.
tools/create-egg/src/templates/egg3-simple-js/config/config.default.js (1)
13-15: Minor: make keys composition explicitTemplate string is simpler to read and avoids accidental numeric coercion.
- config.keys = appInfo.name + '_{{keys}}'; + config.keys = `${appInfo.name}_{{keys}}`;tools/create-egg/src/templates/egg3-simple-js/test/app/controller/home.test.js (1)
17-19: Don’t mix async and returned PromiseEither return the Promise or use async/await. Prefer await for clarity.
- it('should GET /', async () => { - return app.httpRequest().get('/').expect('hi, egg').expect(200); - }); + it('should GET /', async () => { + await app.httpRequest().get('/').expect('hi, egg').expect(200); + });tools/create-egg/src/templates/egg3-tegg/app/module/bar/package.json (1)
1-6: Mark template packages private to prevent accidental publish.Add "private": true.
{ "name": "bar", + "private": true, "eggModule": { "name": "bar" } }tools/create-egg/src/templates/tegg/tsconfig.json (1)
2-3: Template tsconfig “extends” differs from monorepo guideline.Guidelines say sub-project tsconfigs should extend "../../tsconfig.json", while this template extends "@eggjs/tsconfig". If templates are exempt, add a brief comment or rename to a templated filename (e.g., tsconfig.json.hbs) to avoid automated checks; otherwise switch to the monorepo extend.
packages/tsconfig/package.json (1)
28-30: Engines set to Node >=22.17.1 — intentional?This exceeds the repo baseline (>=20.19.0). If not required, align; if required, note rationale in README or package description.
"engines": { - "node": ">=22.17.1" + "node": ">= 20.19.0" },tools/create-egg/src/templates/tegg/config/config.local.ts (1)
1-6: Use type-only import to avoid runtime dependencyAvoid emitting an unnecessary ESM import at runtime.
Apply:
-import { EggAppConfig, PowerPartial } from 'egg'; +import type { EggAppConfig, PowerPartial } from 'egg';tools/create-egg/src/templates/egg3-tegg/config/config.local.ts (1)
1-6: Preferimport typefor pure type usagePrevents emitting a runtime import.
-import { EggAppConfig, PowerPartial } from 'egg'; +import type { EggAppConfig, PowerPartial } from 'egg';tools/create-egg/src/templates/tegg/config/config.prod.ts (1)
1-6: Type-only importSame rationale as other config templates.
-import { EggAppConfig, PowerPartial } from 'egg'; +import type { EggAppConfig, PowerPartial } from 'egg';tools/create-egg/src/templates/tegg/config/plugin.ts (1)
1-1: Tighten typing and avoid runtime importUse type-only import and
satisfiesfor stronger checks without widening.Please confirm the plugin keys (
eventbusModule,aopModule, etc.) match the expected names in TEgg docs.-import { EggPlugin } from 'egg'; +import type { EggPlugin } from 'egg'; -const plugin: EggPlugin = { +const plugin = { tegg: { enable: true, package: '@eggjs/tegg-plugin', }, teggConfig: { enable: true, package: '@eggjs/tegg-config', }, teggController: { enable: true, package: '@eggjs/tegg-controller-plugin', }, teggSchedule: { enable: true, package: '@eggjs/tegg-schedule-plugin', }, eventbusModule: { enable: true, package: '@eggjs/tegg-eventbus-plugin', }, aopModule: { enable: true, package: '@eggjs/tegg-aop-plugin', }, tracer: { enable: true, package: '@eggjs/tracer', }, -}; +} as const satisfies EggPlugin;Also applies to: 3-32
tools/create-egg/src/templates/tegg/config/config.default.ts (1)
14-18: Avoid brittle GitHub line anchor; link drifts over timeThe comment points to a specific line in a GitHub file, which will age poorly. Either drop it or link to Vitest/multipart docs instead.
Apply:
- // @see https://github.com/eggjs/multipart/blob/master/src/config/config.default.ts#L104 + // See egg-multipart config for options.vitest.config.ts (1)
5-9: Point projects at concrete config files to avoid accidental double runsFile: vitest.config.ts — fd shows per-package/plugin/tool vitest.config.ts files plus a root vitest.config.ts; switch the projects entries to explicit config files.
Apply:
test: { projects: [ - 'packages/*', - 'plugins/*', - 'tools/*', + 'packages/*/vitest.config.ts', + 'plugins/*/vitest.config.ts', + 'tools/*/vitest.config.ts',tools/create-egg/src/templates/tegg/package.json (3)
49-56: Update placeholder URLs in template metadata.The template includes placeholder GitHub URLs that should be replaced during project generation to match the actual repository structure.
Ensure these placeholders are properly replaced in the CLI generation process:
- "homepage": "https://github.com/YOUR_USERNAME/YOUR_REPO#readme", - "bugs": { - "url": "https://github.com/YOUR_USERNAME/YOUR_REPO/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/YOUR_USERNAME/YOUR_REPO.git" - }, + "homepage": "https://github.com/{{username}}/{{name}}#readme", + "bugs": { + "url": "https://github.com/{{username}}/{{name}}/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/{{username}}/{{name}}.git" + },
25-31: Update TEgg package versions to latest available.The template specifies TEgg packages at version
^3.5.2, but the current latest version of @eggjs/tegg is 3.57.14. The template should use more recent versions for better functionality and security.Consider updating to the latest stable versions:
- "@eggjs/tegg": "^3.5.2", - "@eggjs/tegg-aop-plugin": "^3.5.2", - "@eggjs/tegg-config": "^3.5.2", - "@eggjs/tegg-controller-plugin": "^3.5.2", - "@eggjs/tegg-eventbus-plugin": "^3.5.2", - "@eggjs/tegg-plugin": "^3.5.2", - "@eggjs/tegg-schedule-plugin": "^3.5.2", + "@eggjs/tegg": "^3.57.14", + "@eggjs/tegg-aop-plugin": "^3.52.0", + "@eggjs/tegg-config": "^3.57.14", + "@eggjs/tegg-controller-plugin": "^3.41.0", + "@eggjs/tegg-eventbus-plugin": "^3.57.14", + "@eggjs/tegg-plugin": "^3.57.14", + "@eggjs/tegg-schedule-plugin": "^3.57.5",Please verify compatibility and run tests after updating to ensure all functionality works correctly with the newer versions.
23-34: Prefer catalog: references for TEgg deps in the templatepnpm-workspace.yaml defines catalog entries for @eggjs/tegg and related packages (catalogMode: prefer, @eggjs/tegg: ^3.2.2) and the repo widely uses "catalog:" — replace the explicit versions in tools/create-egg/src/templates/tegg/package.json (currently ^3.5.2 and egg: "beta") with "catalog:" references, or document why the pinned/newer versions are intentional.
tools/create-egg/src/templates/egg3-tegg/test/app/module/bar/controller/home.test.ts (1)
1-11: Update test to use Vitest imports instead of global describe/it.Based on the coding guidelines, template tests should import test functions from Vitest rather than relying on globals.
Apply this diff to align with Vitest best practices:
+import { describe, it } from 'vitest'; import { strict as assert } from 'node:assert'; import { app } from 'egg-mock/bootstrap';tools/create-egg/src/templates/tegg/test/app/module/foo/service/HelloService.test.ts (1)
1-9: Mixed testing patterns - consider consistency across templates.This test uses Vitest's
testandexpect, while other template tests usedescribe/itwith Node.jsassert. For better consistency across templates, consider standardizing on one approach.Apply this diff to align with the pattern used in other template tests:
-import { test, expect } from 'vitest'; +import { describe, it } from 'vitest'; +import { strict as assert } from 'node:assert'; import { app } from '@eggjs/mock/bootstrap'; import { HelloService } from '@/module/foo/service/HelloService'; -test('should hello() work', async () => { +describe('test/app/module/foo/service/HelloService.test.ts', () => { + it('should hello() work', async () => { - const helloService = await app.getEggObject(HelloService); - const msg = await helloService.hello('123456'); - expect(msg).toBe('hello, 123456'); -}); + const helloService = await app.getEggObject(HelloService); + const msg = await helloService.hello('123456'); + assert.equal(msg, 'hello, 123456'); + }); +});tools/create-egg/src/templates/egg3-tegg/_.gitignore (1)
1-21: Tighten ignores: remove duplication, avoid over-broad '*.js', add common build dirs.
- Duplicate logs/ (Line 7).
- '*.js' (Line 12) will hide non-build JS (e.g., scripts). You already ignore compiled JS per dirs.
- Consider ignoring dist/ and out/, and pnpm-lock.yaml for pnpm-based setups.
Apply:
logs/ npm-debug.log node_modules/ coverage/ .idea/ run/ -logs/ .DS_Store .vscode *.swp *.lock -*.js .eslintcache +dist/ +out/ app/**/*.js test/**/*.js config/**/*.js app/**/*.map test/**/*.map config/**/*.map .package-lock.json +pnpm-lock.yamltools/create-egg/src/templates/tegg/test/app/module/bar/controller/user.test.ts (1)
1-11: Test reads well and asserts the expected contract.Vitest style with expect is fine here. Keep as-is.
For consistency across templates, consider standardizing on either Node assert or Vitest expect in all TEgg tests.
tools/create-egg/src/templates/egg3-tegg/test/app/module/bar/controller/user.test.ts (1)
1-14: Looks good; matches egg-mock bootstrap style.Mocha-style globals via egg-mock/bootstrap are fine. Using Node assert aligns with guidance.
If these tests will be run under Vitest in some setups, explicitly import { describe, it } from 'vitest' to avoid relying on globals.
tools/create-egg/src/templates/egg3-tegg/app/module/bar/controller/user.ts (4)
14-15: Fix strictPropertyInitialization for DI field.With strict mode, property injection needs a definite assignment assertion.
Apply:
- @Inject() - private helloService: HelloService; + @Inject() + private helloService!: HelloService;
18-20: Normalize method path to '/user' (verify TEgg join semantics).Using a leading slash avoids subtle join issues when concatenating with the controller path.
Proposed change:
@HTTPMethod({ method: HTTPMethodEnum.GET, - path: 'user', + path: '/user', })Please confirm TEgg’s path-join behavior for 'user' vs '/user' to ensure the route is '/bar/user'.
21-23: Drop redundant await in return.Avoids an extra microtask and reads cleaner.
- return await this.helloService.hello(userId); + return this.helloService.hello(userId);
21-21: Consider validating required query param.If userId is required, enforce it (e.g., via decorator option or explicit guard) to prevent “hello, undefined”.
If TEgg supports it, prefer:
@HTTPQuery({ name: 'userId', required: true })Otherwise add an early guard and respond 400.
tools/create-egg/src/templates/tegg/test/app/module/bar/controller/home.test.ts (1)
1-8: Align with repo test style: vitest + Node assert.Use describe/it and node:assert to match project guidelines.
-import { test, expect } from 'vitest'; +import { describe, it } from 'vitest'; +import assert from 'node:assert/strict'; import { app } from '@eggjs/mock/bootstrap'; -test('should GET / status 200', async () => { - const res = await app.httpRequest().get('/'); - expect(res.status).toBe(200); - expect(res.text).toBe('hello egg'); -}); +describe('GET /', () => { + it('should return 200', async () => { + const res = await app.httpRequest().get('/'); + assert.equal(res.status, 200); + assert.equal(res.text, 'hello egg'); + }); +});tools/create-egg/src/templates/egg3-tegg/test/app/module/foo/service/HelloService.test.ts (1)
1-14: Import vitest globals explicitly and fix typo in ts-expect-error comment.Keeps tests consistent and tidies copy.
+import { describe, it } from 'vitest'; import { strict as assert } from 'node:assert'; import { app } from 'egg-mock/bootstrap'; import { HelloService } from '@/module/foo/service/HelloService'; describe('test/app/module/foo/service/HelloService.test.ts', () => { it('should hello() work', async () => { - // @ts-expect-error getEggObject no type defination + // @ts-expect-error getEggObject has no type definition const helloService = await app.getEggObject(HelloService); const msg = await helloService.hello('123456'); assert.equal(msg, 'hello, 123456'); }); });tools/create-egg/src/templates/tegg/app/module/bar/controller/home.ts (1)
13-21: Satisfy strict property init and add explicit return type.Prevents TS strictPropertyInitialization error and clarifies API.
@Inject() - private logger: EggLogger; + private logger!: EggLogger; @HTTPMethod({ method: HTTPMethodEnum.GET, path: '/', }) - async index() { + async index(): Promise<string> {tools/create-egg/src/templates/egg3-tegg/app/module/foo/service/HelloService.ts (1)
9-17: Add definite assignment on injected logger.Avoids strictPropertyInitialization error under strict mode.
// 注入一个 logger @Inject() - private logger: EggLogger; + private logger!: EggLogger;tools/create-egg/src/templates/egg3-tegg/app/module/bar/controller/home.ts (1)
13-21: Same strict init and return-type polish as other controllers.Keeps controllers consistent.
@Inject() - private logger: EggLogger; + private logger!: EggLogger; @HTTPMethod({ method: HTTPMethodEnum.GET, path: '/', }) - async index() { + async index(): Promise<string> {tools/create-egg/tsdown.config.ts (1)
3-16: Build config looks correct; add small DX tweaks and ensure dotfiles are copied
- Optional: add clean: true and sourceMap: true for nicer local builds.
- Confirmed: tsdown's copy does NOT include dotfiles by default — add explicit dotfile patterns or list specific dotfiles in the copy array (e.g. add 'src/templates/**/' and 'src/templates/.', or include '.eslintrc', '.gitignore' explicitly).
export default defineConfig({ entry: ['src/index.ts', 'src/cli.ts'], unbundle: true, dts: true, exports: { devExports: true, }, + clean: true, + sourceMap: true, copy: [ { from: 'src/templates', to: 'dist/templates', }, ], });tools/create-egg/test/cli.test.ts (1)
127-131: --overwrite is parsed as boolean; "ignore" arg is ignored.mri treats --overwrite as boolean here, so passing "ignore" has no effect (it behaves like "yes"). Either:
- change the test to pass only --overwrite, or
- change CLI to parse overwrite as an enum (yes|no|ignore).
tools/create-egg/src/templates/tegg/app/module/bar/controller/user.ts (1)
1-9: Type-only import, definite assignment, and drop redundant await.Improves type safety under strict mode and avoids superfluous await.
-import { HelloService } from '@/module/foo'; +import type { HelloService } from '@/module/foo'; @@ - private helloService: HelloService; + private helloService!: HelloService; @@ - async user(@HTTPQuery({ name: 'userId' }) userId: string) { - return await this.helloService.hello(userId); + async user(@HTTPQuery({ name: 'userId' }) userId: string) { + return this.helloService.hello(userId); }Ensure the template’s tsconfig.json configures the "@/..." path alias to the correct directory (e.g., "paths": { "@/": ["app/"] }) so this import resolves after scaffolding.
Also applies to: 14-16, 21-23
tools/create-egg/src/index.ts (2)
103-137: Non-interactive override could support enum via CLI.Current boolean --overwrite maps to “yes”. If you want parity with prompts (yes|no|ignore), parse overwrite as a string enum.
- overwrite?: boolean; + overwrite?: string; @@ - boolean: ['help', 'overwrite'], - string: ['template'], + boolean: ['help'], + string: ['template', 'overwrite'], @@ - const argOverwrite = argv.overwrite; + const argOverwrite = argv.overwrite as 'yes' | 'no' | 'ignore' | undefined; @@ - const overwrite = argOverwrite - ? 'yes' + const overwrite = argOverwrite + ? argOverwrite : await prompts.select({Update tests accordingly.
206-221: Template dir read: guard for missing template.If an invalid template slips through, fs.readdirSync throws. Consider a clearer error.
- const files = fs.readdirSync(templateDir); + if (!fs.existsSync(templateDir)) { + throw new Error(`Unknown template: ${template}`); + } + const files = fs.readdirSync(templateDir);
| > **Compatibility Note:** | ||
| > Egg.js requires [Node.js](https://nodejs.org/) version 20.19+. However, some templates require a higher Node.js version to work, please upgrade if your package manager warns about it. |
There was a problem hiding this comment.
🧩 Analysis chain
Verify engines across all packages match the documented Node >=20.19.0.
Docs say 20.19+, but some packages may differ (e.g., extend2, tsconfig). Run the script to list mismatches.
🏁 Script executed:
#!/bin/bash
# List package.json engines that don't match ">= 20.19.0"
fd -t f package.json | sort | while read -r f; do
eng=$(jq -r '.engines.node // empty' "$f")
if [ -n "$eng" ] && [ "$eng" != ">= 20.19.0" ]; then
printf "%-60s %s\n" "$f" "$eng"
fi
doneLength of output: 513
Align package.json engines with documented Node >=20.19.0
True mismatches (update engines or document exceptions):
- packages/extend2/package.json — engines.node: ">=18.7.0" → change to ">=20.19.0" or justify why it can remain lower.
- packages/tsconfig/package.json — engines.node: ">=22.17.1" → requires Node >=22; lower if possible or document/justify and update README.
- tools/create-egg/src/templates/egg3-simple-js/package.json — engines.node: ">=18.0.0" → change to ">=20.19.0" or document.
Ignore:
- packages/utils/test/fixtures/cjs/node_modules/tsconfig-paths-demo/package.json — test fixture (nested node_modules).
False positives (verification script bug — compared to ">= 20.19.0" with a space):
- tools/create-egg/package.json — ">=20.19.0" (compliant)
- tools/create-egg/src/templates/egg3-tegg/package.json — ">=20.19.0" (compliant)
- tools/create-egg/src/templates/tegg/package.json — ">=20.19.0" (compliant)
Action: standardize engines to ">=20.19.0" across packages or explicitly document per-package exceptions; fix the verification script to normalize whitespace (or compare against ">=20.19.0") and rerun.
🤖 Prompt for AI Agents
In tools/create-egg/README.md around lines 15-16, the documented Node
requirement (>=20.19.0) is out of sync with several package.json files: update
packages/extend2/package.json engines.node from ">=18.7.0" to ">=20.19.0" (or
add a short justification in that package's README if it truly supports older
Node), change tools/create-egg/src/templates/egg3-simple-js/package.json
engines.node from ">=18.0.0" to ">=20.19.0" (or document exception), and review
packages/tsconfig/package.json which currently requires ">=22.17.1" — either
relax it to ">=20.19.0" if compatible or add a documented rationale in README
and in the package.json comment; ignore the test fixture noted; also update the
verification script to normalize whitespace when comparing engine strings (trim
spaces before comparing to ">=20.19.0") and then rerun the verification to
confirm consistency.
| // 5. Run git init if user choose to run git init | ||
| const runGitInit = await prompts.confirm({ | ||
| message: 'Initialize git repository?', | ||
| initialValue: true, | ||
| }); | ||
| if (runGitInit) { | ||
| spawn.sync('git', ['init', cdProjectName], { stdio: 'pipe' }); | ||
| prompts.log.success('Git repository initialized'); | ||
| } |
There was a problem hiding this comment.
git init with empty path when root === cwd.
If target is current directory, cdProjectName is "", yielding git init "". Pass no path in that case.
- if (runGitInit) {
- spawn.sync('git', ['init', cdProjectName], { stdio: 'pipe' });
+ if (runGitInit) {
+ const gitArgs = root === cwd ? ['init'] : ['init', cdProjectName];
+ spawn.sync('git', gitArgs, { stdio: 'pipe' });
prompts.log.success('Git repository initialized');
}📝 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.
| // 5. Run git init if user choose to run git init | |
| const runGitInit = await prompts.confirm({ | |
| message: 'Initialize git repository?', | |
| initialValue: true, | |
| }); | |
| if (runGitInit) { | |
| spawn.sync('git', ['init', cdProjectName], { stdio: 'pipe' }); | |
| prompts.log.success('Git repository initialized'); | |
| } | |
| // 5. Run git init if user choose to run git init | |
| const runGitInit = await prompts.confirm({ | |
| message: 'Initialize git repository?', | |
| initialValue: true, | |
| }); | |
| if (runGitInit) { | |
| const gitArgs = root === cwd ? ['init'] : ['init', cdProjectName]; | |
| spawn.sync('git', gitArgs, { stdio: 'pipe' }); | |
| prompts.log.success('Git repository initialized'); | |
| } |
🤖 Prompt for AI Agents
In tools/create-egg/src/index.ts around lines 241 to 249, the code calls
spawn.sync('git', ['init', cdProjectName], ...) which will pass an empty string
when the target is the current directory (root === cwd), resulting in `git init
""`; change the call to omit the path arg when cdProjectName is an empty string
(e.g., build the args array conditionally: ['init'] when cdProjectName is empty,
otherwise ['init', cdProjectName]), and keep the same stdio options so Git is
invoked correctly without an empty-path argument.
| typings/ | ||
| .nyc_output/ |
There was a problem hiding this comment.
Test expects typings/ to exist but it’s ignored
home.test.js asserts that ../../../typings exists, yet this pattern ignores the whole folder. Ensure the directory is created and tracked.
Apply this diff to allow a tracked placeholder:
typings/
+!typings/.gitkeepAlso add a new file at typings/.gitkeep so the directory is present after scaffolding.
I can push a follow‑up patch adding the .gitkeep to the template if you want.
📝 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.
| typings/ | |
| .nyc_output/ | |
| typings/ | |
| !typings/.gitkeep | |
| .nyc_output/ |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-js/_.gitignore around lines 14-15,
the entry "typings/" ignores the entire typings directory which prevents the
test-created typings/.gitkeep from being tracked; change the gitignore to ignore
contents instead (e.g. use "typings/*" and add an exception "!typings/.gitkeep")
and add a new file typings/.gitkeep in the template so the directory is created
and present after scaffolding.
| * built-in config | ||
| * @type {Egg.EggAppConfig} | ||
| **/ | ||
| const config = (exports = {}); |
There was a problem hiding this comment.
Avoid assigning to CommonJS exports (linter error, potential confusion)
const config = (exports = {}); reassigns the module‑scope exports, tripping noGlobalAssign and risking confusion. Use a plain object.
Apply this diff:
- const config = (exports = {});
+ const config = {};📝 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 config = (exports = {}); | |
| const config = {}; |
🧰 Tools
🪛 Biome (2.1.2)
[error] 11-11: A global variable should not be reassigned.
Assigning to a global variable can override essential functionality.
(lint/suspicious/noGlobalAssign)
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-js/config/config.default.js around
line 11, avoid reassigning the CommonJS exports object; replace the current
pattern that does "const config = (exports = {});" with creating a plain object
(const config = {}) and then export it explicitly using module.exports = config
(or assign specific properties to exports) so you no longer reassign the
module-scoped exports variable.
| "engines": { | ||
| "node": ">=18.0.0" | ||
| }, |
There was a problem hiding this comment.
Node engines mismatch with PR objective (>=20.19.0)
PR summary states minimum Node.js >= 20.19.0; template pins >=18.0.0. Align to avoid user confusion and CI drift.
Apply this diff:
"engines": {
- "node": ">=18.0.0"
+ "node": ">=20.19.0"
},📝 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.
| "engines": { | |
| "node": ">=18.0.0" | |
| }, | |
| "engines": { | |
| "node": ">=20.19.0" | |
| }, |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-js/package.json around lines 19 to
21, the "engines.node" field is set to ">=18.0.0" but the PR requires a minimum
Node.js version of >=20.19.0; update the "node" value to ">=20.19.0" so the
template matches the PR objective and CI expectations.
| @@ -0,0 +1 @@ | |||
| export { HelloService } from './service/HelloService.ts'; | |||
There was a problem hiding this comment.
Fix ESM import specifier: do not import '.ts' under NodeNext.
Using .ts will fail at runtime; TypeScript expects .js specifiers that compile to .js output.
Apply:
-export { HelloService } from './service/HelloService.ts';
+export { HelloService } from './service/HelloService.js';📝 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.
| export { HelloService } from './service/HelloService.ts'; | |
| export { HelloService } from './service/HelloService.js'; |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/tegg/app/module/foo/index.ts around line 1,
the export uses a '.ts' specifier which will break under NodeNext; replace the
TypeScript extension with the runtime extension by updating the export to
reference the compiled .js module (e.g., change './service/HelloService.ts' to
'./service/HelloService.js') so imports resolve at runtime.
| import { EggLogger } from 'egg'; | ||
| import { SingletonProto, AccessLevel, Inject } from '@eggjs/tegg'; | ||
|
|
There was a problem hiding this comment.
Type-only import and definite assignment for injected field.
Prevents runtime import and strictPropertyInitialization errors in strict TS configs.
-import { EggLogger } from 'egg';
+import type { EggLogger } from 'egg';
@@
@Inject()
- private logger: EggLogger;
+ private logger!: EggLogger;Also applies to: 9-12
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/tegg/app/module/foo/service/HelloService.ts
around lines 1-3 (and similarly lines 9-12), the logger type and any other
type-only symbols should be imported using TypeScript's type-only import to
avoid runtime imports (e.g. "import type { EggLogger } from 'egg'"), and the
injected field(s) decorated with @Inject must be marked with the
definite-assignment assertion (!) to satisfy strictPropertyInitialization (e.g.
declare the field as logger!: EggLogger). Update the top imports to use "import
type" for types and add the trailing "!" to the injected property declarations
so compilation and runtime behavior are correct.
| config.keys = appInfo.name + '_{{keys}}'; | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
Ensure generator injects a strong secret for config.keys
The template expects {{keys}} to be replaced. Confirm the CLI generates a cryptographically strong secret (>= 32 bytes, random). If not, I can provide a helper using crypto.randomBytes.
I can wire up a generateKeys() util and template plumbing if needed.
🏁 Script executed:
#!/bin/bash
# Find secret generation in create-egg sources
rg -n --type=ts -C2 "keys.*random|randomBytes|secret|uuid" tools/create-egg | sed -n '1,200p'Length of output: 0
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo "----- top-level -----"
ls -la | sed -n '1,200p' || true
echo
echo "----- show template file if present -----"
if [ -f "tools/create-egg/src/templates/tegg/config/config.default.ts" ]; then
echo "FOUND: tools/create-egg/src/templates/tegg/config/config.default.ts"
sed -n '1,240p' tools/create-egg/src/templates/tegg/config/config.default.ts || true
else
echo "NOT FOUND: tools/create-egg/src/templates/tegg/config/config.default.ts"
fi
echo
echo "----- search for '{{keys}}' and similar placeholders -----"
rg -n --hidden --glob '!node_modules' -S "{{keys}}" || true
rg -n --hidden --glob '!node_modules' -S '\{\{[[:alnum:]_:-]+\}\}' || true
echo
echo "----- search under tools/create-egg for secret generation or templating code -----"
rg -n --hidden --glob '!node_modules' -S --path-separator '/' "tools/create-egg" || true
rg -n --hidden --glob '!node_modules' -S --path tools/create-egg "randomBytes|crypto\.randomBytes|crypto\s*\.|randomUUID|uuid|nanoid|secret|secretKey|generateKeys|generateKey|generate_secret" || true
rg -n --hidden --glob '!node_modules' -S --path tools/create-egg "ejs|mustache|handlebars|nunjucks|copyTpl|renderTemplate|template" || true
rg -n --hidden --glob '!node_modules' -S --path tools/create-egg "replace\(|replaceAll\(|format\(|templateString" || true
echo
echo "----- repo-wide searches for templating + replacement patterns -----"
rg -n --hidden --glob '!node_modules' -S "replace\(|replaceAll\(|template|renderTemplate|copyTpl|{{keys}}" || true
echo
echo "----- show package.json (if present) -----"
if [ -f package.json ]; then
jq '.name, .bin, .scripts' package.json || true
else
echo "No package.json at repo root"
fi
echo
echo "----- DONE -----"Length of output: 6641
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo
echo "----- tools/create-egg top-level -----"
ls -la tools/create-egg || true
echo
echo "----- tools/create-egg/src tree -----"
ls -la tools/create-egg/src || true
echo
echo "----- templates tree (show filenames only) -----"
find tools/create-egg/src/templates -type f -maxdepth 5 -print -exec printf '--- %s ---\n' {} \; -exec sed -n '1,120p' {} \; 2>/dev/null || true
echo
echo "----- show package.json for create-egg (if present) -----"
if [ -f tools/create-egg/package.json ]; then
jq '.name, .bin, .scripts, .dependencies, .devDependencies' tools/create-egg/package.json || true
else
echo "No tools/create-egg/package.json"
fi
echo
echo "----- search repo for template rendering / replacement in tools/create-egg -----"
rg -n --hidden -S -F "copyTpl" tools/create-egg || true
rg -n --hidden -S -F "render" tools/create-egg || true
rg -n --hidden -S -F "template" tools/create-egg || true
rg -n --hidden -S -F "replaceAll" tools/create-egg || true
rg -n --hidden -S -F "replace(" tools/create-egg || true
rg -n --hidden -S -F "ejs" tools/create-egg || true
rg -n --hidden -S -F "mustache" tools/create-egg || true
rg -n --hidden -S -F "handlebars" tools/create-egg || true
echo
echo "----- search repo for secret generation helpers -----"
rg -n --hidden -S -F "crypto.randomBytes" || true
rg -n --hidden -S -F "randomBytes(" || true
rg -n --hidden -S -F "randomUUID(" || true
rg -n --hidden -S -F "nanoid" || true
rg -n --hidden -S -F "uuid" || true
rg -n --hidden -S -F "generateKey" || true
rg -n --hidden -S -F "generateKeys" || true
rg -n --hidden -S -F "secret" || true
echo
echo "----- grep for literal '{{keys}}' occurrences -----"
rg -n --hidden -S -F "{{keys}}" || true
echo
echo "----- DONE -----"Length of output: 19957
Generate and inject a cryptographically-strong secret for config.keys
Templates contain config.keys = appInfo.name + '_{{keys}}'; but the scaffolder (tools/create-egg/src/index.ts) only replaces {{name}} (package.json) and does not replace {{keys}}. Add secure secret generation (>=32 bytes) and replace {{keys}} when writing files — e.g. const keys = crypto.randomBytes(32).toString('hex'); fileContent = fileContent.replaceAll('{{keys}}', keys);.
Locations:
- Templates to patch: tools/create-egg/src/templates/tegg/config/config.default.ts, tools/create-egg/src/templates/egg3-tegg/config/config.default.ts, tools/create-egg/src/templates/egg3-simple-js/config/config.default.js
- Scaffolder to modify: tools/create-egg/src/index.ts (where files are copied / package.json
replaceAllis done)
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/tegg/config/config.default.ts around lines 8-9
the template uses config.keys = appInfo.name + '_{{keys}}'; but the scaffolder
doesn't replace {{keys}}; generate a cryptographically-strong secret (at least
32 bytes) in tools/create-egg/src/index.ts (e.g.
crypto.randomBytes(32).toString('hex')) and, when writing/copying template
files, replaceAll('{{keys}}', generatedKey) in addition to the existing {{name}}
replacement; also update the other template files listed
(tools/create-egg/src/templates/egg3-tegg/config/config.default.ts and
tools/create-egg/src/templates/egg3-simple-js/config/config.default.js) to use
the same {{keys}} token so the scaffolder replacement injects the secure key.
| const run = <SO extends SyncOptions>( | ||
| args: string[], | ||
| options?: SO | ||
| ): SyncResult<SO> => { | ||
| return execaCommandSync(`node ${CLI_PATH} ${args.join(' ')}`, options); | ||
| }; |
There was a problem hiding this comment.
Running TS entry with plain node will fail; load a TS runtime or run built JS.
node can't execute .ts directly. Use a loader (tsdown/register) or tsx, or invoke the built dist/cli.js.
Option A (preferred; no extra dep if tsdown/register is available):
- return execaCommandSync(`node ${CLI_PATH} ${args.join(' ')}`, options);
+ return execaCommandSync(
+ `node --import tsdown/register ${CLI_PATH} ${args.join(' ')}`,
+ options
+ );Option B (requires dev dep "tsx"):
- return execaCommandSync(`node ${CLI_PATH} ${args.join(' ')}`, options);
+ return execaCommandSync(`tsx ${CLI_PATH} ${args.join(' ')}`, options);Option C (run built file):
-const CLI_PATH = path.join(SRC_PATH, 'cli.ts');
+const CLI_PATH = path.join(import.meta.dirname, '../dist/cli.js');…and ensure the test runs after build.
📝 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 run = <SO extends SyncOptions>( | |
| args: string[], | |
| options?: SO | |
| ): SyncResult<SO> => { | |
| return execaCommandSync(`node ${CLI_PATH} ${args.join(' ')}`, options); | |
| }; | |
| const run = <SO extends SyncOptions>( | |
| args: string[], | |
| options?: SO | |
| ): SyncResult<SO> => { | |
| return execaCommandSync( | |
| `node --import tsdown/register ${CLI_PATH} ${args.join(' ')}`, | |
| options | |
| ); | |
| }; |
🤖 Prompt for AI Agents
In tools/create-egg/test/cli.test.ts around lines 19 to 24, the test currently
spawns `node` against a TypeScript entry which will fail because node cannot run
.ts files directly; update the test to either (A) load a TS runtime by prefixing
the command with a loader (e.g., `node -r ts-node/register` or `node -r
tsdown/register` if available), (B) invoke a runtime that supports TS natively
such as `tsx node` (install as a dev dependency if not present), or (C) point
the test at the built JS entry (e.g., dist/cli.js) and ensure the test suite
runs after the project build; pick one option and modify the execaCommandSync
invocation accordingly and add any needed dev dependency or test prebuild step.
| { | ||
| "extends": "../../tsconfig.json", | ||
| "compilerOptions": { | ||
| "baseUrl": "./" | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
LGTM — conforms to repo TS config rules.
Extends ../../tsconfig.json and sets baseUrl: "./" as required.
Run to sanity-check all subproject tsconfigs align:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Every subproject tsconfig must extend ../../tsconfig.json and baseUrl "./"
fd -a tsconfig.json packages plugins tools | grep -vE '^tsconfig.json$' | while read -r f; do
ext=$(jq -r '.extends // ""' "$f")
base=$(jq -r '.compilerOptions.baseUrl // ""' "$f")
if [[ "$ext" != "../../tsconfig.json" || "$base" != "./" ]]; then
echo "Mismatch: $f -> extends=$ext baseUrl=$base"
fi
doneLength of output: 59
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Robustly check all tsconfig.json under packages|plugins|tools for required fields.
command -v jq >/dev/null 2>&1 || { echo "ERROR: jq is required but not installed"; exit 2; }
dirs=(packages plugins tools)
files=()
for d in "${dirs[@]}"; do
if [ -d "$d" ]; then
while IFS= read -r -d '' f; do files+=("$f"); done < <(find "$d" -type f -name tsconfig.json -print0)
fi
done
if [ "${#files[@]}" -eq 0 ]; then
echo "No subproject tsconfig.json files found under packages|plugins|tools"
exit 0
fi
mismatch=0
for f in "${files[@]}"; do
ext=$(jq -r '.extends // ""' "$f" 2>/dev/null || echo "")
base=$(jq -r '.compilerOptions.baseUrl // ""' "$f" 2>/dev/null || echo "")
if [ "$ext" != "../../tsconfig.json" ] || [ "$base" != "./" ]; then
echo "Mismatch: $f -> extends=${ext:-<missing>} baseUrl=${base:-<missing>}"
mismatch=1
fi
done
exit "$mismatch"Length of output: 56
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate all tsconfig.json under packages, plugins, or tools and verify extends and baseUrl.
if ! command -v jq >/dev/null 2>&1; then
echo "ERROR: jq is required but not installed"
exit 2
fi
files=$(find packages plugins tools -type f -name tsconfig.json 2>/dev/null)
if [ -z "$files" ]; then
echo "No subproject tsconfig.json files found under packages, plugins, or tools"
exit 0
fi
echo "$files" | while IFS= read -r f; do
ext=$(jq -r '.extends // empty' "$f" 2>/dev/null)
base=$(jq -r '.compilerOptions.baseUrl // empty' "$f" 2>/dev/null)
if [ "$ext" != "../../tsconfig.json" ] || [ "$base" != "./" ]; then
echo "Mismatch: $f -> extends='${ext:-<missing>}' baseUrl='${base:-<missing>}'"
fi
doneLength of output: 998
Action required — multiple subproject tsconfig.json files do not conform to repo TS config rules
tools/create-egg/tsconfig.json is correct.
Mismatches found:
- packages/core/test/fixtures/app-ts/tsconfig.json -> extends='' baseUrl='.'
- packages/core/test/fixtures/egg-ts-js-tsconfig-paths/tsconfig.json -> extends='' baseUrl=''
- packages/core/test/fixtures/helloworld-ts/tsconfig.json -> extends='@eggjs/tsconfig' baseUrl=''
- packages/egg/test/fixtures/apps/app-ts-esm/tsconfig.json -> extends='../app-ts/tsconfig.json' baseUrl='.'
- packages/egg/test/fixtures/apps/app-ts-type-check/tsconfig.json -> extends='@eggjs/tsconfig' baseUrl='.'
- packages/egg/test/fixtures/apps/app-ts/tsconfig.json -> extends='@eggjs/tsconfig' baseUrl='.'
- packages/mock/test/fixtures/tegg-app-esm/tsconfig.json -> extends='@eggjs/tsconfig' baseUrl=''
- packages/mock/test/fixtures/tegg-app/tsconfig.json -> extends='@eggjs/tsconfig' baseUrl=''
- packages/tsconfig/test/fixtures/apps/ts-proj/tsconfig.json -> extends='@eggjs/tsconfig' baseUrl='./'
Fix: update each listed file to set "extends": "../../tsconfig.json" and "compilerOptions.baseUrl": "./" (or document justified exceptions in the PR).
🤖 Prompt for AI Agents
In tools/create-egg/tsconfig.json around lines 1 to 6 the file is correct, but
the PR must also update the other listed subproject tsconfig files to conform:
for each of the files reported in the review, set "extends" to
"../../tsconfig.json" and set "compilerOptions.baseUrl" to "./" (or provide a
documented exception in the PR if a different value is required); update each
offending tsconfig.json accordingly and run a quick tsc check to ensure no path
resolution regressions.
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (37)
tools/create-egg/src/templates/tegg/package.json (6)
23-44: Template should not depend on moving "beta" tags; parameterize or pin to stable ranges.Using tags like "beta" and broad majors ("24", "5", "1") in a scaffolded app makes installs non‑deterministic and prone to breakage when the tag moves. Prefer:
- Parameterized placeholders resolved by the generator, defaulting to stable caret ranges, or
- Explicit semver ranges (e.g., ^x.y.z).
If you intend to let users opt into “next/beta”, gate it via a prompt that swaps versions accordingly.
Example diff converting moving tags to template placeholders (adjust placeholder names to your templating system and defaults in the generator):
@@ "dependencies": { "@eggjs/scripts": "^4.0.0", "@eggjs/tegg": "^3.5.2", @@ - "egg": "beta" + "egg": "{{eggVersion}}" }, "devDependencies": { - "@eggjs/bin": "beta", - "@eggjs/mock": "beta", - "@eggjs/tsconfig": "beta", - "@types/node": "24", - "oxlint": "1", - "oxlint-tsgolint": "^0.2.0", - "typescript": "5", - "vitest": "beta" + "@eggjs/bin": "{{eggBinVersion}}", + "@eggjs/mock": "{{eggMockVersion}}", + "@eggjs/tsconfig": "{{eggTsconfigVersion}}", + "@types/node": "{{typesNodeVersion}}", + "oxlint": "{{oxlintVersion}}", + "oxlint-tsgolint": "{{oxlintTsgolintVersion}}", + "typescript": "{{typescriptVersion}}", + "vitest": "{{vitestVersion}}" }
17-17: Replace ‘sleep’ with a cross‑platform pause.‘sleep’ isn’t available on Windows shells. Use a Node one‑liner to ensure CI/dev parity.
Apply:
- "postci": "npm run prepublishOnly && npm start && sleep 10 && npm stop && npm run clean", + "postci": "npm run prepublishOnly && npm start && node -e \"setTimeout(() => process.exit(0), 10_000)\" && npm stop && npm run clean",
21-21: Consider renaming/build step clarity for apps.For a private app template, “prepublishOnly” is a misnomer and won’t run in most workflows. Prefer a neutral “build” script and call it from CI.
Example:
- "prepublishOnly": "npm run clean && npm run tsc" + "build": "npm run clean && npm run tsc"If you adopt this, also update “postci” to run “npm run build”.
12-16: Avoid duplicate test scripts.“test:local” and “test” both run vitest. Make “test:local” delegate to “test” to keep behavior in one place.
- "test:local": "vitest run", + "test:local": "npm run test",
48-57: Template these metadata fields to reduce post‑scaffold edits.Use placeholders tied to user/org input (like {{githubUser}} and {{name}}) so generated apps have correct links out of the box.
- "homepage": "https://github.com/YOUR_USERNAME/YOUR_REPO#readme", + "homepage": "https://github.com/{{githubUser}}/{{name}}#readme", @@ - "bugs": { - "url": "https://github.com/YOUR_USERNAME/YOUR_REPO/issues" - }, + "bugs": { "url": "https://github.com/{{githubUser}}/{{name}}/issues" }, @@ - "repository": { - "type": "git", - "url": "git+https://github.com/YOUR_USERNAME/YOUR_REPO.git" - }, + "repository": { "type": "git", "url": "git+https://github.com/{{githubUser}}/{{name}}.git" }, - "author": "Author Name <[email protected]>", + "author": "{{authorName}} <{{authorEmail}}>",
1-58: Catalog/workspace rule applicability to templates.Repo guidelines say tools//package.json should use “catalog:” and “workspace:*”. Applying that inside a project template would break installs outside this monorepo. Please confirm templates are exempt from this rule; if not, consider scoping the guideline to exclude tools//src/templates/**.
Suggestion: Update the lint rule/docs to explicitly exclude “tools//src/templates//package.json” from the catalog/workspace requirement to avoid future churn.
tools/create-egg/src/templates/simple-ts/config/plugin.ts (1)
3-9: Prefersatisfiesfor safer typing and better inference.This keeps literal inference while validating against
EggPlugin.Apply this diff:
-const plugins: EggPlugin = { +const plugins = { // static: true, // nunjucks: { // enable: true, // package: 'egg-view-nunjucks', // }, -}; +} satisfies EggPlugin;tools/create-egg/src/templates/egg3-simple-ts/config/plugin.ts (3)
1-1: Use type-only import to avoid a runtime dependency on 'egg'.This prevents emitting an import in JS when the type erases, keeping the config side-effect free.
-import { EggPlugin } from 'egg'; +import type { EggPlugin } from 'egg';
3-11: Inline the default export and usesatisfiesfor stricter key checking.Terser template; TS will validate keys against
EggPluginwithout widening the value type.-const plugin: EggPlugin = { - // static: true, - // nunjucks: { - // enable: true, - // package: 'egg-view-nunjucks', - // }, -}; - -export default plugin; +export default { + // static: true, + // nunjucks: { + // enable: true, + // package: 'egg-view-nunjucks', + // }, +} satisfies EggPlugin;
4-9: Add a quick install hint for optional plugins.Prevents template users from enabling Nunjucks without installing the package.
// nunjucks: { + // // Enable after installing: pnpm add egg-view-nunjucks // enable: true, // package: 'egg-view-nunjucks', // },tools/create-egg/src/templates/egg3-simple-ts/_.gitignore (5)
7-7: Remove duplicate ignore for logs/
logs/is listed twice. Keep a single entry.-logs/
11-11: Don’t blanket-ignore “*.lock”; either commit lockfiles or scope explicitlyIgnoring all “*.lock” can hide non-package-manager locks. Prefer committing lockfiles for apps, or narrow to specific ones if you truly want them ignored.
Option A (recommended: commit lockfiles) — remove the rule:
-*.lockOption B — scope explicitly:
-*.lock +package-lock.json +yarn.lock +pnpm-lock.yaml
2-2: Match rotated npm logsUse a wildcard to catch rotated/debug variants.
-npm-debug.log +npm-debug.log*
20-21: Add common TS/coverage artifacts to ignoreIf the template uses nyc and typings (common in Egg TS projects), ignore them as well. If compilation emits to dist/, include it too.
config/**/*.map +.nyc_output/ +typings/ +# add only if outDir is "dist" +dist/Run the verification script in my earlier comment to confirm outDir before adding
dist/.
21-21: Add trailing newline at EOFPOSIX tools expect a newline-terminated file.
-<no newline at end of file> +tools/create-egg/src/index.ts (3)
208-212: Exit code handling for customCommand may report success on failure.status can be null or undefined; defaulting to 0 masks errors. Check error and fall back to non‑zero.
- const { status } = spawn.sync(command, replacedArgs, { - stdio: 'inherit', - }); - process.exit(status ?? 0); + const result = spawn.sync(command, replacedArgs, { stdio: 'inherit' }); + if (result.error) { + prompts.log.error(`Failed to run: ${fullCustomCommand}`); + process.exit(1); + } + process.exit(result.status ?? 1);
116-149: “Ignore files and continue” currently overwrites collisions. Clarify or honor ‘ignore’.Selecting “Ignore files and continue” should not overwrite existing files. Add a skip‑existing policy and enforce it in write().
@@ - // 2. Handle directory if exist and not empty + // 2. Handle directory if exist and not empty + let skipExistingFiles = false; if (fs.existsSync(targetDir) && !isEmpty(targetDir)) { @@ switch (overwrite) { case 'yes': emptyDir(targetDir); break; case 'no': cancel(); return; + case 'ignore': + skipExistingFiles = true; + break; } } @@ - const write = (file: string, content?: string) => { + const write = (file: string, content?: string) => { const targetPath = path.join( root, file.startsWith('_') ? file.slice(1) : file ); + if (skipExistingFiles && fs.existsSync(targetPath)) return; if (content) { fs.writeFileSync(targetPath, content); } else { copy(path.join(templateDir, file), targetPath); } };Alternatively, rename the option label to “Proceed and overwrite conflicts” to match current behavior.
Also applies to: 220-230
11-19: Avoid parsing argv at module import time.Parsing argv at top‑level creates side effects when imported by tests or other tools. Parse inside init() or accept args from the CLI wrapper.
-const argv = mri<{ ... -}>(process.argv.slice(2), { ... }); +function parseArgv() { + return mri<{ template?: string; help?: boolean; overwrite?: boolean }>( + process.argv.slice(2), + { alias: { h: 'help', t: 'template' }, boolean: ['help', 'overwrite'], string: ['template'] }, + ); +} @@ export async function init() { + const argv = parseArgv();Also applies to: 78-90
tools/create-egg/src/templates/simple-ts/typings/index.d.ts (1)
1-3: Replace empty augmentation with a scaffold (or remove).
declare module 'egg' {}is a no‑op. Either remove it or keep a commented scaffold for users to extend types later.import 'egg'; -declare module 'egg' {} +// Augment Egg types here when needed, e.g.: +// declare module 'egg' { +// interface IService { +// // foo: FooService; +// } +// }tools/create-egg/src/templates/egg3-simple-ts/typings/index.d.ts (1)
1-3: Same here: avoid empty augmentation.Remove the no‑op augmentation or replace with a commented scaffold to guide users.
import 'egg'; -declare module 'egg' {} +// Augment Egg types here when needed, e.g.: +// declare module 'egg' { +// interface IService { +// // foo: FooService; +// } +// }tools/create-egg/src/templates/egg3-simple-ts/app/service/Test.ts (1)
6-6: File naming: prefer lowercase with hyphens per repo style.Rename
Test.ts→test.tsto align with “lowercase-with-hyphens” rule and avoid case‑sensitivity pitfalls.tools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.test.ts (2)
1-1: Use strict assertions and Node prefix.Prefer
assert.strictEqualfor clearer diffs, and import fromnode:assert.-import assert from 'assert'; +import { strict as assert } from 'node:assert'; @@ - assert(result === 'hi, egg'); + assert.strictEqual(result, 'hi, egg');Also applies to: 13-15
5-5: Correct describe title extension.It’s a
.tsfile.-describe('test/app/service/Test.test.js', () => { +describe('test/app/service/Test.test.ts', () => {tools/create-egg/src/templates/simple-ts/package.json (5)
18-18: postci is not cross‑platform (sleep).
sleepbreaks on Windows. Use a Node-based delay or condition check.- "postci": "npm run prepublishOnly && npm start && sleep 10 && npm stop && npm run clean", + "postci": "npm run prepublishOnly && npm start && node -e \"setTimeout(() => {}, 10_000)\" && npm stop && npm run clean",
32-33: Align @types/node with engines.Engines require Node >=20.19.0 but types target "24". Recommend matching the LTS major to reduce type drift.
- "@types/node": "24", + "@types/node": "^20",
19-22: Consider using project references for build scripts.If the template uses TS project references, prefer
tsc -bfor builds (you already do for clean). Not blocking.- "tsc": "tsc", + "tsc": "tsc -b",
41-49: Placeholder repository metadata may leak to generated projects.Either omit these fields or template them properly; otherwise users get broken links.
- "homepage": "https://github.com/YOUR_USERNAME/YOUR_REPO#readme", - "bugs": { - "url": "https://github.com/YOUR_USERNAME/YOUR_REPO/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/YOUR_USERNAME/YOUR_REPO.git" - }, + "//": "Set these after repo is created",
33-35: oxlint plugin present but unused.Without a config enabling oxlint-tsgolint, the plugin won’t apply. Add a config file or remove the dep.
tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.ts (1)
1-1: Prefer Node assert in Vitest tests (repo convention).Swap to assert for consistency with guidelines.
-import { test, expect } from 'vitest'; +import { test } from 'vitest'; +import assert from 'assert';- expect(res.text).toBe('hi, egg'); + assert.strictEqual(res.text, 'hi, egg');tools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.ts (1)
2-2: Unify mock bootstrap import.Use '@eggjs/mock/bootstrap' for the monorepo ESM-first tooling.
-import { app } from 'egg-mock/bootstrap'; +import { app } from '@eggjs/mock/bootstrap';tools/create-egg/src/templates/simple-ts/test/app/service/Test.test.ts (1)
1-1: Prefer Node assert in Vitest tests (repo convention).Adopt assert for consistency.
-import { test, expect } from 'vitest'; +import { test } from 'vitest'; +import assert from 'assert';- expect(result).toBe('hi, egg'); + assert.strictEqual(result, 'hi, egg');tools/create-egg/src/templates/simple-ts/app/router.ts (1)
1-1: Use type‑only import for Application.Avoids emitting an unnecessary runtime import in ESM builds.
-import { Application } from 'egg'; +import type { Application } from 'egg';tools/create-egg/src/templates/simple-ts/app/service/Test.ts (1)
6-14: Add explicit return type.Minor: makes the public API clearer in templates.
tools/create-egg/src/templates/egg3-simple-ts/app/router.ts (1)
1-1: Use type‑only import for Application.Keep ESM output clean.
-import { Application } from 'egg'; +import type { Application } from 'egg';tools/create-egg/src/templates/egg3-simple-ts/app/controller/home.ts (1)
4-4: Add explicit return type on public methodMake the return type clear to TS users and templates that enable explicit returns.
- public async index() { + public async index(): Promise<void> {tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json (1)
3-3: Tighten exclude glob.Use "node_modules" instead of "node_modules*" to avoid surprising exclusions.
- "exclude": ["app/public", "app/views", "node_modules*"] + "exclude": ["app/public", "app/views", "node_modules"]tools/create-egg/src/templates/egg3-simple-ts/README.md (1)
28-28: Fix typo in npm script documentation.There's a typo "se" that should be "Use".
- - se `npm run clean` to clean compiled js at development mode once + - Use `npm run clean` to clean compiled js at development mode once
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (32)
tools/create-egg/src/index.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/.eslintignore(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/.eslintrc(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/README.md(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/_.gitignore(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/app/controller/home.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/app/router.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/app/service/Test.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/config/config.default.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/config/config.local.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/config/config.prod.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/config/plugin.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/package.json(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.test.ts(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json(1 hunks)tools/create-egg/src/templates/egg3-simple-ts/typings/index.d.ts(1 hunks)tools/create-egg/src/templates/simple-ts/README.md(1 hunks)tools/create-egg/src/templates/simple-ts/_.gitignore(1 hunks)tools/create-egg/src/templates/simple-ts/app/controller/home.ts(1 hunks)tools/create-egg/src/templates/simple-ts/app/router.ts(1 hunks)tools/create-egg/src/templates/simple-ts/app/service/Test.ts(1 hunks)tools/create-egg/src/templates/simple-ts/config/config.default.ts(1 hunks)tools/create-egg/src/templates/simple-ts/config/config.local.ts(1 hunks)tools/create-egg/src/templates/simple-ts/config/config.prod.ts(1 hunks)tools/create-egg/src/templates/simple-ts/config/plugin.ts(1 hunks)tools/create-egg/src/templates/simple-ts/package.json(1 hunks)tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.ts(1 hunks)tools/create-egg/src/templates/simple-ts/test/app/service/Test.test.ts(1 hunks)tools/create-egg/src/templates/simple-ts/tsconfig.json(1 hunks)tools/create-egg/src/templates/simple-ts/typings/index.d.ts(1 hunks)tools/create-egg/src/templates/tegg/package.json(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- tools/create-egg/src/templates/simple-ts/README.md
- tools/create-egg/src/templates/egg3-simple-ts/.eslintignore
- tools/create-egg/src/templates/simple-ts/_.gitignore
🧰 Additional context used
📓 Path-based instructions (4)
**/*.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:
tools/create-egg/src/templates/egg3-simple-ts/app/router.tstools/create-egg/src/templates/simple-ts/config/plugin.tstools/create-egg/src/templates/egg3-simple-ts/config/config.local.tstools/create-egg/src/templates/simple-ts/config/config.default.tstools/create-egg/src/templates/egg3-simple-ts/app/controller/home.tstools/create-egg/src/templates/simple-ts/app/controller/home.tstools/create-egg/src/templates/egg3-simple-ts/config/config.prod.tstools/create-egg/src/templates/simple-ts/app/service/Test.tstools/create-egg/src/templates/simple-ts/app/router.tstools/create-egg/src/templates/simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.tstools/create-egg/src/index.tstools/create-egg/src/templates/egg3-simple-ts/typings/index.d.tstools/create-egg/src/templates/simple-ts/config/config.local.tstools/create-egg/src/templates/egg3-simple-ts/config/config.default.tstools/create-egg/src/templates/egg3-simple-ts/config/plugin.tstools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.test.tstools/create-egg/src/templates/simple-ts/typings/index.d.tstools/create-egg/src/templates/simple-ts/test/app/service/Test.test.tstools/create-egg/src/templates/simple-ts/config/config.prod.tstools/create-egg/src/templates/egg3-simple-ts/app/service/Test.ts
{packages,plugins,tools}/**/tsconfig.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/tsconfig.json: All sub-project tsconfig.json files must extend the root tsconfig.json using "extends": "../../tsconfig.json"
All sub-project tsconfig.json files must include compilerOptions.baseUrl set to "./"
Files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/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:
tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.test.tstools/create-egg/src/templates/simple-ts/test/app/service/Test.test.ts
{packages,plugins,tools}/**/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
{packages,plugins,tools}/**/package.json: Individual packages must reference external dependencies via "catalog:" from pnpm-workspace.yaml
Use "workspace:*" for internal monorepo dependencies between packages
Files:
tools/create-egg/src/templates/tegg/package.jsontools/create-egg/src/templates/simple-ts/package.jsontools/create-egg/src/templates/egg3-simple-ts/package.json
🧠 Learnings (17)
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to packages/egg/tsconfig.json : packages/egg/tsconfig.json must extend eggjs/tsconfig and enable strict mode
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/egg3-simple-ts/config/config.prod.tstools/create-egg/src/templates/egg3-simple-ts/.eslintrctools/create-egg/src/templates/egg3-simple-ts/typings/index.d.tstools/create-egg/src/templates/tegg/package.jsontools/create-egg/src/templates/simple-ts/package.jsontools/create-egg/src/templates/simple-ts/typings/index.d.tstools/create-egg/src/templates/egg3-simple-ts/package.jsontools/create-egg/src/templates/simple-ts/tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to tools/egg-bin/tsdown.config.ts : egg-bin tool must use tsdown for TypeScript compilation
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/config/plugin.tstools/create-egg/src/templates/egg3-simple-ts/config/config.local.tstools/create-egg/src/templates/simple-ts/config/config.default.tstools/create-egg/src/templates/egg3-simple-ts/config/config.prod.tstools/create-egg/src/templates/egg3-simple-ts/.eslintrctools/create-egg/src/templates/egg3-simple-ts/typings/index.d.tstools/create-egg/src/templates/simple-ts/config/config.local.tstools/create-egg/src/templates/simple-ts/typings/index.d.tstools/create-egg/src/templates/simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/config/config.prod.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to packages/egg/tsdown.config.ts : packages/egg must use tsdown configured for unbundled ESM output
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/config/plugin.tstools/create-egg/src/templates/egg3-simple-ts/config/config.local.tstools/create-egg/src/templates/simple-ts/config/config.default.tstools/create-egg/src/templates/egg3-simple-ts/config/config.prod.tstools/create-egg/src/templates/egg3-simple-ts/.eslintrctools/create-egg/src/templates/simple-ts/package.jsontools/create-egg/src/templates/egg3-simple-ts/package.jsontools/create-egg/src/templates/simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/config/config.prod.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins,tools}/**/tsconfig.json : All sub-project tsconfig.json files must extend the root tsconfig.json using "extends": "../../tsconfig.json"
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/egg3-simple-ts/.eslintrc
📚 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:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/egg3-simple-ts/.eslintrctools/create-egg/src/templates/simple-ts/tsconfig.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin (CLI tool) tests must use Mocha
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/typings/index.d.tstools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.test.tstools/create-egg/src/templates/simple-ts/typings/index.d.tstools/create-egg/src/templates/simple-ts/test/app/service/Test.test.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must export TS sources in development ("exports": { ".": "./src/index.ts", "./agent": "./src/agent.ts", "./app": "./src/app.ts", "./package.json": "./package.json" })
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.jsontools/create-egg/src/templates/simple-ts/config/plugin.tstools/create-egg/src/templates/egg3-simple-ts/config/plugin.tstools/create-egg/src/templates/simple-ts/package.jsontools/create-egg/src/templates/egg3-simple-ts/package.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/*/package.json : Plugin package.json must include an eggPlugin configuration field
Applied to files:
tools/create-egg/src/templates/simple-ts/config/plugin.tstools/create-egg/src/templates/simple-ts/config/config.default.tstools/create-egg/src/templates/egg3-simple-ts/typings/index.d.tstools/create-egg/src/templates/egg3-simple-ts/config/config.default.tstools/create-egg/src/templates/egg3-simple-ts/config/plugin.tstools/create-egg/src/templates/tegg/package.jsontools/create-egg/src/templates/simple-ts/package.jsontools/create-egg/src/templates/simple-ts/typings/index.d.tstools/create-egg/src/templates/egg3-simple-ts/package.json
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to plugins/**/tsdown.config.ts : All plugins must use the standard tsdown configuration template (entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true)
Applied to files:
tools/create-egg/src/templates/simple-ts/config/plugin.tstools/create-egg/src/templates/egg3-simple-ts/config/plugin.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins}/**/test/**/*.test.ts : Vitest test files should follow the naming pattern test/**/*.test.ts and import from vitest
Applied to files:
tools/create-egg/src/templates/simple-ts/test/app/controller/home.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:
tools/create-egg/src/templates/simple-ts/test/app/controller/home.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:
tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/simple-ts/test/app/service/Test.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: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps
Applied to files:
tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.ts
📚 Learning: 2025-09-15T01:56:16.297Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T01:56:16.297Z
Learning: Applies to {packages,plugins}/**/test/**/*.test.ts : Use Node.js built-in assert for assertions in Vitest tests
Applied to files:
tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.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:
tools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.tstools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.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:
tools/create-egg/src/templates/egg3-simple-ts/.eslintrctools/create-egg/src/templates/simple-ts/tsconfig.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 : Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Applied to files:
tools/create-egg/src/templates/egg3-simple-ts/.eslintrc
🧬 Code graph analysis (15)
tools/create-egg/src/templates/egg3-simple-ts/app/router.ts (1)
tools/create-egg/src/templates/simple-ts/app/router.ts (1)
app(3-7)
tools/create-egg/src/templates/simple-ts/config/plugin.ts (1)
packages/egg/src/lib/types.ts (1)
EggPlugin(290-304)
tools/create-egg/src/templates/egg3-simple-ts/config/config.local.ts (1)
packages/egg/src/lib/types.ts (2)
PowerPartial(93-95)EggAppConfig(97-271)
tools/create-egg/src/templates/simple-ts/config/config.default.ts (2)
tools/create-egg/src/templates/egg3-simple-ts/config/config.default.ts (1)
appInfo(3-23)packages/egg/src/lib/types.ts (3)
EggAppInfo(29-29)PowerPartial(93-95)EggAppConfig(97-271)
tools/create-egg/src/templates/egg3-simple-ts/app/controller/home.ts (1)
tools/create-egg/src/templates/simple-ts/app/controller/home.ts (1)
HomeController(3-8)
tools/create-egg/src/templates/simple-ts/app/controller/home.ts (1)
tools/create-egg/src/templates/egg3-simple-ts/app/controller/home.ts (1)
HomeController(3-8)
tools/create-egg/src/templates/egg3-simple-ts/config/config.prod.ts (2)
tools/create-egg/src/templates/egg3-simple-ts/config/config.local.ts (1)
config(3-6)packages/egg/src/lib/types.ts (2)
PowerPartial(93-95)EggAppConfig(97-271)
tools/create-egg/src/templates/simple-ts/app/router.ts (1)
tools/create-egg/src/templates/egg3-simple-ts/app/router.ts (1)
app(3-7)
tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.ts (2)
tools/create-egg/src/templates/simple-ts/app/router.ts (1)
app(3-7)packages/supertest/src/test.ts (1)
expect(84-147)
tools/create-egg/src/templates/egg3-simple-ts/test/app/controller/home.test.ts (1)
tools/create-egg/src/templates/egg3-simple-ts/app/router.ts (1)
app(3-7)
tools/create-egg/src/templates/simple-ts/config/config.local.ts (4)
tools/create-egg/src/templates/egg3-simple-ts/config/config.local.ts (1)
config(3-6)tools/create-egg/src/templates/egg3-simple-ts/config/config.prod.ts (1)
config(3-6)tools/create-egg/src/templates/simple-ts/config/config.prod.ts (1)
config(3-6)packages/egg/src/lib/types.ts (2)
PowerPartial(93-95)EggAppConfig(97-271)
tools/create-egg/src/templates/egg3-simple-ts/config/config.default.ts (3)
packages/egg/src/lib/types.ts (2)
PowerPartial(93-95)EggAppConfig(97-271)tools/create-egg/src/templates/egg3-simple-ts/config/config.local.ts (1)
config(3-6)tools/create-egg/src/templates/egg3-simple-ts/config/config.prod.ts (1)
config(3-6)
tools/create-egg/src/templates/egg3-simple-ts/config/plugin.ts (1)
packages/egg/src/lib/types.ts (1)
EggPlugin(290-304)
tools/create-egg/src/templates/simple-ts/config/config.prod.ts (2)
tools/create-egg/src/templates/simple-ts/config/config.local.ts (1)
config(3-6)packages/egg/src/lib/types.ts (2)
PowerPartial(93-95)EggAppConfig(97-271)
tools/create-egg/src/templates/egg3-simple-ts/app/service/Test.ts (1)
tools/create-egg/src/templates/simple-ts/app/service/Test.ts (1)
Test(6-14)
🪛 markdownlint-cli2 (0.18.1)
tools/create-egg/src/templates/egg3-simple-ts/README.md
10-10: Dollar signs used before commands without showing output
(MD014, commands-show-output)
11-11: Dollar signs used before commands without showing output
(MD014, commands-show-output)
12-12: Dollar signs used before commands without showing output
(MD014, commands-show-output)
20-20: Dollar signs used before commands without showing output
(MD014, commands-show-output)
21-21: Dollar signs used before commands without showing output
(MD014, commands-show-output)
⏰ 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). (13)
- GitHub Check: Test packages (macos-latest, 24)
- GitHub Check: Test packages (ubuntu-latest, 24)
- GitHub Check: Test packages (ubuntu-latest, 22)
- GitHub Check: Test packages (macos-latest, 22)
- GitHub Check: Test packages (windows-latest, 24)
- GitHub Check: Test packages (windows-latest, 22)
- GitHub Check: Test egg-bin (windows-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: Test egg-bin (ubuntu-latest, 24)
- GitHub Check: Test egg-bin (ubuntu-latest, 22)
- GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (23)
tools/create-egg/src/templates/tegg/package.json (1)
9-11: Confirm that the “egg-bin” CLI is actually provided by @eggjs/bin.The dev script invokes “egg-bin dev” but the package installed is “@eggjs/bin”. If “egg-bin” isn’t an alias exposed by @eggjs/bin, the command will fail. If the intended CLI is different (e.g., “eggctl dev”), update the script accordingly or add the correct dependency.
Also applies to: 35-38
tools/create-egg/src/templates/egg3-simple-ts/.eslintrc (1)
1-6: Add "root": true and ignorePatterns; confirm TypeScript ESLint deps (template uses ESLint v8)
- Update tools/create-egg/src/templates/egg3-simple-ts/.eslintrc to include root:true and ignorePatterns (skip dist/, coverage/) to prevent parent-config traversal and avoid linting build artifacts.
- Verification: tools/create-egg/src/templates/egg3-simple-ts/package.json reports eslint: "8" and eslint-config-egg: "13"; @typescript-eslint/parser and @typescript-eslint/eslint-plugin are NOT present. Confirm whether eslint-config-egg provides these as deps/peer-deps — if not, add "@typescript-eslint/parser" and "@typescript-eslint/eslint-plugin" to the template's devDependencies.
- Because the template uses ESLint v8, do NOT push a flat eslint.config.js (that recommendation applies to ESLint v9+). Renaming to .eslintrc.json is optional.
Apply (unchanged suggestion):
{ "extends": "eslint-config-egg/typescript", + "root": true, "parserOptions": { "project": "./tsconfig.json" - } + }, + "ignorePatterns": ["dist/", "coverage/"] }tools/create-egg/src/templates/simple-ts/config/plugin.ts (3)
1-1: Type-only import is correct.Matches ESM/TS guidelines and keeps the import erased at emit.
11-11: Default export is fine.Matches Egg’s loader expectations for config/plugin.ts.
4-9: Incorrect — boolean shorthand is supported; no change needed.
types.ts defines EggPluginItem = IEggPluginItem | boolean, sostatic: trueis valid.Likely an incorrect or invalid review comment.
tools/create-egg/src/templates/egg3-simple-ts/config/plugin.ts (1)
1-11: LGTM overall — clean, ESM-first TS template.tools/create-egg/src/index.ts (2)
244-249: Nice: packageManager field set from user agent.This improves reproducibility across workspaces. No issues.
259-261: git init passes an empty path when scaffolding into the current directory.When root === cwd, cdProjectName is "", producing git init "". Omit the path arg in that case.
- if (runGitInit) { - spawn.sync('git', ['init', cdProjectName], { stdio: 'pipe' }); + if (runGitInit) { + const gitArgs = root === cwd ? ['init'] : ['init', cdProjectName]; + spawn.sync('git', gitArgs, { stdio: 'pipe' }); prompts.log.success('Git repository initialized'); }tools/create-egg/src/templates/simple-ts/config/config.local.ts (1)
1-6: LGTM.Typed partial config with ESM default export looks good.
tools/create-egg/src/templates/simple-ts/config/config.prod.ts (1)
1-6: LGTM.Production partial config stub is correct and type‑safe.
tools/create-egg/src/templates/simple-ts/config/config.default.ts (2)
13-16: Verify sourceUrl branch/reference.The
examplesrepo may usemaininstead ofmaster. Confirm the link is valid or update accordingly.
1-23: LGTM overall.Typed base config, keys seed, and merge pattern follow Egg conventions.
tools/create-egg/src/templates/simple-ts/tsconfig.json (1)
1-10: Approved — template tsconfig extends @eggjs/tsconfig and is not part of workspace refs/tests. Root tsconfig.json only references packages (e.g. ./packages/egg) and tools/create-egg/vitest.config.ts explicitly excludes '/templates//test/**'. No changes required.tools/create-egg/src/templates/egg3-simple-ts/test/app/service/Test.test.ts (1)
1-16: Template tests are already excluded from Vitest — no action required.
tools/create-egg/vitest.config.ts contains exclude: ['/node_modules/','/dist/','/templates//test/']; package configs also use include: ['test//*.test.ts'], so tests under tools/create-egg/src/templates/... won't be picked up.tools/create-egg/src/templates/simple-ts/app/controller/home.ts (1)
3-8: LGTM — controller wiring is correct.Matches router and (with the service fix) returns the expected payload.
tools/create-egg/src/templates/egg3-simple-ts/app/controller/home.ts (2)
3-8: LGTM: idiomatic Egg controllerClass naming, ESM import style, and two‑space indentation look good. Mirrors existing simple‑ts template behavior.
1-1: Import path confirmed — keepimport { Controller } from 'egg'. Matches Egg v3 official docs and TypeScript examples.tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json (1)
2-2: Confirm deviation from “extend root tsconfig” rule is intentional for templates.Guidelines say sub-project tsconfigs should
extend: "../../tsconfig.json", but this template extends@eggjs/tsconfig. If this is deliberate (because generated apps are standalone), please confirm and document it in the generator/template README; otherwise, adjust.tools/create-egg/src/templates/egg3-simple-ts/config/config.prod.ts (1)
1-6: LGTM! Production configuration template is properly structured.The template correctly imports the necessary types and provides an empty configuration object typed as
PowerPartial<EggAppConfig>, which is appropriate for a production configuration template that can be customized by users.tools/create-egg/src/templates/egg3-simple-ts/config/config.local.ts (1)
1-6: LGTM! Local configuration template follows best practices.The template correctly imports the necessary types and provides an empty configuration object, which is appropriate for a local development configuration template that users can customize as needed.
tools/create-egg/src/templates/egg3-simple-ts/package.json (3)
36-37: Update Node.js engine requirement to match LTS standards.The template specifies
>=20.0.0which is good, but should be aligned with the current LTS recommendations. Node.js v22 is now in Active LTS status, and Node.js v20 remains in Maintenance LTS until April 2026.The current requirement of
>=20.0.0is appropriate as it ensures compatibility with supported LTS versions. However, consider whether you want to require a more specific minimum version like>=20.19.0to align with the PR objectives mentioned in the description.
22-25: Consider using catalog references for dependencies as per coding guidelines.The coding guidelines specify that individual packages should reference external dependencies via
"catalog:"from pnpm-workspace.yaml. However, since this is a template file that gets copied to user projects, using direct version references is actually correct here.
17-17: Ensureets(egg-ts-helper) is available or make scripts explicitThe template's package.json scripts ("tsc" and "clean") call
ets, but the template does not add egg-ts-helper to dependencies;etsis provided by the egg-ts-helper package and can be run via npx or installed as a devDependency. (github.com) Egg-bin can also surface this helper (e.g. via --dts / register). (npm.io)Actions (choose one):
- Add "egg-ts-helper" to devDependencies of tools/create-egg/src/templates/egg3-simple-ts/package.json so
etsis available during npm scripts.- Or change the scripts to call
npx ets && tsc -p tsconfig.jsonandnpx ets clean(or rely onegg-bin ... --dts).tools/create-egg/src/templates/egg3-simple-ts/package.json (scripts: "tsc", "clean")
| const templateDir = path.join(import.meta.dirname, `templates/${template}`); | ||
|
|
There was a problem hiding this comment.
Bug: import.meta.dirname is not available on Node 20.x (will crash).
Node 20.19.0 does not support import.meta.dirname. Resolve from import.meta.url instead.
Apply this diff to the usage:
- const templateDir = path.join(import.meta.dirname, `templates/${template}`);
+ const templateDir = path.join(__dirname, `templates/${template}`);Add the following near the top with the other imports:
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));🤖 Prompt for AI Agents
In tools/create-egg/src/index.ts around lines 218 to 219, the code uses
import.meta.dirname which is not supported in Node 20.x and will crash; replace
that usage by computing a __dirname from import.meta.url: near the top with the
other imports add an import for fileURLToPath from node:url and set const
__dirname = path.dirname(fileURLToPath(import.meta.url)), then change the
templateDir assignment to use path.join(__dirname, `templates/${template}`)
instead of import.meta.dirname.
| *.js | ||
| !.autod.conf.js | ||
|
|
||
| app/**/*.js | ||
| test/**/*.js | ||
| config/**/*.js | ||
| app/**/*.map | ||
| test/**/*.map | ||
| config/**/*.map |
There was a problem hiding this comment.
🧩 Analysis chain
Overbroad “*.js” ignore will hide important config files; rely on targeted paths
*.js ignores all JS (including common tool configs like eslint.config.js, commitlint.config.js, etc.). You already ignore compiled JS under app/test/config; drop the global rule.
If the intent was to ignore compiler outputs only, apply:
-*.js
!.autod.conf.jsTo confirm the compiler output location, run:
🏁 Script executed:
#!/bin/bash
# Verify TS outDir or same-dir emit for the template
fd -a tsconfig.json tools/create-egg/src/templates/egg3-simple-ts -x sh -c '
echo "==> {}"
jq -r ".compilerOptions.outDir // \"(no outDir)\"" "{}" 2>/dev/null || grep -n \"outDir\" "{}" || true
'Length of output: 94
Remove global *.js from egg3-simple-ts template .gitignore
tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json has no compiler outDir (emits beside sources), and a global *.js will also hide repo config files (eslint.config.js, commitlint.config.js). Drop the global rule and keep the targeted ignores.
-*.js
!.autod.conf.js📝 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.
| *.js | |
| !.autod.conf.js | |
| app/**/*.js | |
| test/**/*.js | |
| config/**/*.js | |
| app/**/*.map | |
| test/**/*.map | |
| config/**/*.map | |
| !.autod.conf.js | |
| app/**/*.js | |
| test/**/*.js | |
| config/**/*.js | |
| app/**/*.map | |
| test/**/*.map | |
| config/**/*.map |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-ts/_.gitignore around lines 12 to
20, remove the global '*.js' ignore entry because the template's tsconfig emits
JS alongside sources and the global pattern unintentionally hides repo config
files like eslint.config.js and commitlint.config.js; instead keep only the
targeted ignore patterns (app/**/*.js, test/**/*.js, config/**/*.js and their
.map counterparts) so generated JS files are ignored without excluding top-level
config files.
| public async sayHi(name: string) { | ||
| return `hi, ${name}, TypeScript`; |
There was a problem hiding this comment.
Fix mismatch with tests: return string should be “hi, ${name}”.
Current implementation appends “, TypeScript” but tests expect exactly hi, egg.
public async sayHi(name: string) {
- return `hi, ${name}, TypeScript`;
+ return `hi, ${name}`;
}📝 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.
| public async sayHi(name: string) { | |
| return `hi, ${name}, TypeScript`; | |
| public async sayHi(name: string) { | |
| return `hi, ${name}`; | |
| } |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-ts/app/service/Test.ts around
lines 11 to 12, the sayHi method currently returns a string that appends ",
TypeScript" which mismatches tests; change the return value to exactly "hi,
${name}" (i.e., remove the ", TypeScript" suffix) so the function returns `hi,
${name}` for the provided name.
| import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg'; | ||
|
|
||
| export default (appInfo: EggAppInfo) => { | ||
| const config = {} as PowerPartial<EggAppConfig>; | ||
|
|
||
| // override config from framework / plugin | ||
| // use for cookie sign key, should change to your own and keep security | ||
| config.keys = appInfo.name + '_{{keys}}'; | ||
|
|
||
| // add your egg config in here | ||
| config.middleware = []; | ||
|
|
||
| // add your special config in here | ||
| const bizConfig = { | ||
| sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`, | ||
| }; | ||
|
|
||
| // the return config will combines to EggAppConfig | ||
| return { | ||
| ...config, | ||
| ...bizConfig, | ||
| }; | ||
| }; |
There was a problem hiding this comment.
Configuration template is well-structured but needs security improvement.
The template correctly implements the Egg.js configuration pattern with proper typing and structure. However, the hardcoded {{keys}} placeholder in the security keys creates potential security concerns.
For Line 8, consider making the keys generation more secure:
- config.keys = appInfo.name + '_{{keys}}';
+ config.keys = appInfo.name + '_' + Date.now() + '_' + Math.random().toString(36);Or better yet, encourage users to use environment variables:
- config.keys = appInfo.name + '_{{keys}}';
+ config.keys = process.env.EGG_KEYS || (appInfo.name + '_' + Date.now() + '_' + Math.random().toString(36));📝 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.
| import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg'; | |
| export default (appInfo: EggAppInfo) => { | |
| const config = {} as PowerPartial<EggAppConfig>; | |
| // override config from framework / plugin | |
| // use for cookie sign key, should change to your own and keep security | |
| config.keys = appInfo.name + '_{{keys}}'; | |
| // add your egg config in here | |
| config.middleware = []; | |
| // add your special config in here | |
| const bizConfig = { | |
| sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`, | |
| }; | |
| // the return config will combines to EggAppConfig | |
| return { | |
| ...config, | |
| ...bizConfig, | |
| }; | |
| }; | |
| import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg'; | |
| export default (appInfo: EggAppInfo) => { | |
| const config = {} as PowerPartial<EggAppConfig>; | |
| // override config from framework / plugin | |
| // use for cookie sign key, should change to your own and keep security | |
| config.keys = process.env.EGG_KEYS || (appInfo.name + '_' + Date.now() + '_' + Math.random().toString(36)); | |
| // add your egg config in here | |
| config.middleware = []; | |
| // add your special config in here | |
| const bizConfig = { | |
| sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`, | |
| }; | |
| // the return config will combines to EggAppConfig | |
| return { | |
| ...config, | |
| ...bizConfig, | |
| }; | |
| }; |
| - Node.js 8.x | ||
| - Typescript 2.8+ |
There was a problem hiding this comment.
Update Node.js version requirement to align with modern standards.
Node.js v22 is now in LTS status as of October 29, 2024, and Node.js v20 is in Maintenance LTS until April 2026. The template currently specifies "Node.js 8.x" which has been End of Life (EOL) and no longer receives official support.
- - Node.js 8.x
+ - Node.js >= 20.0.0📝 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.
| - Node.js 8.x | |
| - Typescript 2.8+ | |
| - Node.js >= 20.0.0 | |
| - Typescript 2.8+ |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-ts/README.md around lines 32-33,
the Node.js requirement currently reads "Node.js 8.x" which is EOL; update that
line to specify a modern LTS baseline (for example "Node.js 20.x or newer" or
"Node.js 20+ (LTS)") so the template aligns with current supported Node
versions; leave or separately bump the TypeScript requirement if needed to match
the updated Node support.
| { | ||
| "extends": "@eggjs/tsconfig", | ||
| "exclude": ["app/public", "app/views", "node_modules*"] | ||
| } |
There was a problem hiding this comment.
Add compilerOptions.baseUrl as required by repo guidelines.
Templates should also set baseUrl to "./" for consistent absolute import resolution.
Apply:
{
"extends": "@eggjs/tsconfig",
+ "compilerOptions": {
+ "baseUrl": "./"
+ },
"exclude": ["app/public", "app/views", "node_modules*"]
}📝 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.
| { | |
| "extends": "@eggjs/tsconfig", | |
| "exclude": ["app/public", "app/views", "node_modules*"] | |
| } | |
| { | |
| "extends": "@eggjs/tsconfig", | |
| "compilerOptions": { | |
| "baseUrl": "./" | |
| }, | |
| "exclude": ["app/public", "app/views", "node_modules*"] | |
| } |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json around lines 1 to
4, the template is missing compilerOptions.baseUrl per repo guidelines; add a
compilerOptions section with "baseUrl": "./" (merge with existing extends and
exclude) so the file contains a compilerOptions object that sets baseUrl to "./"
to ensure consistent absolute import resolution across projects.
🛠️ Refactor suggestion
🧩 Analysis chain
Optional: verify all template tsconfigs comply (baseUrl set).
Run to check across templates:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -a --glob 'tools/create-egg/src/templates/**/tsconfig.json' \
| while read -r f; do
has_baseurl=$(jq -er '.compilerOptions.baseUrl=="./"' "$f" 2>/dev/null || echo "no")
if [ "$has_baseurl" != "true" ]; then
echo "Missing baseUrl in: $f"
fi
doneLength of output: 0
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Searching for template tsconfig files under tools/create-egg/src/templates..."
mapfile -t files < <(find tools/create-egg/src/templates -type f -name tsconfig.json 2>/dev/null || true)
if [ "${#files[@]}" -eq 0 ]; then
echo "NO_TSCONFIG_FILES_FOUND"
exit 0
fi
for f in "${files[@]}"; do
echo "--- FILE: $f"
if ! command -v jq >/dev/null 2>&1; then
echo "JQ_NOT_INSTALLED — dumping file for manual inspection:"
sed -n '1,200p' "$f"
continue
fi
if jq -e '.compilerOptions and .compilerOptions.baseUrl' "$f" >/dev/null 2>&1; then
val=$(jq -r '.compilerOptions.baseUrl' "$f")
echo "baseUrl: $val"
else
echo "baseUrl_missing"
fi
doneLength of output: 134
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ROOT="tools/create-egg/src/templates"
echo "Searching for tsconfig.json under: $ROOT"
tmp=$(mktemp) || exit 1
find "$ROOT" -type f -name 'tsconfig.json' -print0 2>/dev/null > "$tmp" || true
if [ ! -s "$tmp" ]; then
echo "NO_TSCONFIG_FILES_FOUND"
rm -f "$tmp"
exit 0
fi
while IFS= read -r -d '' f; do
echo "--- FILE: $f"
if ! command -v jq >/dev/null 2>&1; then
echo "JQ_NOT_INSTALLED — dumping file for manual inspection:"
sed -n '1,200p' "$f" || true
continue
fi
baseurl=$(jq -r 'if (.compilerOptions and .compilerOptions.baseUrl) then .compilerOptions.baseUrl else empty end' "$f" 2>/dev/null || true)
if [ -z "$baseurl" ]; then
echo "baseUrl_missing"
else
echo "baseUrl: $baseurl"
fi
done < "$tmp"
rm -f "$tmp"Length of output: 374
Set compilerOptions.baseUrl to "./" in template tsconfig.json files
- tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json — missing compilerOptions.baseUrl
- tools/create-egg/src/templates/egg3-tegg/tsconfig.json — baseUrl: "."
- tools/create-egg/src/templates/simple-ts/tsconfig.json — baseUrl: "."
- tools/create-egg/src/templates/tegg/tsconfig.json — baseUrl: "."
Add compilerOptions.baseUrl = "./" to the missing file and normalize the "." entries to "./".
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/egg3-simple-ts/tsconfig.json around lines 1 to
4, the tsconfig is missing compilerOptions.baseUrl and other template files use
"." instead of "./"; add a compilerOptions object with baseUrl set to "./" to
this file and update any templates using baseUrl "." to use "./" to normalize
the value (keep other fields intact and ensure JSON remains valid).
| public async sayHi(name: string) { | ||
| return `hi, ${name}, TypeScript`; | ||
| } |
There was a problem hiding this comment.
Fix service response to match tests and other templates.
Remove the trailing ", TypeScript" to standardize on "hi, ".
- public async sayHi(name: string) {
- return `hi, ${name}, TypeScript`;
+ public async sayHi(name: string): Promise<string> {
+ return `hi, ${name}`;
}📝 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.
| public async sayHi(name: string) { | |
| return `hi, ${name}, TypeScript`; | |
| } | |
| public async sayHi(name: string): Promise<string> { | |
| return `hi, ${name}`; | |
| } |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/simple-ts/app/service/Test.ts around lines 11
to 13, the service returns "hi, <name>, TypeScript" which doesn't match tests
and other templates; change the return value to just "hi, <name>" by removing
the trailing ", TypeScript" so the method returns `hi, ${name}`.
| "typescript": "5", | ||
| "vitest": "beta" | ||
| }, |
There was a problem hiding this comment.
Avoid using an unstable dist-tag for Vitest.
"vitest": "beta" may not resolve reliably for scaffolded apps. Prefer a stable major (e.g., "^2") or pin via your template’s version matrix.
- "vitest": "beta"
+ "vitest": "^2"📝 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.
| "typescript": "5", | |
| "vitest": "beta" | |
| }, | |
| "typescript": "5", | |
| "vitest": "^2" | |
| }, |
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/simple-ts/package.json around lines 35 to 37,
the dependency "vitest": "beta" uses an unstable dist-tag that can resolve
inconsistently for scaffolded projects; replace the dist-tag with a stable
version specifier (for example "^2" or a specific pinned version according to
your template version matrix) in package.json so generated apps install a known,
stable Vitest release.
| test('should GET / status 200', async () => { | ||
| const res = await app.httpRequest().get('/').expect(200); | ||
| expect(res.text).toBe('hi, egg'); | ||
| }); |
There was a problem hiding this comment.
Test will fail against current service response.
Service returns "hi, egg, TypeScript" while the test expects "hi, egg". Prefer fixing the service to return "hi, " for parity with other templates.
Apply with the service fix in app/service/Test.ts (see inline suggestion there).
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/simple-ts/test/app/controller/home.test.ts
around lines 5-8 the test expects the response "hi, egg" but the service
currently returns "hi, egg, TypeScript"; update the service instead of the test:
open templates/simple-ts/app/service/Test.ts and change its response to return
exactly "hi, <name>" (e.g., construct and return `hi, ${name}` without appending
", TypeScript"), keep the same parameter handling so callers providing "egg"
still receive "hi, egg", then run tests to verify the controller test passes.
| test('sayHi should return hi, egg', async () => { | ||
| const ctx = app.mockContext(); | ||
| const result = await ctx.service.test.sayHi('egg'); | ||
| expect(result).toBe('hi, egg'); | ||
| }); |
There was a problem hiding this comment.
Test will fail against current service response.
Service returns "hi, egg, TypeScript". Align service to "hi, " for consistency with controller test and egg3 template.
(See fix in app/service/Test.ts.)
🤖 Prompt for AI Agents
In tools/create-egg/src/templates/simple-ts/test/app/service/Test.test.ts around
lines 5 to 9, the test expects "hi, <name>" but the service currently returns
"hi, <name>, TypeScript"; update the service implementation in
app/service/Test.ts to return exactly `hi, ${name}` (remove the ", TypeScript"
suffix) so the output matches the test and controller/egg3 template behavior,
then run the tests to confirm the change.
Merge the create-egg package from https://github.com/eggjs/create-egg into the monorepo at tools/create-egg. This consolidates the scaffolding tool with the main framework for easier maintenance.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Tests
Chores