diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000000..16d60e3eee --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "vite-plus": { + "command": "npx", + "args": ["vp", "mcp"] + } + } +} diff --git a/.claude/skills/vite-plus b/.claude/skills/vite-plus new file mode 120000 index 0000000000..71d3e5b0fd --- /dev/null +++ b/.claude/skills/vite-plus @@ -0,0 +1 @@ +../../node_modules/.pnpm/vite-plus@0.1.1_@types+node@20.19.37_jsdom@16.7.0_terser@5.46.0_typescript@5.9.3/node_modules/vite-plus/skills/vite-plus \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 5f59807ac1..5578d1a1aa 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -2,6 +2,7 @@ open_collective: eggjs # Replace with a single Open Collective username + # github: [ fengmk2, popomore, atian25, dead_horse ] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] # patreon: # Replace with a single Patreon username # ko_fi: # Replace with a single Ko-fi username diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 11bd06379e..4a715b6fec 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -42,7 +42,7 @@ body: description: | What's your Eggjs version? placeholder: | - See it directly in your "package.json" file (e.g: 3.1.0) + See it directly in your "package.json" file (e.g: 3.1.0) validations: required: true - type: input diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 954f1057f3..8ec9a4937a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,10 @@ name: "CodeQL" on: push: - branches: [ 3.x ] + branches: [3.x] pull_request: # The branches below must be a subset of the branches above - branches: [ 3.x ] + branches: [3.x] jobs: analyze: @@ -30,39 +30,39 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ["javascript"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://git.io/codeql-language-support steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - # โ„น๏ธ Command-line programs to run using the OS shell. - # ๐Ÿ“š https://git.io/JvXDl + # โ„น๏ธ Command-line programs to run using the OS shell. + # ๐Ÿ“š https://git.io/JvXDl - # โœ๏ธ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # โœ๏ธ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index fd81f760b3..3cdeab617b 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -2,7 +2,7 @@ name: Github Pages on: push: - branches: [ 3.x ] + branches: [3.x] jobs: Runner: @@ -10,25 +10,25 @@ jobs: strategy: fail-fast: false matrix: - os: [ ubuntu-latest ] - node-version: [ 18 ] + os: [ubuntu-latest] + node-version: [18] steps: - - name: Checkout Git Source - uses: actions/checkout@master + - name: Checkout Git Source + uses: actions/checkout@master - - name: Setup Node.js - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} + - name: Setup Node.js + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} - - name: Install Dependencies - run: npm i -g npminstall && npminstall + - name: Install Dependencies + run: npm i -g npminstall && npminstall - - name: Build Documents - run: npm run site:build + - name: Build Documents + run: npm run site:build - - name: Deploy Documents - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./site/dist + - name: Deploy Documents + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site/dist diff --git a/.github/workflows/nodejs-3.x.yml b/.github/workflows/nodejs-3.x.yml index 18e684106e..13cab54956 100644 --- a/.github/workflows/nodejs-3.x.yml +++ b/.github/workflows/nodejs-3.x.yml @@ -2,19 +2,19 @@ name: CI for 3.x on: push: - branches: [ 3.x ] + branches: [3.x] pull_request: - branches: [ 3.x ] + branches: [3.x] merge_group: - branches: [ 3.x ] + branches: [3.x] jobs: Job: name: Node.js uses: node-modules/github-actions/.github/workflows/node-test.yml@master with: - os: 'ubuntu-latest, macos-latest, windows-latest' - version: '14, 16, 18, 20, 22, 24' - install: 'npm i -g npminstall && npminstall' + os: "ubuntu-latest, macos-latest, windows-latest" + version: "14, 16, 18, 20, 22, 24" + install: "npm i -g npminstall && npminstall" secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index efb9f64be0..359b3e651a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ name: Release 3.x on: push: - branches: [ 3.x ] + branches: [3.x] permissions: contents: write diff --git a/.vite-hooks/pre-commit b/.vite-hooks/pre-commit new file mode 100755 index 0000000000..85fb65b4fc --- /dev/null +++ b/.vite-hooks/pre-commit @@ -0,0 +1 @@ +vp staged diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..99e2f7ddf7 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..7ab77f7a7c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + "editor.codeActionsOnSave": { + "source.fixAll.oxc": "explicit" + }, + "oxc.typeAware": true +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..85734764bb --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,76 @@ + + +# Using Vite+, the Unified Toolchain for the Web + +This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`. + +## Vite+ Workflow + +`vp` is a global binary that handles the full development lifecycle. Run `vp help` to print a list of commands and `vp --help` for information about a specific command. + +### Start + +- create - Create a new project from a template +- migrate - Migrate an existing project to Vite+ +- config - Configure hooks and agent integration +- staged - Run linters on staged files +- install (`i`) - Install dependencies +- env - Manage Node.js versions + +### Develop + +- dev - Run the development server +- check - Run format, lint, and TypeScript type checks +- lint - Lint code +- fmt - Format code +- test - Run tests + +### Execute + +- run - Run monorepo tasks +- exec - Execute a command from local `node_modules/.bin` +- dlx - Execute a package binary without installing it as a dependency +- cache - Manage the task cache + +### Build + +- build - Build for production +- pack - Build libraries +- preview - Preview production build + +### Manage Dependencies + +Vite+ automatically detects and wraps the underlying package manager such as pnpm, npm, or Yarn through the `packageManager` field in `package.json` or package manager-specific lockfiles. + +- add - Add packages to dependencies +- remove (`rm`, `un`, `uninstall`) - Remove packages from dependencies +- update (`up`) - Update packages to latest versions +- dedupe - Deduplicate dependencies +- outdated - Check for outdated packages +- list (`ls`) - List installed packages +- why (`explain`) - Show why a package is installed +- info (`view`, `show`) - View package information from the registry +- link (`ln`) / unlink - Manage local package links +- pm - Forward a command to the package manager + +### Maintain + +- upgrade - Update `vp` itself to the latest version + +These commands map to their corresponding tools. For example, `vp dev --port 3000` runs Vite's dev server and works the same as Vite. `vp test` runs JavaScript tests through the bundled Vitest. The version of all tools can be checked using `vp --version`. This is useful when researching documentation, features, and bugs. + +## Common Pitfalls + +- **Using the package manager directly:** Do not use pnpm, npm, or Yarn directly. Vite+ can handle all package manager operations. +- **Always use Vite commands to run tools:** Don't attempt to run `vp vitest` or `vp oxlint`. They do not exist. Use `vp test` and `vp lint` instead. +- **Running scripts:** Vite+ commands take precedence over `package.json` scripts. If there is a `test` script defined in `scripts` that conflicts with the built-in `vp test` command, run it using `vp run test`. +- **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly:** Vite+ wraps these tools. They must not be installed directly. You cannot upgrade these tools by installing their latest versions. Always use Vite+ commands. +- **Use Vite+ wrappers for one-off binaries:** Use `vp dlx` instead of package-manager-specific `dlx`/`npx` commands. +- **Import JavaScript modules from `vite-plus`:** Instead of importing from `vite` or `vitest`, all modules should be imported from the project's `vite-plus` dependency. For example, `import { defineConfig } from 'vite-plus';` or `import { expect, test, vi } from 'vite-plus/test';`. You must not install `vitest` to import test utilities. +- **Type-Aware Linting:** There is no need to install `oxlint-tsgolint`, `vp lint --type-aware` works out of the box. + +## Review Checklist for Agents + +- [ ] Run `vp install` after pulling remote changes and before getting started. +- [ ] Run `vp check` and `vp test` to validate changes. + diff --git a/CHANGELOG.md b/CHANGELOG.md index f61dd2d7cb..1e99e9531d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,253 +2,220 @@ ## 3.34.0 (2026-01-18) -* feat(core): support `config.httpclient.interceptors` for `fetch`/`safeFetch` tracer injection (#5771 ([fdfe958](https://github.com/eggjs/egg/commit/fdfe958)), closes [#5771](https://github.com/eggjs/egg/issues/5771) +- feat(core): support `config.httpclient.interceptors` for `fetch`/`safeFetch` tracer injection (#5771 ([fdfe958](https://github.com/eggjs/egg/commit/fdfe958)), closes [#5771](https://github.com/eggjs/egg/issues/5771) ## 3.33.1 (2026-01-16) -* fix: egg-mock for httpclient_next proxy (#5768) ([04cfa1b](https://github.com/eggjs/egg/commit/04cfa1b)), closes [#5768](https://github.com/eggjs/egg/issues/5768) +- fix: egg-mock for httpclient_next proxy (#5768) ([04cfa1b](https://github.com/eggjs/egg/commit/04cfa1b)), closes [#5768](https://github.com/eggjs/egg/issues/5768) ## 3.33.0 (2026-01-12) -* feat: httpclient_next proxy (#5763) ([a1169f3](https://github.com/eggjs/egg/commit/a1169f3)), closes [#5763](https://github.com/eggjs/egg/issues/5763) -* chore: rename to release.yml ([13d9a19](https://github.com/eggjs/egg/commit/13d9a19)) +- feat: httpclient_next proxy (#5763) ([a1169f3](https://github.com/eggjs/egg/commit/a1169f3)), closes [#5763](https://github.com/eggjs/egg/issues/5763) +- chore: rename to release.yml ([13d9a19](https://github.com/eggjs/egg/commit/13d9a19)) ## 3.32.0 (2025-12-24) -* feat: enable custom lookup for httpclient and fetch (#5749) ([4fa4d4b](https://github.com/eggjs/egg/commit/4fa4d4b)), closes [#5749](https://github.com/eggjs/egg/issues/5749) -* chore: fix auto release on 3.x ([e4d49a7](https://github.com/eggjs/egg/commit/e4d49a7)) -* chore: remove unuse actions ([5b4e3be](https://github.com/eggjs/egg/commit/5b4e3be)) +- feat: enable custom lookup for httpclient and fetch (#5749) ([4fa4d4b](https://github.com/eggjs/egg/commit/4fa4d4b)), closes [#5749](https://github.com/eggjs/egg/issues/5749) +- chore: fix auto release on 3.x ([e4d49a7](https://github.com/eggjs/egg/commit/e4d49a7)) +- chore: remove unuse actions ([5b4e3be](https://github.com/eggjs/egg/commit/5b4e3be)) ## [3.31.0](https://github.com/eggjs/egg/compare/v3.30.1...v3.31.0) (2025-07-04) - ### Features -* add urllib4 fetch ([#5424](https://github.com/eggjs/egg/issues/5424)) ([63d14da](https://github.com/eggjs/egg/commit/63d14da00170a73c55a7a12ab57dea93b8b2daa1)) +- add urllib4 fetch ([#5424](https://github.com/eggjs/egg/issues/5424)) ([63d14da](https://github.com/eggjs/egg/commit/63d14da00170a73c55a7a12ab57dea93b8b2daa1)) ## [3.30.1](https://github.com/eggjs/egg/compare/v3.30.0...v3.30.1) (2025-01-19) - ### Bug Fixes -* redefine urllib export types ([#5386](https://github.com/eggjs/egg/issues/5386)) ([02d9fdb](https://github.com/eggjs/egg/commit/02d9fdb7c127f9e8150bdb8f23977a2effeaf6ae)) +- redefine urllib export types ([#5386](https://github.com/eggjs/egg/issues/5386)) ([02d9fdb](https://github.com/eggjs/egg/commit/02d9fdb7c127f9e8150bdb8f23977a2effeaf6ae)) ## [3.30.0](https://github.com/eggjs/egg/compare/v3.29.0...v3.30.0) (2025-01-09) - ### Features -* dump ignore support key path ([#5380](https://github.com/eggjs/egg/issues/5380)) ([74346c2](https://github.com/eggjs/egg/commit/74346c2d056cab63c3c3a905c1e8afbf857451b4)) +- dump ignore support key path ([#5380](https://github.com/eggjs/egg/issues/5380)) ([74346c2](https://github.com/eggjs/egg/commit/74346c2d056cab63c3c3a905c1e8afbf857451b4)) ## [3.24.1](https://github.com/eggjs/egg/compare/v3.24.0...v3.24.1) (2024-06-07) - ### Bug Fixes -* serverTimeout default to 0 (no timeout) ([#5325](https://github.com/eggjs/egg/issues/5325)) ([44ab507](https://github.com/eggjs/egg/commit/44ab507b6299c849a2fe31bee54f3a1909aa9d53)) +- serverTimeout default to 0 (no timeout) ([#5325](https://github.com/eggjs/egg/issues/5325)) ([44ab507](https://github.com/eggjs/egg/commit/44ab507b6299c849a2fe31bee54f3a1909aa9d53)) ## [3.24.0](https://github.com/eggjs/egg/compare/v3.23.0...v3.24.0) (2024-06-07) - ### Features -* add bodyParser.onProtoPoisoning type define ([#5324](https://github.com/eggjs/egg/issues/5324)) ([b3582e0](https://github.com/eggjs/egg/commit/b3582e02d0f5d85edbc03f3f20c4cdcc65619dc1)) +- add bodyParser.onProtoPoisoning type define ([#5324](https://github.com/eggjs/egg/issues/5324)) ([b3582e0](https://github.com/eggjs/egg/commit/b3582e02d0f5d85edbc03f3f20c4cdcc65619dc1)) ## [3.23.0](https://github.com/eggjs/egg/compare/v3.22.0...v3.23.0) (2024-05-08) - ### Features -* use utility@2 ([#5312](https://github.com/eggjs/egg/issues/5312)) ([9bf5f22](https://github.com/eggjs/egg/commit/9bf5f22bfae44a1f44651efba7b3e167f9040714)) +- use utility@2 ([#5312](https://github.com/eggjs/egg/issues/5312)) ([9bf5f22](https://github.com/eggjs/egg/commit/9bf5f22bfae44a1f44651efba7b3e167f9040714)) ## [3.22.0](https://github.com/eggjs/egg/compare/v3.21.0...v3.22.0) (2024-04-12) - ### Features -* app.httpClient alias to app.httpclient ([#5304](https://github.com/eggjs/egg/issues/5304)) ([a6ebe0f](https://github.com/eggjs/egg/commit/a6ebe0f49a9e1a8506c26a0bb4e89a32528aa727)) +- app.httpClient alias to app.httpclient ([#5304](https://github.com/eggjs/egg/issues/5304)) ([a6ebe0f](https://github.com/eggjs/egg/commit/a6ebe0f49a9e1a8506c26a0bb4e89a32528aa727)) ## [3.21.0](https://github.com/eggjs/egg/compare/v3.20.0...v3.21.0) (2024-03-31) - ### Features -* tiny improvements for "convertValue" ([#5302](https://github.com/eggjs/egg/issues/5302)) ([794d7f3](https://github.com/eggjs/egg/commit/794d7f3e89c2a283e38d2082b407b79e480f0b50)) +- tiny improvements for "convertValue" ([#5302](https://github.com/eggjs/egg/issues/5302)) ([794d7f3](https://github.com/eggjs/egg/commit/794d7f3e89c2a283e38d2082b407b79e480f0b50)) ## [3.20.0](https://github.com/eggjs/egg/compare/v3.19.0...v3.20.0) (2024-02-22) - ### Features -* urllib-next alias to npm:urllib ([#5299](https://github.com/eggjs/egg/issues/5299)) ([61cd51d](https://github.com/eggjs/egg/commit/61cd51d02a86cb6ca8d510fb3ea3a1ed73f7beec)) +- urllib-next alias to npm:urllib ([#5299](https://github.com/eggjs/egg/issues/5299)) ([61cd51d](https://github.com/eggjs/egg/commit/61cd51d02a86cb6ca8d510fb3ea3a1ed73f7beec)) ## [3.19.0](https://github.com/eggjs/egg/compare/v3.18.0...v3.19.0) (2024-02-08) - ### Features -* ไผ˜ๅŒ–ไธญๆ–‡ๆ–‡ๆกฃ่กจ่พพ ([#5290](https://github.com/eggjs/egg/issues/5290)) ([d73046b](https://github.com/eggjs/egg/commit/d73046bb9165c74473b6f28842de23c880e78a87)) +- ไผ˜ๅŒ–ไธญๆ–‡ๆ–‡ๆกฃ่กจ่พพ ([#5290](https://github.com/eggjs/egg/issues/5290)) ([d73046b](https://github.com/eggjs/egg/commit/d73046bb9165c74473b6f28842de23c880e78a87)) ## [3.18.0](https://github.com/eggjs/egg/compare/v3.17.7...v3.18.0) (2024-01-21) - ### Features -* auto set custom logger with onelogger ([#5287](https://github.com/eggjs/egg/issues/5287)) ([1fd79a2](https://github.com/eggjs/egg/commit/1fd79a2715b4eded47ae77d955de5fa50efa573b)) +- auto set custom logger with onelogger ([#5287](https://github.com/eggjs/egg/issues/5287)) ([1fd79a2](https://github.com/eggjs/egg/commit/1fd79a2715b4eded47ae77d955de5fa50efa573b)) ## [3.17.7](https://github.com/eggjs/egg/compare/v3.17.6...v3.17.7) (2024-01-11) - ### Bug Fixes -* omit koa application ctxStorage and currentContext define ([#5285](https://github.com/eggjs/egg/issues/5285)) ([4c24dac](https://github.com/eggjs/egg/commit/4c24dac1e9ec86051d806dd6940c1d5095723b4d)) +- omit koa application ctxStorage and currentContext define ([#5285](https://github.com/eggjs/egg/issues/5285)) ([4c24dac](https://github.com/eggjs/egg/commit/4c24dac1e9ec86051d806dd6940c1d5095723b4d)) ## [3.17.6](https://github.com/eggjs/egg/compare/v3.17.5...v3.17.6) (2024-01-10) - ### Bug Fixes -* typo on index.d.ts ([#5284](https://github.com/eggjs/egg/issues/5284)) ([17ee60b](https://github.com/eggjs/egg/commit/17ee60b35a48c22eb90f392b688b4347c44b490d)) +- typo on index.d.ts ([#5284](https://github.com/eggjs/egg/issues/5284)) ([17ee60b](https://github.com/eggjs/egg/commit/17ee60b35a48c22eb90f392b688b4347c44b490d)) ## [3.17.5](https://github.com/eggjs/egg/compare/v3.17.4...v3.17.5) (2023-10-12) - ### Bug Fixes -* set body parser error to status 400 by default ([#5262](https://github.com/eggjs/egg/issues/5262)) ([5ac26a3](https://github.com/eggjs/egg/commit/5ac26a39b4256b6a3fcd55da947a47a82811c7c1)) +- set body parser error to status 400 by default ([#5262](https://github.com/eggjs/egg/issues/5262)) ([5ac26a3](https://github.com/eggjs/egg/commit/5ac26a39b4256b6a3fcd55da947a47a82811c7c1)) ## [3.17.4](https://github.com/eggjs/egg/compare/v3.17.3...v3.17.4) (2023-08-01) - ### Bug Fixes -* use app.logger instead of ctx.logger ([#5246](https://github.com/eggjs/egg/issues/5246)) ([b700fb9](https://github.com/eggjs/egg/commit/b700fb962a866c6e699f5c88b342960cc5ee0b78)), closes [/github.com/eggjs/egg/issues/5213#issuecomment-1657771583](https://github.com/eggjs//github.com/eggjs/egg/issues/5213/issues/issuecomment-1657771583) +- use app.logger instead of ctx.logger ([#5246](https://github.com/eggjs/egg/issues/5246)) ([b700fb9](https://github.com/eggjs/egg/commit/b700fb962a866c6e699f5c88b342960cc5ee0b78)), closes [/github.com/eggjs/egg/issues/5213#issuecomment-1657771583](https://github.com/eggjs//github.com/eggjs/egg/issues/5213/issues/issuecomment-1657771583) ## [3.17.3](https://github.com/eggjs/egg/compare/v3.17.2...v3.17.3) (2023-06-29) - ### Bug Fixes -* add missing args definition on runSchedule ([#5232](https://github.com/eggjs/egg/issues/5232)) ([f90763b](https://github.com/eggjs/egg/commit/f90763b164897bf4992b6ec58c4eae20775c0006)) +- add missing args definition on runSchedule ([#5232](https://github.com/eggjs/egg/issues/5232)) ([f90763b](https://github.com/eggjs/egg/commit/f90763b164897bf4992b6ec58c4eae20775c0006)) ## [3.17.2](https://github.com/eggjs/egg/compare/v3.17.1...v3.17.2) (2023-06-25) - ### Bug Fixes -* don't require inspector module on production env ([#5228](https://github.com/eggjs/egg/issues/5228)) ([398fe15](https://github.com/eggjs/egg/commit/398fe15eb28c3bbe8d79a0c2b129d55922f45a9a)) +- don't require inspector module on production env ([#5228](https://github.com/eggjs/egg/issues/5228)) ([398fe15](https://github.com/eggjs/egg/commit/398fe15eb28c3bbe8d79a0c2b129d55922f45a9a)) ## [3.17.1](https://github.com/eggjs/egg/compare/v3.17.0...v3.17.1) (2023-06-22) - ### Bug Fixes -* compatible with content-type extra semicolon ([#5217](https://github.com/eggjs/egg/issues/5217)) ([cfdca36](https://github.com/eggjs/egg/commit/cfdca36b4ee84397ed2cb1987982d502a3c8af0a)) +- compatible with content-type extra semicolon ([#5217](https://github.com/eggjs/egg/issues/5217)) ([cfdca36](https://github.com/eggjs/egg/commit/cfdca36b4ee84397ed2cb1987982d502a3c8af0a)) ## [3.17.0](https://github.com/eggjs/egg/compare/v3.16.1...v3.17.0) (2023-06-19) - ### Features -* add getSingletonInstance alias to singleton.get(id) ([#5216](https://github.com/eggjs/egg/issues/5216)) ([9868768](https://github.com/eggjs/egg/commit/98687685bb095d37166d3a66890f0164428a8e53)) +- add getSingletonInstance alias to singleton.get(id) ([#5216](https://github.com/eggjs/egg/issues/5216)) ([9868768](https://github.com/eggjs/egg/commit/98687685bb095d37166d3a66890f0164428a8e53)) ## [3.16.1](https://github.com/eggjs/egg/compare/v3.16.0...v3.16.1) (2023-06-15) - ### Bug Fixes -* ipc not work with worker_threads mode ([#5210](https://github.com/eggjs/egg/issues/5210)) ([03c8cf7](https://github.com/eggjs/egg/commit/03c8cf743d1fb56a55dbc633f088b08410423c5a)) +- ipc not work with worker_threads mode ([#5210](https://github.com/eggjs/egg/issues/5210)) ([03c8cf7](https://github.com/eggjs/egg/commit/03c8cf743d1fb56a55dbc633f088b08410423c5a)) ## [3.16.0](https://github.com/eggjs/egg/compare/v3.15.0...v3.16.0) (2023-05-10) - ### Features -* use egg-security@3.0.0 ([#5182](https://github.com/eggjs/egg/issues/5182)) ([a13b35e](https://github.com/eggjs/egg/commit/a13b35e05ca660fee3663db9381cdf44d63e44a0)) +- use egg-security@3.0.0 ([#5182](https://github.com/eggjs/egg/issues/5182)) ([a13b35e](https://github.com/eggjs/egg/commit/a13b35e05ca660fee3663db9381cdf44d63e44a0)) ## [3.15.0](https://github.com/eggjs/egg/compare/v3.14.2...v3.15.0) (2023-01-28) - ### Features -* runInAnonymousContextScope support req ([#5134](https://github.com/eggjs/egg/issues/5134)) ([615d660](https://github.com/eggjs/egg/commit/615d6608ab2fc66af848fb82ce41ed359f41bfb0)) +- runInAnonymousContextScope support req ([#5134](https://github.com/eggjs/egg/issues/5134)) ([615d660](https://github.com/eggjs/egg/commit/615d6608ab2fc66af848fb82ce41ed359f41bfb0)) ## [3.14.2](https://github.com/eggjs/egg/compare/v3.14.1...v3.14.2) (2023-01-20) - ### Bug Fixes -* **types:** app.router.url params should be optional ([#5132](https://github.com/eggjs/egg/issues/5132)) ([dda6bb3](https://github.com/eggjs/egg/commit/dda6bb3674af4acbdd7d5eb2f2ca373c714c7d2d)) +- **types:** app.router.url params should be optional ([#5132](https://github.com/eggjs/egg/issues/5132)) ([dda6bb3](https://github.com/eggjs/egg/commit/dda6bb3674af4acbdd7d5eb2f2ca373c714c7d2d)) ## [3.14.1](https://github.com/eggjs/egg/compare/v3.14.0...v3.14.1) (2023-01-17) - ### Bug Fixes -* export urllib types directly ([#5128](https://github.com/eggjs/egg/issues/5128)) ([483bf1d](https://github.com/eggjs/egg/commit/483bf1d12bee5157f9a95e0a5b7403fc7562900e)) +- export urllib types directly ([#5128](https://github.com/eggjs/egg/issues/5128)) ([483bf1d](https://github.com/eggjs/egg/commit/483bf1d12bee5157f9a95e0a5b7403fc7562900e)) ## [3.14.0](https://github.com/eggjs/egg/compare/v3.13.0...v3.14.0) (2023-01-17) - ### Features -* export urllib types ([#5127](https://github.com/eggjs/egg/issues/5127)) ([1f7b082](https://github.com/eggjs/egg/commit/1f7b08298ff4c6f118b93d3b3bf8e1fb3ac37db1)) +- export urllib types ([#5127](https://github.com/eggjs/egg/issues/5127)) ([1f7b082](https://github.com/eggjs/egg/commit/1f7b08298ff4c6f118b93d3b3bf8e1fb3ac37db1)) ## [3.13.0](https://github.com/eggjs/egg/compare/v3.12.0...v3.13.0) (2023-01-13) - ### Features -* log app start timeline on coreLogger ([#5122](https://github.com/eggjs/egg/issues/5122)) ([6c4e8bc](https://github.com/eggjs/egg/commit/6c4e8bca1b829ecd47e98cc9b0544c7aa874e755)) +- log app start timeline on coreLogger ([#5122](https://github.com/eggjs/egg/issues/5122)) ([6c4e8bc](https://github.com/eggjs/egg/commit/6c4e8bca1b829ecd47e98cc9b0544c7aa874e755)) ## [3.12.0](https://github.com/eggjs/egg/compare/v3.11.1...v3.12.0) (2023-01-04) - ### Features -* siteFile favicon config support async function type ([#5114](https://github.com/eggjs/egg/issues/5114)) ([667684f](https://github.com/eggjs/egg/commit/667684f79d8485ee9d9a03bf99077fa2dfef5507)) +- siteFile favicon config support async function type ([#5114](https://github.com/eggjs/egg/issues/5114)) ([667684f](https://github.com/eggjs/egg/commit/667684f79d8485ee9d9a03bf99077fa2dfef5507)) ## [3.11.1](https://github.com/eggjs/egg/compare/v3.11.0...v3.11.1) (2023-01-03) - ### Bug Fixes -* remove duplicate identifier ssrf ([#5113](https://github.com/eggjs/egg/issues/5113)) ([2b407eb](https://github.com/eggjs/egg/commit/2b407ebce9112d96e5e8a452eef09bcc70496e92)) +- remove duplicate identifier ssrf ([#5113](https://github.com/eggjs/egg/issues/5113)) ([2b407eb](https://github.com/eggjs/egg/commit/2b407ebce9112d96e5e8a452eef09bcc70496e92)) ## [3.11.0](https://github.com/eggjs/egg/compare/v3.10.0...v3.11.0) (2023-01-02) - ### Features -* add ssrf declaration ([#4687](https://github.com/eggjs/egg/issues/4687)) ([b1414f2](https://github.com/eggjs/egg/commit/b1414f2c749da5ab9bf07abf26ff75eac0b9cb73)) +- add ssrf declaration ([#4687](https://github.com/eggjs/egg/issues/4687)) ([b1414f2](https://github.com/eggjs/egg/commit/b1414f2c749da5ab9bf07abf26ff75eac0b9cb73)) ## [3.10.0](https://github.com/eggjs/egg/compare/v3.9.2...v3.10.0) (2023-01-02) - ### Features -* use egg-core@5 ([#5111](https://github.com/eggjs/egg/issues/5111)) ([7b8edbf](https://github.com/eggjs/egg/commit/7b8edbf322ed59c76ce3a85cd4595605d743fb80)) +- use egg-core@5 ([#5111](https://github.com/eggjs/egg/issues/5111)) ([7b8edbf](https://github.com/eggjs/egg/commit/7b8edbf322ed59c76ce3a85cd4595605d743fb80)) ## [3.9.2](https://github.com/eggjs/egg/compare/v3.9.1...v3.9.2) (2022-12-21) - ### Bug Fixes -* currentContext typo ([#5107](https://github.com/eggjs/egg/issues/5107)) ([713a081](https://github.com/eggjs/egg/commit/713a081475189ef6d00c85a559849ff97f824d11)) +- currentContext typo ([#5107](https://github.com/eggjs/egg/issues/5107)) ([713a081](https://github.com/eggjs/egg/commit/713a081475189ef6d00c85a559849ff97f824d11)) ## [3.9.1](https://github.com/eggjs/egg/compare/v3.9.0...v3.9.1) (2022-12-18) - ### Bug Fixes -* Enable auto npm release workflow ([#5102](https://github.com/eggjs/egg/issues/5102)) ([13bbe6c](https://github.com/eggjs/egg/commit/13bbe6c24e1c8160ae629e12c81e30e27b6c3dba)) +- Enable auto npm release workflow ([#5102](https://github.com/eggjs/egg/issues/5102)) ([13bbe6c](https://github.com/eggjs/egg/commit/13bbe6c24e1c8160ae629e12c81e30e27b6c3dba)) ## [3.9.1](https://github.com/eggjs/egg/compare/v3.9.0...v3.9.1) (2022-12-18) - ### Bug Fixes -* Enable auto npm release workflow ([#5102](https://github.com/eggjs/egg/issues/5102)) ([13bbe6c](https://github.com/eggjs/egg/commit/13bbe6c24e1c8160ae629e12c81e30e27b6c3dba)) +- Enable auto npm release workflow ([#5102](https://github.com/eggjs/egg/issues/5102)) ([13bbe6c](https://github.com/eggjs/egg/commit/13bbe6c24e1c8160ae629e12c81e30e27b6c3dba)) --- @@ -258,1825 +225,1828 @@ ### Notable Changes -* **features** - * ๐Ÿ“ฆ NEW: Run async function in the anonymous context scope +- **features** + - ๐Ÿ“ฆ NEW: Run async function in the anonymous context scope ```js - await app.runInAnonymousContextScope(async ctx => { + await app.runInAnonymousContextScope(async (ctx) => { // run with anonymous ctx here }); ``` ### Commits - * [[`af1206904`](http://github.com/eggjs/egg/commit/af12069041c1ea11217688c9c17d3712a44d3422)] - chore: update workflow for gh-pages (#5098) (Suyi <>) - * [[`344139e47`](http://github.com/eggjs/egg/commit/344139e4759f56ab2beca2e2a5c2783160396ba9)] - ๐Ÿ› FIX: Typo on HttpClient request (#5097) (fengmk2 <>) - * [[`1021faf78`](http://github.com/eggjs/egg/commit/1021faf78e5f23fa366c0034a38f81b0f361e9ec)] - ๐Ÿ‘Œ IMPROVE: Keep more compatible d.ts on httpclient request (#5092) (fengmk2 <>) - * [[`9d6acfd7c`](http://github.com/eggjs/egg/commit/9d6acfd7c3266ae6a56e45cb7a72473d628f6e16)] - ๐Ÿ“ฆ NEW: Run async function in the anonymous context scope (#5094) (fengmk2 <>) +- [[`af1206904`](http://github.com/eggjs/egg/commit/af12069041c1ea11217688c9c17d3712a44d3422)] - chore: update workflow for gh-pages (#5098) (Suyi <>) +- [[`344139e47`](http://github.com/eggjs/egg/commit/344139e4759f56ab2beca2e2a5c2783160396ba9)] - ๐Ÿ› FIX: Typo on HttpClient request (#5097) (fengmk2 <>) +- [[`1021faf78`](http://github.com/eggjs/egg/commit/1021faf78e5f23fa366c0034a38f81b0f361e9ec)] - ๐Ÿ‘Œ IMPROVE: Keep more compatible d.ts on httpclient request (#5092) (fengmk2 <>) +- [[`9d6acfd7c`](http://github.com/eggjs/egg/commit/9d6acfd7c3266ae6a56e45cb7a72473d628f6e16)] - ๐Ÿ“ฆ NEW: Run async function in the anonymous context scope (#5094) (fengmk2 <>) ## 2022-12-12, Version 3.8.0 @fengmk2 ### Notable Changes -* **features** - * Upgrade egg-schedule@4 to support `app.currentContext` on scheduler +- **features** + - Upgrade egg-schedule@4 to support `app.currentContext` on scheduler ### Commits - * [[`75d025b24`](http://github.com/eggjs/egg/commit/75d025b24e5e3016f2df84e2ba1901f42156c0b7)] - ๐Ÿ‘Œ IMPROVE: Upgrade egg-schedule to v4 (#5088) (fengmk2 <>) +- [[`75d025b24`](http://github.com/eggjs/egg/commit/75d025b24e5e3016f2df84e2ba1901f42156c0b7)] - ๐Ÿ‘Œ IMPROVE: Upgrade egg-schedule to v4 (#5088) (fengmk2 <>) ## 2022-12-11, Version 3.7.0 @fengmk2 ### Notable Changes -* **features** - * ๐Ÿ“ฆ NEW: Set `config.logger.enableFastContextLogger = true` to enable faster context logger +- **features** + - ๐Ÿ“ฆ NEW: Set `config.logger.enableFastContextLogger = true` to enable faster context logger ### Commits - * [[`e94c7df63`](http://github.com/eggjs/egg/commit/e94c7df63e1812da672dbaf7200e652cc4537c7b)] - ๐Ÿ“ฆ NEW: Upgrade egg-logger v3 to enable localStorage (#5085) (fengmk2 <>) - * [[`c76e16cf7`](http://github.com/eggjs/egg/commit/c76e16cf7fb67d5f2c1b19252e01a5e3fed9cf96)] - ๐Ÿ“– DOC: Use @eggjs/tsconfig for tsconfig.json (#5066) (fengmk2 <>) +- [[`e94c7df63`](http://github.com/eggjs/egg/commit/e94c7df63e1812da672dbaf7200e652cc4537c7b)] - ๐Ÿ“ฆ NEW: Upgrade egg-logger v3 to enable localStorage (#5085) (fengmk2 <>) +- [[`c76e16cf7`](http://github.com/eggjs/egg/commit/c76e16cf7fb67d5f2c1b19252e01a5e3fed9cf96)] - ๐Ÿ“– DOC: Use @eggjs/tsconfig for tsconfig.json (#5066) (fengmk2 <>) ## 2022-12-09, Version 3.6.0 @fengmk2 ### Notable Changes -* **features** - * ๐Ÿš€๐Ÿš€๐Ÿš€ Support `app.ctxStorage` and `app.currentContext` to get current execute ctx, see [koa#1455](https://github.com/koajs/koa/pull/1455) +- **features** + - ๐Ÿš€๐Ÿš€๐Ÿš€ Support `app.ctxStorage` and `app.currentContext` to get current execute ctx, see [koa#1455](https://github.com/koajs/koa/pull/1455) ### Commits - * [[`bf36904e0`](http://github.com/eggjs/egg/commit/bf36904e0fb1d4477ebb7068dd8ad6726d29182f)] - ๐Ÿ“ฆ NEW: Add ctxStorage and currentContext d.ts (#5079) (fengmk2 <>) - * [[`c68992ab7`](http://github.com/eggjs/egg/commit/c68992ab71b854f825df0ff3ea4b82e7666ec828)] - chore: ignore gp-pages branch while deploying preview (#5077) (Suyi <>) - * [[`13906825b`](http://github.com/eggjs/egg/commit/13906825bc3fab260aa0dd8888ce9fd19f2f70c5)] - chore: use actions to deploy vercel project (#5076) (Suyi <>) - * [[`5d825bb59`](http://github.com/eggjs/egg/commit/5d825bb59ed691bd45c3a8b2f6c222496910e250)] - docs: update communite links (#5073) (Suyi <>) +- [[`bf36904e0`](http://github.com/eggjs/egg/commit/bf36904e0fb1d4477ebb7068dd8ad6726d29182f)] - ๐Ÿ“ฆ NEW: Add ctxStorage and currentContext d.ts (#5079) (fengmk2 <>) +- [[`c68992ab7`](http://github.com/eggjs/egg/commit/c68992ab71b854f825df0ff3ea4b82e7666ec828)] - chore: ignore gp-pages branch while deploying preview (#5077) (Suyi <>) +- [[`13906825b`](http://github.com/eggjs/egg/commit/13906825bc3fab260aa0dd8888ce9fd19f2f70c5)] - chore: use actions to deploy vercel project (#5076) (Suyi <>) +- [[`5d825bb59`](http://github.com/eggjs/egg/commit/5d825bb59ed691bd45c3a8b2f6c222496910e250)] - docs: update communite links (#5073) (Suyi <>) ## 2022-11-28, Version 3.5.1 @killagu ### Notable Changes -* **fixes** - * Dump `config/timing` when app start timeout +- **fixes** + - Dump `config/timing` when app start timeout ### Commits - * [[`c859506a0`](http://github.com/eggjs/egg/commit/c859506a094181f5f45db16a8501daaaea56b3d3)] - fix: dump config/timing when timeout (#5069) (killa <>) +- [[`c859506a0`](http://github.com/eggjs/egg/commit/c859506a094181f5f45db16a8501daaaea56b3d3)] - fix: dump config/timing when timeout (#5069) (killa <>) ## 2022-11-15, Version 3.5.0 @fengmk2 ### Notable Changes -* **features** - * Auto disable cluster-client heartbeat checker on debug mode +- **features** + - Auto disable cluster-client heartbeat checker on debug mode ### Commits - * [[`6de5cba5d`](http://github.com/eggjs/egg/commit/6de5cba5d0d02d09e9e6ee71f9e7b1cb3d65c24e)] - feat: disable cluster-client heartbeat on debug mode (#5059) (sinkhaha <<1468709106@qq.com>>) +- [[`6de5cba5d`](http://github.com/eggjs/egg/commit/6de5cba5d0d02d09e9e6ee71f9e7b1cb3d65c24e)] - feat: disable cluster-client heartbeat on debug mode (#5059) (sinkhaha <<1468709106@qq.com>>) ## 2022-11-07, Version 3.4.0 @fengmk2 ### Notable Changes -* **features** - * Upgrade egg-cluster v2 to support worker_threads start mode - * Drop httpclient callback and thunk style, a breaking change to egg@2 - * Print warnning log when boot action takes more than 5000ms - * Don't need to patch keep-alive header on Node.js >= 14.20.0 +- **features** + - Upgrade egg-cluster v2 to support worker_threads start mode + - Drop httpclient callback and thunk style, a breaking change to egg@2 + - Print warnning log when boot action takes more than 5000ms + - Don't need to patch keep-alive header on Node.js >= 14.20.0 ### Commits - * [[`2b5f289bb`](http://github.com/eggjs/egg/commit/2b5f289bba3bd14c2867136b5dcbf3bed5cfdf9e)] - ๐Ÿ“ฆ NEW: Use egg-cluster v2 (#5055) (fengmk2 <>) - * [[`610a39e7f`](http://github.com/eggjs/egg/commit/610a39e7f41a17a2123705691d6c1bfdc3e12f88)] - ๐Ÿ‘Œ IMPROVE: Drop httpclient callback and thunk style (#5052) (fengmk2 <>) - * [[`3a941d669`](http://github.com/eggjs/egg/commit/3a941d669cc1d2c12a2caad4dd24492e98444348)] - ๐Ÿ‘Œ IMPROVE: Print warnning log when boot action takes more than 5000ms (#5049) (fengmk2 <>) - * [[`d820b739b`](http://github.com/eggjs/egg/commit/d820b739b95207bdea8c9b4c3da0f5059bc0113c)] - ๐Ÿ‘Œ IMPROVE: Don't need to patch keep-alive header on Node.js >= 14.20.0 (#5051) (fengmk2 <>) - * [[`6ac4cdbfb`](http://github.com/eggjs/egg/commit/6ac4cdbfbb35905f6f315f51122c1badcb913b5c)] - ๐Ÿค– TEST: Add Node.js 19 ci runner (#5050) (fengmk2 <>) - * [[`d05cc015e`](http://github.com/eggjs/egg/commit/d05cc015e4a748bf41a4dbf46e978d1f4ad44954)] - docs: fix Application description (#5044) (ldc-37 <<34739463+ldc-37@users.noreply.github.com>>) +- [[`2b5f289bb`](http://github.com/eggjs/egg/commit/2b5f289bba3bd14c2867136b5dcbf3bed5cfdf9e)] - ๐Ÿ“ฆ NEW: Use egg-cluster v2 (#5055) (fengmk2 <>) +- [[`610a39e7f`](http://github.com/eggjs/egg/commit/610a39e7f41a17a2123705691d6c1bfdc3e12f88)] - ๐Ÿ‘Œ IMPROVE: Drop httpclient callback and thunk style (#5052) (fengmk2 <>) +- [[`3a941d669`](http://github.com/eggjs/egg/commit/3a941d669cc1d2c12a2caad4dd24492e98444348)] - ๐Ÿ‘Œ IMPROVE: Print warnning log when boot action takes more than 5000ms (#5049) (fengmk2 <>) +- [[`d820b739b`](http://github.com/eggjs/egg/commit/d820b739b95207bdea8c9b4c3da0f5059bc0113c)] - ๐Ÿ‘Œ IMPROVE: Don't need to patch keep-alive header on Node.js >= 14.20.0 (#5051) (fengmk2 <>) +- [[`6ac4cdbfb`](http://github.com/eggjs/egg/commit/6ac4cdbfbb35905f6f315f51122c1badcb913b5c)] - ๐Ÿค– TEST: Add Node.js 19 ci runner (#5050) (fengmk2 <>) +- [[`d05cc015e`](http://github.com/eggjs/egg/commit/d05cc015e4a748bf41a4dbf46e978d1f4ad44954)] - docs: fix Application description (#5044) (ldc-37 <<34739463+ldc-37@users.noreply.github.com>>) ## 2022-09-28, Version 3.3.3 @fengmk2 ### Notable Changes -* **fixes** - * Allow override HttpClientNext +- **fixes** + - Allow override HttpClientNext ### Commits - * [[`7ee19e840`](http://github.com/eggjs/egg/commit/7ee19e8402b1d23ecdc1791e044a1902049e14dd)] - ๐Ÿ› FIX: Allow override HttpClientNext (#5037) (fengmk2 <>) + +- [[`7ee19e840`](http://github.com/eggjs/egg/commit/7ee19e8402b1d23ecdc1791e044a1902049e14dd)] - ๐Ÿ› FIX: Allow override HttpClientNext (#5037) (fengmk2 <>) ## 2022-09-27, Version 3.3.2 @atian25 ### Notable Changes -* **fixes** - * update multipart 3.1.0, https://github.com/eggjs/egg-multipart/pull/56 +- **fixes** + - update multipart 3.1.0, https://github.com/eggjs/egg-multipart/pull/56 ### Commits - * [[`201bfa749`](http://github.com/eggjs/egg/commit/201bfa7492920aafad71b7845e5cc6eaef69f8bc)] - fix: update multipart 3.1.0 (#5034) (TZ | ๅคฉ็Œช <>) +- [[`201bfa749`](http://github.com/eggjs/egg/commit/201bfa7492920aafad71b7845e5cc6eaef69f8bc)] - fix: update multipart 3.1.0 (#5034) (TZ | ๅคฉ็Œช <>) ## 2022-09-26, Version 3.3.1 @fengmk2 ### Notable Changes -* **fixes** - * fallback egg-multipart@2 to support filename with non-ASCII characters -### Commits +- **fixes** + - fallback egg-multipart@2 to support filename with non-ASCII characters - * [[`acadb28e2`](http://github.com/eggjs/egg/commit/acadb28e2814b0b91828e0766673f199d7767f3a)] - fix: fallback egg-multipart to v2 (#5032) (fengmk2 <>) +### Commits +- [[`acadb28e2`](http://github.com/eggjs/egg/commit/acadb28e2814b0b91828e0766673f199d7767f3a)] - fix: fallback egg-multipart to v2 (#5032) (fengmk2 <>) ## 2022-09-23, Version 3.3.0 @fengmk2 ### Notable Changes -* **features** - * Support config `serverGracefulIgnoreCode` to ignore error avoid process exit when uncatch error emit - See https://github.com/node-modules/graceful/pull/13 +- **features** + - Support config `serverGracefulIgnoreCode` to ignore error avoid process exit when uncatch error emit + See https://github.com/node-modules/graceful/pull/13 + ### Commits - * [[`a0761d65f`](http://github.com/eggjs/egg/commit/a0761d65f5df1002853c169efedab969636247d3)] - feat(graceful): support serverGracefulIgnoreCode (#5027) (hyj1991 <>) - * [[`8b8dd3be9`](http://github.com/eggjs/egg/commit/8b8dd3be95bb53ad3c732b8bc9c20566021e955f)] - chore: remove jsdoc and disable vercel comment (#5026) (Suyi <>) - * [[`f4225339f`](http://github.com/eggjs/egg/commit/f4225339f6235f78fe53d34d1eb0993faa410b36)] - test: fix ci (#5025) (TZ | ๅคฉ็Œช <>) - * [[`5de994b9c`](http://github.com/eggjs/egg/commit/5de994b9c4cd17f9ecd4d4083c20b29f399a9e40)] - chore: fix action for gh-pages (#5024) (Suyi <>) +- [[`a0761d65f`](http://github.com/eggjs/egg/commit/a0761d65f5df1002853c169efedab969636247d3)] - feat(graceful): support serverGracefulIgnoreCode (#5027) (hyj1991 <>) +- [[`8b8dd3be9`](http://github.com/eggjs/egg/commit/8b8dd3be95bb53ad3c732b8bc9c20566021e955f)] - chore: remove jsdoc and disable vercel comment (#5026) (Suyi <>) +- [[`f4225339f`](http://github.com/eggjs/egg/commit/f4225339f6235f78fe53d34d1eb0993faa410b36)] - test: fix ci (#5025) (TZ | ๅคฉ็Œช <>) +- [[`5de994b9c`](http://github.com/eggjs/egg/commit/5de994b9c4cd17f9ecd4d4083c20b29f399a9e40)] - chore: fix action for gh-pages (#5024) (Suyi <>) ## 2022-09-21, Version 3.2.0 @fengmk2 ### Notable Changes **features** - * [[`733d66989`](http://github.com/eggjs/egg/commit/733d66989d1f8657ce55b6032944188da635b8f0)] - feat: update egg-multipart 2.x -> 3.x (#5023) (TZ | ๅคฉ็Œช <>) - * [[`2ffb37ab5`](http://github.com/eggjs/egg/commit/2ffb37ab59395c9b14f153f91abb9f816a5e98ea)] - feat: Support urllib@3 (#5000) (fengmk2 <>) + +- [[`733d66989`](http://github.com/eggjs/egg/commit/733d66989d1f8657ce55b6032944188da635b8f0)] - feat: update egg-multipart 2.x -> 3.x (#5023) (TZ | ๅคฉ็Œช <>) +- [[`2ffb37ab5`](http://github.com/eggjs/egg/commit/2ffb37ab59395c9b14f153f91abb9f816a5e98ea)] - feat: Support urllib@3 (#5000) (fengmk2 <>) **others** - * [[`485781389`](http://github.com/eggjs/egg/commit/485781389e548ff0cf1eb107fea93c1bb01170d7)] - docs: update the version of the required Node (#5021) (Maledong <>) - * [[`bbd0e432e`](http://github.com/eggjs/egg/commit/bbd0e432e52832cc7a3d4b26a0141d7eb02e3793)] - chore: change the templates of bug/suggestion report (#5019) (Maledong <>) - * [[`2c5ba484a`](http://github.com/eggjs/egg/commit/2c5ba484a2dd8f214b9cdb53aa952688bc54cb2b)] - ๐Ÿ› FIX: Add config.httpclient.useHttpClientNext defined (#5001) (fengmk2 <>) + +- [[`485781389`](http://github.com/eggjs/egg/commit/485781389e548ff0cf1eb107fea93c1bb01170d7)] - docs: update the version of the required Node (#5021) (Maledong <>) +- [[`bbd0e432e`](http://github.com/eggjs/egg/commit/bbd0e432e52832cc7a3d4b26a0141d7eb02e3793)] - chore: change the templates of bug/suggestion report (#5019) (Maledong <>) +- [[`2c5ba484a`](http://github.com/eggjs/egg/commit/2c5ba484a2dd8f214b9cdb53aa952688bc54cb2b)] - ๐Ÿ› FIX: Add config.httpclient.useHttpClientNext defined (#5001) (fengmk2 <>) ## 2022-08-28, Version 3.1.0 @fengmk2 ### Notable Changes -* **features** - * Support urllib@3 by `config.httpclient.useHttpClientNext = true`, see [#4847](https://github.com/eggjs/egg/issues/4847) +- **features** + - Support urllib@3 by `config.httpclient.useHttpClientNext = true`, see [#4847](https://github.com/eggjs/egg/issues/4847) ### Commits - * [[`2c5ba484a`](http://github.com/eggjs/egg/commit/2c5ba484a2dd8f214b9cdb53aa952688bc54cb2b)] - ๐Ÿ› FIX: Add config.httpclient.useHttpClientNext defined (#5001) (fengmk2 <>) - * [[`2ffb37ab5`](http://github.com/eggjs/egg/commit/2ffb37ab59395c9b14f153f91abb9f816a5e98ea)] - feat: Support urllib@3 (#5000) (fengmk2 <>) + +- [[`2c5ba484a`](http://github.com/eggjs/egg/commit/2c5ba484a2dd8f214b9cdb53aa952688bc54cb2b)] - ๐Ÿ› FIX: Add config.httpclient.useHttpClientNext defined (#5001) (fengmk2 <>) +- [[`2ffb37ab5`](http://github.com/eggjs/egg/commit/2ffb37ab59395c9b14f153f91abb9f816a5e98ea)] - feat: Support urllib@3 (#5000) (fengmk2 <>) ## 2022-08-21, Version 3.0.0 @fengmk2 **features** - * Drop Node.js 8, 10, 12 supports, this release is a LTS version for egg@2, see https://github.com/eggjs/egg/issues/3644#issuecomment-1221460692 + +- Drop Node.js 8, 10, 12 supports, this release is a LTS version for egg@2, see https://github.com/eggjs/egg/issues/3644#issuecomment-1221460692 ## 2022-06-17, Version 2.36.0 @atian25 **features** - * [[`e0b93e023`](http://github.com/eggjs/egg/commit/e0b93e023e1258c4037c68dacfc41fc304602bbc)] - feat: should log unfinished timing item (#4968) (TZ | ๅคฉ็Œช <>) + +- [[`e0b93e023`](http://github.com/eggjs/egg/commit/e0b93e023e1258c4037c68dacfc41fc304602bbc)] - feat: should log unfinished timing item (#4968) (TZ | ๅคฉ็Œช <>) **others** - * [[`7f1689f9f`](http://github.com/eggjs/egg/commit/7f1689f9fbd286bde3b8b5aebf86af09a599359c)] - chore: typo CSRF on router.md (#4962) (Homyee King <>) - * [[`e31c09c20`](http://github.com/eggjs/egg/commit/e31c09c2001b15fbc2431f4c36f6e59da5e3ebca)] - chore: fix some comments (#4937) (Maledong <>) - * [[`b0c17fdd0`](http://github.com/eggjs/egg/commit/b0c17fdd02512f743786203c326dc86be636f9a6)] - chore: remove git.io (#4940) (Baoshuo Ren <>) - * [[`12755e275`](http://github.com/eggjs/egg/commit/12755e27555b8f84a745c319c89b1c4d75ae3f78)] - test: Create codeql-analysis.yml (#4935) (fengmk2 <>) - * [[`8078917fd`](http://github.com/eggjs/egg/commit/8078917fd66c41d21b0f2c738f77cc7916edfaca)] - chore: package upgrade and unittest fixture (#4933) (Maledong <>) - * [[`a5a358ceb`](http://github.com/eggjs/egg/commit/a5a358cebc78734d45a450a641913ae242c5dc70)] - chore: fix contributors badges on README.md (#4930) (XiaoRui <>) + +- [[`7f1689f9f`](http://github.com/eggjs/egg/commit/7f1689f9fbd286bde3b8b5aebf86af09a599359c)] - chore: typo CSRF on router.md (#4962) (Homyee King <>) +- [[`e31c09c20`](http://github.com/eggjs/egg/commit/e31c09c2001b15fbc2431f4c36f6e59da5e3ebca)] - chore: fix some comments (#4937) (Maledong <>) +- [[`b0c17fdd0`](http://github.com/eggjs/egg/commit/b0c17fdd02512f743786203c326dc86be636f9a6)] - chore: remove git.io (#4940) (Baoshuo Ren <>) +- [[`12755e275`](http://github.com/eggjs/egg/commit/12755e27555b8f84a745c319c89b1c4d75ae3f78)] - test: Create codeql-analysis.yml (#4935) (fengmk2 <>) +- [[`8078917fd`](http://github.com/eggjs/egg/commit/8078917fd66c41d21b0f2c738f77cc7916edfaca)] - chore: package upgrade and unittest fixture (#4933) (Maledong <>) +- [[`a5a358ceb`](http://github.com/eggjs/egg/commit/a5a358cebc78734d45a450a641913ae242c5dc70)] - chore: fix contributors badges on README.md (#4930) (XiaoRui <>) ## 2022-04-01, Version 2.35.0 @mansonchor **features** - * [[`c1313f5ef`](http://github.com/eggjs/egg/commit/c1313f5ef960e5aaad7f04adb6665679f2ec10e2)] - feat: dumpConfig add appInfo (#4917) (mansonchor.github.com <>) + +- [[`c1313f5ef`](http://github.com/eggjs/egg/commit/c1313f5ef960e5aaad7f04adb6665679f2ec10e2)] - feat: dumpConfig add appInfo (#4917) (mansonchor.github.com <>) **others** - * [[`4e5309188`](http://github.com/eggjs/egg/commit/4e5309188a60393435d5ab2df65ca67186f31035)] - test: add ChainAlert action (#4908) (fengmk2 <>) + +- [[`4e5309188`](http://github.com/eggjs/egg/commit/4e5309188a60393435d5ab2df65ca67186f31035)] - test: add ChainAlert action (#4908) (fengmk2 <>) ## 2022-03-16, Version 2.34.0 **features** - * [[`caacd09c3`](http://github.com/eggjs/egg/commit/caacd09c38aae03fc291febbb97a43c8ecbdc221)] - feat: siteFile support custom control-cache (#4902) (binginsist <>) + +- [[`caacd09c3`](http://github.com/eggjs/egg/commit/caacd09c38aae03fc291febbb97a43c8ecbdc221)] - feat: siteFile support custom control-cache (#4902) (binginsist <>) **others** - * [[`f97fe4a8c`](http://github.com/eggjs/egg/commit/f97fe4a8c8c0b5f8c097055213f9e7177b9ab2dd)] - test: change error code assert (#4907) (fengmk2 <>) - * [[`a7aa7f37d`](http://github.com/eggjs/egg/commit/a7aa7f37d901afd4c26a2a9aa57fe938b2109e94)] - docs: typo fix on deployment.zh-CN.md (#4906) (Krryxa <>) - * [[`d3fe13aa2`](http://github.com/eggjs/egg/commit/d3fe13aa25065995cfa9d78461be80194176f183)] - docs: typo fix on security.zh-CN.md (#4905) (Krryxa <>) - * [[`2dc723129`](http://github.com/eggjs/egg/commit/2dc723129614bd727e86871ae3e7cfc60166dd81)] - docs: use egg brand color for site (#4900) (Peach <>) - * [[`11bbd8527`](http://github.com/eggjs/egg/commit/11bbd852731b1583cae5a5d519baa20960c0521d)] - docs: enhance (#4884) (Suyi <>) - * [[`76d014bd5`](http://github.com/eggjs/egg/commit/76d014bd583c6d0b9b9f40ac2e6e7ba9dd66e8ed)] - docs: update node version (#4886) (lxinr <<33972246+lxinr@users.noreply.github.com>>) - * [[`9003cb5ad`](http://github.com/eggjs/egg/commit/9003cb5ad370d0c07b2baee88f3b25c597ac3929)] - docs: update https://registry.npm.taobao.org to https://registry.npmmirror.com (#4881) (Non-Official NPM Mirror Bot <<99484857+npmmirror@users.noreply.github.com>>) - * [[`b47409770`](http://github.com/eggjs/egg/commit/b47409770d76f03eb1ea0476be9e00207186c42e)] - docs: dumi (#4879) (Suyi <>) - * [[`56816dbc5`](http://github.com/eggjs/egg/commit/56816dbc59dbb1a4973ca60130c9ff3f5be8b2da)] - docs (sequelize): Changed `config.sequelize` to `exports.sequelize` in configuration part (#4873) (Aelita <<45784210+xsjcTony@users.noreply.github.com>>) - * [[`20842f9c2`](http://github.com/eggjs/egg/commit/20842f9c216ed538924936163b7ed18437c54cd7)] - docs: Add license scan report and status (#4880) (fossabot <>) + +- [[`f97fe4a8c`](http://github.com/eggjs/egg/commit/f97fe4a8c8c0b5f8c097055213f9e7177b9ab2dd)] - test: change error code assert (#4907) (fengmk2 <>) +- [[`a7aa7f37d`](http://github.com/eggjs/egg/commit/a7aa7f37d901afd4c26a2a9aa57fe938b2109e94)] - docs: typo fix on deployment.zh-CN.md (#4906) (Krryxa <>) +- [[`d3fe13aa2`](http://github.com/eggjs/egg/commit/d3fe13aa25065995cfa9d78461be80194176f183)] - docs: typo fix on security.zh-CN.md (#4905) (Krryxa <>) +- [[`2dc723129`](http://github.com/eggjs/egg/commit/2dc723129614bd727e86871ae3e7cfc60166dd81)] - docs: use egg brand color for site (#4900) (Peach <>) +- [[`11bbd8527`](http://github.com/eggjs/egg/commit/11bbd852731b1583cae5a5d519baa20960c0521d)] - docs: enhance (#4884) (Suyi <>) +- [[`76d014bd5`](http://github.com/eggjs/egg/commit/76d014bd583c6d0b9b9f40ac2e6e7ba9dd66e8ed)] - docs: update node version (#4886) (lxinr <<33972246+lxinr@users.noreply.github.com>>) +- [[`9003cb5ad`](http://github.com/eggjs/egg/commit/9003cb5ad370d0c07b2baee88f3b25c597ac3929)] - docs: update https://registry.npm.taobao.org to https://registry.npmmirror.com (#4881) (Non-Official NPM Mirror Bot <<99484857+npmmirror@users.noreply.github.com>>) +- [[`b47409770`](http://github.com/eggjs/egg/commit/b47409770d76f03eb1ea0476be9e00207186c42e)] - docs: dumi (#4879) (Suyi <>) +- [[`56816dbc5`](http://github.com/eggjs/egg/commit/56816dbc59dbb1a4973ca60130c9ff3f5be8b2da)] - docs (sequelize): Changed `config.sequelize` to `exports.sequelize` in configuration part (#4873) (Aelita <<45784210+xsjcTony@users.noreply.github.com>>) +- [[`20842f9c2`](http://github.com/eggjs/egg/commit/20842f9c216ed538924936163b7ed18437c54cd7)] - docs: Add license scan report and status (#4880) (fossabot <>) ## 2021-12-07, Version 2.33.1 **features** - * [[`18dcadc1c`](http://github.com/eggjs/egg/commit/18dcadc1cf6c9837de605916a0d8b161a63e7218)] - feat: meta middleware x-readtime support performanceStarttime (#4827) (fengmk2 <>) + +- [[`18dcadc1c`](http://github.com/eggjs/egg/commit/18dcadc1cf6c9837de605916a0d8b161a63e7218)] - feat: meta middleware x-readtime support performanceStarttime (#4827) (fengmk2 <>) **others** - * [[`8659d4bc3`](http://github.com/eggjs/egg/commit/8659d4bc37e0652d66d04d2e5504fdc0ef2f7f7d)] - docs: update contributors (#4826) (Suyi <>) - * [[`4d18732c7`](http://github.com/eggjs/egg/commit/4d18732c79e44a84140df05e879b8b5f569c2b4b)] - chore: remove @types/urllib from autod (fengmk2 <>) + +- [[`8659d4bc3`](http://github.com/eggjs/egg/commit/8659d4bc37e0652d66d04d2e5504fdc0ef2f7f7d)] - docs: update contributors (#4826) (Suyi <>) +- [[`4d18732c7`](http://github.com/eggjs/egg/commit/4d18732c79e44a84140df05e879b8b5f569c2b4b)] - chore: remove @types/urllib from autod (fengmk2 <>) ## 2021-12-06, Version 2.33.0 **features** - * [[`0f6589e1d`](http://github.com/eggjs/egg/commit/0f6589e1dc9e538434eb1580327556d5aa264822)] - feat: support better logger timer in precise milliseconds (#4806) (fengmk2 <>) + +- [[`0f6589e1d`](http://github.com/eggjs/egg/commit/0f6589e1dc9e538434eb1580327556d5aa264822)] - feat: support better logger timer in precise milliseconds (#4806) (fengmk2 <>) ## 2021-11-15, Version 2.32.0 @atian25 ### Notable Changes -* **features** - * handle ENETUNREACH error on httpclient +- **features** + - handle ENETUNREACH error on httpclient ### Commits - * [[`189c47804`](http://github.com/eggjs/egg/commit/189c478048d820b7b1a6ba6e8bce3444604876ff)] - feat: handle ENETUNREACH error on httpclient (#4792) (fengmk2 <>) - +- [[`189c47804`](http://github.com/eggjs/egg/commit/189c478048d820b7b1a6ba6e8bce3444604876ff)] - feat: handle ENETUNREACH error on httpclient (#4792) (fengmk2 <>) ## 2021-10-18, Version 2.31.0 @killagu ### Notable Changes -* **typing** - * support ssrf typing in config +- **typing** + - support ssrf typing in config ### Commits -* [[`debfda7ab`](https://github.com/eggjs/egg/commit/debfda7ab38f4893b6f122abfbf3e5288af1441e)] - feat(config): support ssrf field in security config. (#4778) (Jasin Yip <>) +- [[`debfda7ab`](https://github.com/eggjs/egg/commit/debfda7ab38f4893b6f122abfbf3e5288af1441e)] - feat(config): support ssrf field in security config. (#4778) (Jasin Yip <>) ## 2021-08-09, Version 2.30.0 @mansonchor ### Notable Changes -* **features** - * support disableDNSCache in one request even though config set to `enableDNSCache: true` +- **features** + - support disableDNSCache in one request even though config set to `enableDNSCache: true` -* **docs** - * update ts docs, add missing zh-CN doc - * typo fix +- **docs** + - update ts docs, add missing zh-CN doc + - typo fix ### Commits - * [[`13dd55076`](https://github.com/eggjs/egg.git/commit/13dd5507694a57a11e12d1ac6f71ba4a562d88c0)] - feat: support disableDNSCache by request args handle (#4728) (mansonchor.github.com <>) - * [[`1b4fde454`](https://github.com/eggjs/egg.git/commit/1b4fde454d2d61200a8b066ba841ad6d81b5b69d)] - unittest: rename and remove some useless tests (#4705) (Maledong <>) - * [[`156980d36`](https://github.com/eggjs/egg.git/commit/156980d369570531c1ef9cf842f02f513b56fe4a)] - doc: Typo fixture (#4707) (Maledong <>) - * [[`27aa49b59`](https://github.com/eggjs/egg.git/commit/27aa49b5945f08fa6b636479cf4cba7822e3af2d)] - doc: Typo fixture:ใ€Œ,ใ€->ใ€Œ๏ผŒใ€ (#4708) (้™ˆ็…ฎ้…’ <<501205587@qq.com>>) - * [[`1f02a8d45`](https://github.com/eggjs/egg.git/commit/1f02a8d4560ca3334425e646c1ac87226aba3a63)] - doc: Add the missing zh-CN trans for typescript (#4703) (Maledong <<52018749+MaledongGit@users.noreply.github.com>>) - * [[`f5cf0d965`](https://github.com/eggjs/egg.git/commit/f5cf0d965fa4077da10e87f070e113496077872c)] - doc: "็™ป้™†" should be "็™ปๅฝ•" (#4697) (HOU Ce <<594965698@qq.com>>) - * [[`750558400`](https://github.com/eggjs/egg.git/commit/750558400e3bd5f39658dfcbedd4af7bc0bdda2a)] - docs: update ts docs (#4666) (ๅ–็Œฉ <>) - * [[`93d2b04b9`](https://github.com/eggjs/egg.git/commit/93d2b04b985145f27a39335300a78002a61da2a8)] - docs: fix loaderUpdate.md didReady example (#4652) (shadyzoz <>) +- [[`13dd55076`](https://github.com/eggjs/egg.git/commit/13dd5507694a57a11e12d1ac6f71ba4a562d88c0)] - feat: support disableDNSCache by request args handle (#4728) (mansonchor.github.com <>) +- [[`1b4fde454`](https://github.com/eggjs/egg.git/commit/1b4fde454d2d61200a8b066ba841ad6d81b5b69d)] - unittest: rename and remove some useless tests (#4705) (Maledong <>) +- [[`156980d36`](https://github.com/eggjs/egg.git/commit/156980d369570531c1ef9cf842f02f513b56fe4a)] - doc: Typo fixture (#4707) (Maledong <>) +- [[`27aa49b59`](https://github.com/eggjs/egg.git/commit/27aa49b5945f08fa6b636479cf4cba7822e3af2d)] - doc: Typo fixture:ใ€Œ,ใ€->ใ€Œ๏ผŒใ€ (#4708) (้™ˆ็…ฎ้…’ <<501205587@qq.com>>) +- [[`1f02a8d45`](https://github.com/eggjs/egg.git/commit/1f02a8d4560ca3334425e646c1ac87226aba3a63)] - doc: Add the missing zh-CN trans for typescript (#4703) (Maledong <<52018749+MaledongGit@users.noreply.github.com>>) +- [[`f5cf0d965`](https://github.com/eggjs/egg.git/commit/f5cf0d965fa4077da10e87f070e113496077872c)] - doc: "็™ป้™†" should be "็™ปๅฝ•" (#4697) (HOU Ce <<594965698@qq.com>>) +- [[`750558400`](https://github.com/eggjs/egg.git/commit/750558400e3bd5f39658dfcbedd4af7bc0bdda2a)] - docs: update ts docs (#4666) (ๅ–็Œฉ <>) +- [[`93d2b04b9`](https://github.com/eggjs/egg.git/commit/93d2b04b985145f27a39335300a78002a61da2a8)] - docs: fix loaderUpdate.md didReady example (#4652) (shadyzoz <>) ## 2021-04-13, Version 2.29.4 @popomore ### Notable Changes -* **fixes** - * remove internal interval handler when close agent -* **docs** - * Added english doc to how-to-migrate-from-1.x, Thx @ZixiaoWang - * typo improvement +- **fixes** + - remove internal interval handler when close agent +- **docs** + - Added english doc to how-to-migrate-from-1.x, Thx @ZixiaoWang + - typo improvement ### Commits - * [[`ce234226b`](http://github.com/eggjs/egg/commit/ce234226bf0c43f03aedf727a7d195ae4175c01f)] - fix: remove internal interval handler when close agent (#4654) (Harry Chen <>) - * [[`6a6d68fb2`](http://github.com/eggjs/egg/commit/6a6d68fb228a3eae9b5cab3ba7afe0892d5e08ea)] - Typo fixture๏ผšๅˆถๅฎš -> ๆŒ‡ๅฎš (#4639) (ๅŽๆ™จ <>) - * [[`603c74b58`](http://github.com/eggjs/egg/commit/603c74b581d6b3a9ad80170335425b0876ffcb1f)] - docs: Added english doc to how-to-migrate-from-1.x (#4630) (Jacky Wang <>) - * [[`693df6066`](http://github.com/eggjs/egg/commit/693df60661735008e8a758258fc2df0bb9783f04)] - docs: fix schedule reference (#4556) (xuxu <>) - * [[`4ebbe8143`](http://github.com/eggjs/egg/commit/4ebbe814386102377870959129e831a3b20133c1)] - docs: fix typo (#4596) (suinia <>) +- [[`ce234226b`](http://github.com/eggjs/egg/commit/ce234226bf0c43f03aedf727a7d195ae4175c01f)] - fix: remove internal interval handler when close agent (#4654) (Harry Chen <>) +- [[`6a6d68fb2`](http://github.com/eggjs/egg/commit/6a6d68fb228a3eae9b5cab3ba7afe0892d5e08ea)] - Typo fixture๏ผšๅˆถๅฎš -> ๆŒ‡ๅฎš (#4639) (ๅŽๆ™จ <>) +- [[`603c74b58`](http://github.com/eggjs/egg/commit/603c74b581d6b3a9ad80170335425b0876ffcb1f)] - docs: Added english doc to how-to-migrate-from-1.x (#4630) (Jacky Wang <>) +- [[`693df6066`](http://github.com/eggjs/egg/commit/693df60661735008e8a758258fc2df0bb9783f04)] - docs: fix schedule reference (#4556) (xuxu <>) +- [[`4ebbe8143`](http://github.com/eggjs/egg/commit/4ebbe814386102377870959129e831a3b20133c1)] - docs: fix typo (#4596) (suinia <>) ## 2021-02-19, Version 2.29.3 @killa ### Notable Changes -* **fixes** - * fix ctx body typing +- **fixes** + - fix ctx body typing ### Commits - * [[`e9fba1b7b`](http://github.com/eggjs/egg/commit/e9fba1b7bbe3f54b023262aeb5487b31047e119e)] - fix: fix ctx body as any (#4613) (killa <>) + +- [[`e9fba1b7b`](http://github.com/eggjs/egg/commit/e9fba1b7bbe3f54b023262aeb5487b31047e119e)] - fix: fix ctx body as any (#4613) (killa <>) ## 2021-02-18, Version 2.29.2 @killa ### Notable Changes -* **fixes** - * fix query typing - * add overrideIgnore define +- **fixes** + - fix query typing + - add overrideIgnore define ### Commits - * [[`99682e4bd`](http://github.com/eggjs/egg/commit/99682e4bd5afe1697cab02001e919b967c264869)] - fix: fix query typing (#4611) (killa <>) - * [[`26017ee2e`](http://github.com/eggjs/egg/commit/26017ee2e49bd8a42b660baabe31284e00f81bcb)] - chore: fix comment typo at request.js (#4513) (Albert ็†ๆ–ฏ็‰น <>) - * [[`34048c275`](http://github.com/eggjs/egg/commit/34048c275afe1126716ef4265b667169e9866e53)] - fix: add overrideIgnore define (#4490) (kotot <<317643941@qq.com>>) - * [[`d652658d1`](http://github.com/eggjs/egg/commit/d652658d1205d0fbc73b4417c2ae54ee0a24f395)] - docs: d2 ads (#4508) (Suyi <>) +- [[`99682e4bd`](http://github.com/eggjs/egg/commit/99682e4bd5afe1697cab02001e919b967c264869)] - fix: fix query typing (#4611) (killa <>) +- [[`26017ee2e`](http://github.com/eggjs/egg/commit/26017ee2e49bd8a42b660baabe31284e00f81bcb)] - chore: fix comment typo at request.js (#4513) (Albert ็†ๆ–ฏ็‰น <>) +- [[`34048c275`](http://github.com/eggjs/egg/commit/34048c275afe1126716ef4265b667169e9866e53)] - fix: add overrideIgnore define (#4490) (kotot <<317643941@qq.com>>) +- [[`d652658d1`](http://github.com/eggjs/egg/commit/d652658d1205d0fbc73b4417c2ae54ee0a24f395)] - docs: d2 ads (#4508) (Suyi <>) ## 2020-10-19, Version 2.29.1 @atian25 ### Notable Changes -* **fixes** - * revert clear timing after ready, only disable - * won't set keep-alive header at Node.js ^12.19.0 || >=14.8.0 +- **fixes** + - revert clear timing after ready, only disable + - won't set keep-alive header at Node.js ^12.19.0 || >=14.8.0 ### Commits - * [[`9f653afe7`](http://github.com/eggjs/egg/commit/9f653afe790e0ead44109c68dfffb8353fdca56c)] - fix: remove clear timing && skip keep-alive after 12.19.0 (#4497) (TZ | ๅคฉ็Œช <>) - +- [[`9f653afe7`](http://github.com/eggjs/egg/commit/9f653afe790e0ead44109c68dfffb8353fdca56c)] - fix: remove clear timing && skip keep-alive after 12.19.0 (#4497) (TZ | ๅคฉ็Œช <>) ## 2020-09-23, Version 2.29.0 @atian25 ### Notable Changes -* **features** - * dumpconfig also dump disabled plugin +- **features** + - dumpconfig also dump disabled plugin -* **docs** - * csrf double cookie defense should enabled on all method - * test case for env.EGG_APP_CONFIG - * optimize multiple env configuration description +- **docs** + - csrf double cookie defense should enabled on all method + - test case for env.EGG_APP_CONFIG + - optimize multiple env configuration description ### Commits - * [[`cc80c6ab8`](http://github.com/eggjs/egg/commit/cc80c6ab86c71b1c9ea244065d4766297bfb6c17)] - feat: dumpconfig also dump disabled plugin (#4480) (TZ | ๅคฉ็Œช <>) - * [[`1d32771e5`](http://github.com/eggjs/egg/commit/1d32771e5aeb8fa8546ad8bfacf2f438973afae0)] - doc: csrf double cookie defense should enabled on all method (#3881) (Hongcai Deng <>) - * [[`504e4bebc`](http://github.com/eggjs/egg/commit/504e4bebcef03830be7c7432210b5b6b1de9d06b)] - test: for env.EGG_APP_CONFIG (#4468) (TZ | ๅคฉ็Œช <>) - * [[`ff4dfaa09`](http://github.com/eggjs/egg/commit/ff4dfaa098ad40ab7a0773c44d409829fcbb0e41)] - docs(config): optimize multiple env configuration description (#4406) (Andy <>) - * [[`b283791da`](http://github.com/eggjs/egg/commit/b283791dab3c86beb14506668e2aa3ef21cb78e6)] - docs: update badge to github action (#4463) (TZ | ๅคฉ็Œช <>) - +- [[`cc80c6ab8`](http://github.com/eggjs/egg/commit/cc80c6ab86c71b1c9ea244065d4766297bfb6c17)] - feat: dumpconfig also dump disabled plugin (#4480) (TZ | ๅคฉ็Œช <>) +- [[`1d32771e5`](http://github.com/eggjs/egg/commit/1d32771e5aeb8fa8546ad8bfacf2f438973afae0)] - doc: csrf double cookie defense should enabled on all method (#3881) (Hongcai Deng <>) +- [[`504e4bebc`](http://github.com/eggjs/egg/commit/504e4bebcef03830be7c7432210b5b6b1de9d06b)] - test: for env.EGG_APP_CONFIG (#4468) (TZ | ๅคฉ็Œช <>) +- [[`ff4dfaa09`](http://github.com/eggjs/egg/commit/ff4dfaa098ad40ab7a0773c44d409829fcbb0e41)] - docs(config): optimize multiple env configuration description (#4406) (Andy <>) +- [[`b283791da`](http://github.com/eggjs/egg/commit/b283791dab3c86beb14506668e2aa3ef21cb78e6)] - docs: update badge to github action (#4463) (TZ | ๅคฉ็Œช <>) ## 2020-09-08, Version 2.28.0 @atian25 ### Notable Changes -* **features** - * clear & disable timing after ready +- **features** + - clear & disable timing after ready -* **fixes** - * only set keep-alive header before Node.js 14.8.0 +- **fixes** + - only set keep-alive header before Node.js 14.8.0 -* **typings** - * Added missing types in HttpClientConfig - * export EggLogger/EggHttpClient/EggContextHttpClient +- **typings** + - Added missing types in HttpClientConfig + - export EggLogger/EggHttpClient/EggContextHttpClient -* **docs** - * fixed grammatical and spelling errors - * update compress url +- **docs** + - fixed grammatical and spelling errors + - update compress url ### Commits - * [[`b31b47df1`](http://github.com/eggjs/egg/commit/b31b47df10722bfac7ac13771db534f0200fc6ce)] - feat: clear & disable timing after ready (#4421) (TZ | ๅคฉ็Œช <>) - * [[`d25d32e58`](http://github.com/eggjs/egg/commit/d25d32e584b0bfd80f21cc522b91ac465f2852ac)] - fix: only set keep-alive header before Node.js 14.8.0 (#4457) (TZ | ๅคฉ็Œช <>) - * [[`a7ae46c84`](http://github.com/eggjs/egg/commit/a7ae46c847db07c0c4af1a85173bc4009d1219d9)] - type: Added missing types in HttpClientConfig (#4388) (Gcaufy <>) - * [[`064cc7a91`](http://github.com/eggjs/egg/commit/064cc7a91a2be89e39d72a833a1cb35cdcd8f201)] - docs: fixed grammatical and spelling errors (#4424) (Hridayesh Sharma <>) - * [[`95776d646`](http://github.com/eggjs/egg/commit/95776d6462080448e946c049f9ad4da4e9fc065e)] - docs: fix spelling mistakes and grammatical errors (#4423) (Hridayesh Sharma <>) - * [[`50976280f`](http://github.com/eggjs/egg/commit/50976280fcb19ce556ddc46f76da1f5fab46fa4a)] - docs: update compress url (#4415) (ๅฟฝๅฆ‚ๅฏ„ <<594613537@qq.com>>) +- [[`b31b47df1`](http://github.com/eggjs/egg/commit/b31b47df10722bfac7ac13771db534f0200fc6ce)] - feat: clear & disable timing after ready (#4421) (TZ | ๅคฉ็Œช <>) +- [[`d25d32e58`](http://github.com/eggjs/egg/commit/d25d32e584b0bfd80f21cc522b91ac465f2852ac)] - fix: only set keep-alive header before Node.js 14.8.0 (#4457) (TZ | ๅคฉ็Œช <>) +- [[`a7ae46c84`](http://github.com/eggjs/egg/commit/a7ae46c847db07c0c4af1a85173bc4009d1219d9)] - type: Added missing types in HttpClientConfig (#4388) (Gcaufy <>) +- [[`064cc7a91`](http://github.com/eggjs/egg/commit/064cc7a91a2be89e39d72a833a1cb35cdcd8f201)] - docs: fixed grammatical and spelling errors (#4424) (Hridayesh Sharma <>) +- [[`95776d646`](http://github.com/eggjs/egg/commit/95776d6462080448e946c049f9ad4da4e9fc065e)] - docs: fix spelling mistakes and grammatical errors (#4423) (Hridayesh Sharma <>) +- [[`50976280f`](http://github.com/eggjs/egg/commit/50976280fcb19ce556ddc46f76da1f5fab46fa4a)] - docs: update compress url (#4415) (ๅฟฝๅฆ‚ๅฏ„ <<594613537@qq.com>>) ## 2020-06-29, Version 2.27.0 @killa ### Notable Changes -* **typings** - * fix curl type - * export EggLogger/EggHttpClient/EggContextHttpClient +- **typings** + - fix curl type + - export EggLogger/EggHttpClient/EggContextHttpClient -* **docs** - * update docs about how to extends ctx.helper +- **docs** + - update docs about how to extends ctx.helper ### Commits - * [[`b5cc8b6e3`](http://github.com/eggjs/egg/commit/b5cc8b6e361b1ac2e7b4eb509f1e6486fe1dab13)] - fix(dts): fix curl type (#4312) (่ƒกๅฎ‡่ˆช <<591765099@qq.com>>) - * [[`432128a80`](http://github.com/eggjs/egg/commit/432128a80aefdc8d11a6571da1ff35550e85fd66)] - type: export EggLogger/EggHttpClient/EggContextHttpClient (#4280) (killa <>) - * [[`eca6b04c1`](http://github.com/eggjs/egg/commit/eca6b04c1c50bc69c53f9910cc35bb7441c7cb02)] - docs:update docs about how to extends ctx.helper (#4362) (EasonQwQ <<750225883@qq.com>>) - +- [[`b5cc8b6e3`](http://github.com/eggjs/egg/commit/b5cc8b6e361b1ac2e7b4eb509f1e6486fe1dab13)] - fix(dts): fix curl type (#4312) (่ƒกๅฎ‡่ˆช <<591765099@qq.com>>) +- [[`432128a80`](http://github.com/eggjs/egg/commit/432128a80aefdc8d11a6571da1ff35550e85fd66)] - type: export EggLogger/EggHttpClient/EggContextHttpClient (#4280) (killa <>) +- [[`eca6b04c1`](http://github.com/eggjs/egg/commit/eca6b04c1c50bc69c53f9910cc35bb7441c7cb02)] - docs:update docs about how to extends ctx.helper (#4362) (EasonQwQ <<750225883@qq.com>>) ## 2020-05-13, Version 2.26.1 @dead-horse ### Notable Changes -* **fixes** - * runInBackground always run after setImmediate +- **fixes** + - runInBackground always run after setImmediate -* **docs** - * imporve docs - * imporve typings +- **docs** + - imporve docs + - imporve typings ### Commits - * [[`9c67298d6`](http://github.com/eggjs/egg/commit/9c67298d69946d4ba0887c3648d3404e835c6902)] - test: run test on node 14 (#4272) (fengmk2 <>) - * [[`427a30a07`](http://github.com/eggjs/egg/commit/427a30a071d248cc2e5e15bb4bad35f3058e867f)] - test: make dnscache test case more stable (#4297) (Yiyu He <>) - * [[`64efd076b`](http://github.com/eggjs/egg/commit/64efd076bf9d937e36748f89bada6fce186913cd)] - fix: runInBackground always run after setImmediate (#4296) (Yiyu He <>) - * [[`69923977a`](http://github.com/eggjs/egg/commit/69923977a7e5c0825f2fc5c616852b0721411a0c)] - docs: Update doc for config of logger.consoleLevel (#4276) (xuxu <>) - * [[`7b6e4371c`](http://github.com/eggjs/egg/commit/7b6e4371c7367583627977a0ca4aa2ff66e28429)] - docs(typescript): Add --noEmit to unittest example code (#4250) (Ink <>) - * [[`3413e35fd`](http://github.com/eggjs/egg/commit/3413e35fd86408896e5c0b7e77ec2528ac08c9f9)] - chore: fix typo (#4234) (zoomdong <<1344492820@qq.com>>) - * [[`b4b9b50af`](http://github.com/eggjs/egg/commit/b4b9b50af1bb842e0138fc236d45882188698123)] - doc (socketio): fix packet middleware bug (#4204) (zfx <<502545703@qq.com>>) - * [[`2fcd605c6`](http://github.com/eggjs/egg/commit/2fcd605c6397480b0a5add9c11f7c7d071393de5)] - docs: update bodyParser types and doc (#4192) (sexy pig <<353071655@qq.com>>) - * [[`5e2bad0c4`](http://github.com/eggjs/egg/commit/5e2bad0c421952b7c84471df06d2ca80c20fa14c)] - docs: fix typo in router (#4203) (Xuemuyang <>) - * [[`1181a675c`](http://github.com/eggjs/egg/commit/1181a675cae08c2d6952b8c15a3a9375947e220b)] - docs(plugin): format en/basics/plugin.md (#4168) (chs97 <<623528324@qq.com>>) - * [[`e9011e8f3`](http://github.com/eggjs/egg/commit/e9011e8f332a97da7e6e112d0f1ded42f0b5db42)] - feat: add http method patch to typings (#4125) (xiaoxu <>) - * [[`2109505b4`](http://github.com/eggjs/egg/commit/2109505b40a159cd047075e566e9465b1ad5a365)] - test: fix doctools path on windows (#4090) (fengmk2 <>) - +- [[`9c67298d6`](http://github.com/eggjs/egg/commit/9c67298d69946d4ba0887c3648d3404e835c6902)] - test: run test on node 14 (#4272) (fengmk2 <>) +- [[`427a30a07`](http://github.com/eggjs/egg/commit/427a30a071d248cc2e5e15bb4bad35f3058e867f)] - test: make dnscache test case more stable (#4297) (Yiyu He <>) +- [[`64efd076b`](http://github.com/eggjs/egg/commit/64efd076bf9d937e36748f89bada6fce186913cd)] - fix: runInBackground always run after setImmediate (#4296) (Yiyu He <>) +- [[`69923977a`](http://github.com/eggjs/egg/commit/69923977a7e5c0825f2fc5c616852b0721411a0c)] - docs: Update doc for config of logger.consoleLevel (#4276) (xuxu <>) +- [[`7b6e4371c`](http://github.com/eggjs/egg/commit/7b6e4371c7367583627977a0ca4aa2ff66e28429)] - docs(typescript): Add --noEmit to unittest example code (#4250) (Ink <>) +- [[`3413e35fd`](http://github.com/eggjs/egg/commit/3413e35fd86408896e5c0b7e77ec2528ac08c9f9)] - chore: fix typo (#4234) (zoomdong <<1344492820@qq.com>>) +- [[`b4b9b50af`](http://github.com/eggjs/egg/commit/b4b9b50af1bb842e0138fc236d45882188698123)] - doc (socketio): fix packet middleware bug (#4204) (zfx <<502545703@qq.com>>) +- [[`2fcd605c6`](http://github.com/eggjs/egg/commit/2fcd605c6397480b0a5add9c11f7c7d071393de5)] - docs: update bodyParser types and doc (#4192) (sexy pig <<353071655@qq.com>>) +- [[`5e2bad0c4`](http://github.com/eggjs/egg/commit/5e2bad0c421952b7c84471df06d2ca80c20fa14c)] - docs: fix typo in router (#4203) (Xuemuyang <>) +- [[`1181a675c`](http://github.com/eggjs/egg/commit/1181a675cae08c2d6952b8c15a3a9375947e220b)] - docs(plugin): format en/basics/plugin.md (#4168) (chs97 <<623528324@qq.com>>) +- [[`e9011e8f3`](http://github.com/eggjs/egg/commit/e9011e8f332a97da7e6e112d0f1ded42f0b5db42)] - feat: add http method patch to typings (#4125) (xiaoxu <>) +- [[`2109505b4`](http://github.com/eggjs/egg/commit/2109505b40a159cd047075e566e9465b1ad5a365)] - test: fix doctools path on windows (#4090) (fengmk2 <>) ## 2019-12-07, Version 2.26.0 @fengmk2 ### Notable changes -* **features** - * add application level Cookie options, can fix [Cookie SameSite warning on Chrome](https://support.google.com/chrome/thread/16654793?hl=en) now. - * use new URL instead of url.parse, avoiding potential security issues. +- **features** + - add application level Cookie options, can fix [Cookie SameSite warning on Chrome](https://support.google.com/chrome/thread/16654793?hl=en) now. + - use new URL instead of url.parse, avoiding potential security issues. ### Commits - * [[`b28134e77`](http://github.com/eggjs/egg/commit/b28134e7709c803eb7a7ed071a25bac8a28e3d1f)] - feat: add application level Cookie options (#4086) (fengmk2 <>) - * [[`b7718c1cc`](http://github.com/eggjs/egg/commit/b7718c1cc2b94b02ee728088060fdbc85e462b6d)] - fix: use new URL instead of url.parse (#4048) (Yiyu He <>) - * [[`afed9105d`](http://github.com/eggjs/egg/commit/afed9105df34aad60c40ecba0e44ddaad1a605dc)] - fix: index.d.ts (#4012) (dxd <>) - * [[`690711bab`](http://github.com/eggjs/egg/commit/690711bab8bd8c838b4dd651baea3bc49a5fa1f1)] - test: fix the testcase error of load_boot.test.js (#4041) (Xin Wang <>) - * [[`6c55a436b`](http://github.com/eggjs/egg/commit/6c55a436bf2afb7bb99810401a6f92b3a58471ff)] - docs: fix typo (#4028) (Xuehua Cai <>) +- [[`b28134e77`](http://github.com/eggjs/egg/commit/b28134e7709c803eb7a7ed071a25bac8a28e3d1f)] - feat: add application level Cookie options (#4086) (fengmk2 <>) +- [[`b7718c1cc`](http://github.com/eggjs/egg/commit/b7718c1cc2b94b02ee728088060fdbc85e462b6d)] - fix: use new URL instead of url.parse (#4048) (Yiyu He <>) +- [[`afed9105d`](http://github.com/eggjs/egg/commit/afed9105df34aad60c40ecba0e44ddaad1a605dc)] - fix: index.d.ts (#4012) (dxd <>) +- [[`690711bab`](http://github.com/eggjs/egg/commit/690711bab8bd8c838b4dd651baea3bc49a5fa1f1)] - test: fix the testcase error of load_boot.test.js (#4041) (Xin Wang <>) +- [[`6c55a436b`](http://github.com/eggjs/egg/commit/6c55a436bf2afb7bb99810401a6f92b3a58471ff)] - docs: fix typo (#4028) (Xuehua Cai <>) ## 2019-10-28, Version 2.25.0 @dead-horse ### Notable changes -* **features** - * support config.maxIpsCount, deprecate config.maxProxyCount - * singleton returns client name when create client +- **features** + - support config.maxIpsCount, deprecate config.maxProxyCount + - singleton returns client name when create client ### Commits - * [[`b3479e8e2`](http://github.com/eggjs/egg/commit/b3479e8e2b6cc74c95eef4334bd6b054fddb6158)] - feat: support config.maxIpsCount (#4014) (Yiyu He <>) - * [[`380e7d634`](http://github.com/eggjs/egg/commit/380e7d6344b4f608397fed5dea4f19918ca347f5)] - docs(env): cleanup the document (#3988) (Alpha <>) - * [[`2c5e64a50`](http://github.com/eggjs/egg/commit/2c5e64a50edd78522aa5bf83e4ea8ef4d72f5b40)] - docs: add promo link (#3995) (Haoliang Gao <>) - * [[`adca16637`](http://github.com/eggjs/egg/commit/adca1663712acd361dddd1b390ca48dda5a3608e)] - docs(deployment): update the description for hostname (#3994) (Suyi <>) - * [[`27dacb7c9`](http://github.com/eggjs/egg/commit/27dacb7c9dae4b65c1b973d39aae1f8c9a4cd7b1)] - feat:Singleton returns client name when create client (#3905) (ๆš—่‰ฒ่ฐƒ <<41288382+dark-tone@users.noreply.github.com>>) - * [[`d3f68c371`](http://github.com/eggjs/egg/commit/d3f68c3710946a63f640b1885e9c7120db935d8e)] - docs(deployment): modify hostname (#3987) (zfx <<502545703@qq.com>>) - * [[`73ad6c086`](http://github.com/eggjs/egg/commit/73ad6c0861d5d6f8235fde2a5ba985ad9f53fcfe)] - chore: use github actions to run CI (#3974) (Suyi <>) - +- [[`b3479e8e2`](http://github.com/eggjs/egg/commit/b3479e8e2b6cc74c95eef4334bd6b054fddb6158)] - feat: support config.maxIpsCount (#4014) (Yiyu He <>) +- [[`380e7d634`](http://github.com/eggjs/egg/commit/380e7d6344b4f608397fed5dea4f19918ca347f5)] - docs(env): cleanup the document (#3988) (Alpha <>) +- [[`2c5e64a50`](http://github.com/eggjs/egg/commit/2c5e64a50edd78522aa5bf83e4ea8ef4d72f5b40)] - docs: add promo link (#3995) (Haoliang Gao <>) +- [[`adca16637`](http://github.com/eggjs/egg/commit/adca1663712acd361dddd1b390ca48dda5a3608e)] - docs(deployment): update the description for hostname (#3994) (Suyi <>) +- [[`27dacb7c9`](http://github.com/eggjs/egg/commit/27dacb7c9dae4b65c1b973d39aae1f8c9a4cd7b1)] - feat:Singleton returns client name when create client (#3905) (ๆš—่‰ฒ่ฐƒ <<41288382+dark-tone@users.noreply.github.com>>) +- [[`d3f68c371`](http://github.com/eggjs/egg/commit/d3f68c3710946a63f640b1885e9c7120db935d8e)] - docs(deployment): modify hostname (#3987) (zfx <<502545703@qq.com>>) +- [[`73ad6c086`](http://github.com/eggjs/egg/commit/73ad6c0861d5d6f8235fde2a5ba985ad9f53fcfe)] - chore: use github actions to run CI (#3974) (Suyi <>) ## 2019-10-11, Version 2.24.0 @thonatos ### Notable changes -* **features** - * feat: set default body-parser limitation to 1mb - -* **fixes** - * app.keys getter must have a setter either - * more log for bodyParser - -* **docs** - * add opencollective to sponsors list - * update lf url - * fix hsts docs error - * fix typo of socket.io - * modify invalid links - -### Commits - - * [[`bddf1e183`](http://github.com/eggjs/egg/commit/bddf1e183b5b6fc0f1414f81948ffdedd71e16a9)] - feat: set default body-parser limitation to 1mb (#3903) (Suyi <>) - * [[`5ddf07c43`](http://github.com/eggjs/egg/commit/5ddf07c435ad81142a6e995583849e20c7348dda)] - docs: update readme (#3968) (Suyi <>) - * [[`be1b72606`](http://github.com/eggjs/egg/commit/be1b72606a62a8efe88849976126cc8ca61b8d7e)] - docs(security): hsts is disabled by default (#3972) (Suyi <>) - * [[`e5e948783`](http://github.com/eggjs/egg/commit/e5e948783a45ea138592a33e9ae7faa20a85af26)] - docs: add opencollective to sponsors list (#3971) (Suyi <>) - * [[`cde921456`](http://github.com/eggjs/egg/commit/cde921456657c16dba81c6fb9c991b62a826d120)] - docs: update lf url (#3922) (Suyi <>) - * [[`17b22c86b`](http://github.com/eggjs/egg/commit/17b22c86b7f83bc168d9c7176191618e19add1dd)] - docs: fix typo of socket.io (#3895) (lqzhgood <<9134671+lqzhgood@users.noreply.github.com>>) - * [[`a9d0cf5c0`](http://github.com/eggjs/egg/commit/a9d0cf5c0d5aadc957e12854f7a3ab6469f83f75)] - fix: app.keys getter must have a setter either (#3891) (Yiyu He <>) - * [[`f1707410b`](http://github.com/eggjs/egg/commit/f1707410bc3f703d69aae27965cc622b9a768107)] - docs(deployment): add logs that the egg app has been successfully connected to alinode (#3868) (hyj1991 <>) - * [[`24c388b4a`](http://github.com/eggjs/egg/commit/24c388b4a5ec4c717875a1510accbd5882800ad0)] - docs(egg-and-koa): modify invalid links (#3851) (sdjdd <<352207572@qq.com>>) - * [[`84894e871`](http://github.com/eggjs/egg/commit/84894e8714747876821447faeaada0dabc2a7147)] - chore: add sponsor config (#3751) (TZ | ๅคฉ็Œช <>) - * [[`064616934`](http://github.com/eggjs/egg/commit/064616934b4ff2c044395baae60bd33d3d7dc5ff)] - chore: add node12 for ci (#3196) (Haoliang Gao <>) - * [[`45a966621`](http://github.com/eggjs/egg/commit/45a966621746f9d2c9e8a91fc1b17f75d97033de)] - docs(quickstart): npm version for npm init command (#3836) (QingDeng <>) - * [[`341beda59`](http://github.com/eggjs/egg/commit/341beda59ee99867998e28603f9ed623e49c33aa)] - test: mv assert to fixtures (#3829) (Suyi <>) - * [[`79dbb14a5`](http://github.com/eggjs/egg/commit/79dbb14a535c27a55daf83b441b47aabff472b06)] - docs(logger): formatter (#3835) (TZ | ๅคฉ็Œช <>) +- **features** + - feat: set default body-parser limitation to 1mb + +- **fixes** + - app.keys getter must have a setter either + - more log for bodyParser + +- **docs** + - add opencollective to sponsors list + - update lf url + - fix hsts docs error + - fix typo of socket.io + - modify invalid links + +### Commits + +- [[`bddf1e183`](http://github.com/eggjs/egg/commit/bddf1e183b5b6fc0f1414f81948ffdedd71e16a9)] - feat: set default body-parser limitation to 1mb (#3903) (Suyi <>) +- [[`5ddf07c43`](http://github.com/eggjs/egg/commit/5ddf07c435ad81142a6e995583849e20c7348dda)] - docs: update readme (#3968) (Suyi <>) +- [[`be1b72606`](http://github.com/eggjs/egg/commit/be1b72606a62a8efe88849976126cc8ca61b8d7e)] - docs(security): hsts is disabled by default (#3972) (Suyi <>) +- [[`e5e948783`](http://github.com/eggjs/egg/commit/e5e948783a45ea138592a33e9ae7faa20a85af26)] - docs: add opencollective to sponsors list (#3971) (Suyi <>) +- [[`cde921456`](http://github.com/eggjs/egg/commit/cde921456657c16dba81c6fb9c991b62a826d120)] - docs: update lf url (#3922) (Suyi <>) +- [[`17b22c86b`](http://github.com/eggjs/egg/commit/17b22c86b7f83bc168d9c7176191618e19add1dd)] - docs: fix typo of socket.io (#3895) (lqzhgood <<9134671+lqzhgood@users.noreply.github.com>>) +- [[`a9d0cf5c0`](http://github.com/eggjs/egg/commit/a9d0cf5c0d5aadc957e12854f7a3ab6469f83f75)] - fix: app.keys getter must have a setter either (#3891) (Yiyu He <>) +- [[`f1707410b`](http://github.com/eggjs/egg/commit/f1707410bc3f703d69aae27965cc622b9a768107)] - docs(deployment): add logs that the egg app has been successfully connected to alinode (#3868) (hyj1991 <>) +- [[`24c388b4a`](http://github.com/eggjs/egg/commit/24c388b4a5ec4c717875a1510accbd5882800ad0)] - docs(egg-and-koa): modify invalid links (#3851) (sdjdd <<352207572@qq.com>>) +- [[`84894e871`](http://github.com/eggjs/egg/commit/84894e8714747876821447faeaada0dabc2a7147)] - chore: add sponsor config (#3751) (TZ | ๅคฉ็Œช <>) +- [[`064616934`](http://github.com/eggjs/egg/commit/064616934b4ff2c044395baae60bd33d3d7dc5ff)] - chore: add node12 for ci (#3196) (Haoliang Gao <>) +- [[`45a966621`](http://github.com/eggjs/egg/commit/45a966621746f9d2c9e8a91fc1b17f75d97033de)] - docs(quickstart): npm version for npm init command (#3836) (QingDeng <>) +- [[`341beda59`](http://github.com/eggjs/egg/commit/341beda59ee99867998e28603f9ed623e49c33aa)] - test: mv assert to fixtures (#3829) (Suyi <>) +- [[`79dbb14a5`](http://github.com/eggjs/egg/commit/79dbb14a535c27a55daf83b441b47aabff472b06)] - docs(logger): formatter (#3835) (TZ | ๅคฉ็Œช <>) ## 2019-07-17, Version 2.23.0 @atian25 ### Notable changes -* **features** - * error message rewrite when it has only a getter - -* **fixes** - * handleRequest method should return a promise - * more log for bodyParser - -* **docs** - * httpclient upload files - * typings improve - -### Commits - - * [[`6bfc0eb5b`](http://github.com/eggjs/egg/commit/6bfc0eb5b9a6d38c73d46bf641ece6adda3481a1)] - feat: error message rewrite when it has only a getter (#3796) (TZ | ๅคฉ็Œช <>) - * [[`489f52b5c`](http://github.com/eggjs/egg/commit/489f52b5ce4078efccefc8837729b42c15828722)] - fix: handleRequest method should return a promise (#3820) (ๅผ•่ฏ <>) - * [[`29a2f2fd9`](http://github.com/eggjs/egg/commit/29a2f2fd92e4d3e3cf0ee9ff034d8cdce07ee693)] - fix: more log for bodyParser (#3809) (TZ | ๅคฉ็Œช <>) - * [[`6dc8a2d14`](http://github.com/eggjs/egg/commit/6dc8a2d14582c774479593f002af2f2b96e0ce96)] - chore: fix ci (#3825) (Suyi <>) - * [[`e30511eff`](http://github.com/eggjs/egg/commit/e30511effeb77d954e2c15b684c274b85da2c69b)] - docs: add alinode supported platforms (#3821) (hyj1991 <>) - * [[`c67ca2059`](http://github.com/eggjs/egg/commit/c67ca2059f2c44140e3a5bc46c38c87f52a08172)] - docs: open should come with protocol (#3787) (zhennann <>) - * [[`9adcd40f8`](http://github.com/eggjs/egg/commit/9adcd40f81a22670abf2f5f9167d9c8de438ad34)] - docs(lifecyle): add class export in sample code (#3758) (Kermit Xuan <<33770367+Kermit-Xuan@users.noreply.github.com>>) - * [[`4ca62734d`](http://github.com/eggjs/egg/commit/4ca62734db829cad7e3ea35bc6394de98c9ad160)] - fix: typos (#3768) (Jeff <>) - * [[`b1cb5332d`](http://github.com/eggjs/egg/commit/b1cb5332d433c158f59ab4877f3f6ab07bf9fe79)] - chore: remove @types/urllib (#3732) (TZ | ๅคฉ็Œช <>) - * [[`3de31f541`](http://github.com/eggjs/egg/commit/3de31f5418503f02afde9e92409d5f40e664c46c)] - fix(typings): add custom logger typings (#3697) (ๅ–็Œฉ <>) - * [[`35af6331c`](http://github.com/eggjs/egg/commit/35af6331c97b2e9c9f831ff193709f8fc984f3a9)] - docs: https options en version (#3702) (liulun <>) - * [[`9c23232a4`](http://github.com/eggjs/egg/commit/9c23232a47679bdcb8f071a5cc01f013f443aa05)] - docs(sequelize): replace findById with findByPk (#3700) (Zhao zuoqi <<30346283+Mavericker-1996@users.noreply.github.com>>) - * [[`3fccb4f27`](http://github.com/eggjs/egg/commit/3fccb4f275b2982b974a1a1d99cec32795f4efd3)] - docs: https options (#3701) (liulun <>) - * [[`5b2dbd5b0`](http://github.com/eggjs/egg/commit/5b2dbd5b097d80b0f9150d1a03ec1d9c73af8dec)] - test: fix some test methods failed on windows platform (#3686) (QingDeng <>) - * [[`409990299`](http://github.com/eggjs/egg/commit/409990299fd3afeb35968bc06b02f4b0137718ba)] - fix๏ผšadd the doc test on windows (#3654) (Maledong <>) - * [[`17fab1c1d`](http://github.com/eggjs/egg/commit/17fab1c1d645076bda76be351fcb3c6f86cea4ca)] - docs: httpclient upload files (#3682) (TZ | ๅคฉ็Œช <>) - * [[`da2d439d6`](http://github.com/eggjs/egg/commit/da2d439d6f79f767055021bf96f7ef73207a751a)] - docs๏ผˆlifecyle): fix typo (#3681) (+v <>) +- **features** + - error message rewrite when it has only a getter + +- **fixes** + - handleRequest method should return a promise + - more log for bodyParser + +- **docs** + - httpclient upload files + - typings improve + +### Commits + +- [[`6bfc0eb5b`](http://github.com/eggjs/egg/commit/6bfc0eb5b9a6d38c73d46bf641ece6adda3481a1)] - feat: error message rewrite when it has only a getter (#3796) (TZ | ๅคฉ็Œช <>) +- [[`489f52b5c`](http://github.com/eggjs/egg/commit/489f52b5ce4078efccefc8837729b42c15828722)] - fix: handleRequest method should return a promise (#3820) (ๅผ•่ฏ <>) +- [[`29a2f2fd9`](http://github.com/eggjs/egg/commit/29a2f2fd92e4d3e3cf0ee9ff034d8cdce07ee693)] - fix: more log for bodyParser (#3809) (TZ | ๅคฉ็Œช <>) +- [[`6dc8a2d14`](http://github.com/eggjs/egg/commit/6dc8a2d14582c774479593f002af2f2b96e0ce96)] - chore: fix ci (#3825) (Suyi <>) +- [[`e30511eff`](http://github.com/eggjs/egg/commit/e30511effeb77d954e2c15b684c274b85da2c69b)] - docs: add alinode supported platforms (#3821) (hyj1991 <>) +- [[`c67ca2059`](http://github.com/eggjs/egg/commit/c67ca2059f2c44140e3a5bc46c38c87f52a08172)] - docs: open should come with protocol (#3787) (zhennann <>) +- [[`9adcd40f8`](http://github.com/eggjs/egg/commit/9adcd40f81a22670abf2f5f9167d9c8de438ad34)] - docs(lifecyle): add class export in sample code (#3758) (Kermit Xuan <<33770367+Kermit-Xuan@users.noreply.github.com>>) +- [[`4ca62734d`](http://github.com/eggjs/egg/commit/4ca62734db829cad7e3ea35bc6394de98c9ad160)] - fix: typos (#3768) (Jeff <>) +- [[`b1cb5332d`](http://github.com/eggjs/egg/commit/b1cb5332d433c158f59ab4877f3f6ab07bf9fe79)] - chore: remove @types/urllib (#3732) (TZ | ๅคฉ็Œช <>) +- [[`3de31f541`](http://github.com/eggjs/egg/commit/3de31f5418503f02afde9e92409d5f40e664c46c)] - fix(typings): add custom logger typings (#3697) (ๅ–็Œฉ <>) +- [[`35af6331c`](http://github.com/eggjs/egg/commit/35af6331c97b2e9c9f831ff193709f8fc984f3a9)] - docs: https options en version (#3702) (liulun <>) +- [[`9c23232a4`](http://github.com/eggjs/egg/commit/9c23232a47679bdcb8f071a5cc01f013f443aa05)] - docs(sequelize): replace findById with findByPk (#3700) (Zhao zuoqi <<30346283+Mavericker-1996@users.noreply.github.com>>) +- [[`3fccb4f27`](http://github.com/eggjs/egg/commit/3fccb4f275b2982b974a1a1d99cec32795f4efd3)] - docs: https options (#3701) (liulun <>) +- [[`5b2dbd5b0`](http://github.com/eggjs/egg/commit/5b2dbd5b097d80b0f9150d1a03ec1d9c73af8dec)] - test: fix some test methods failed on windows platform (#3686) (QingDeng <>) +- [[`409990299`](http://github.com/eggjs/egg/commit/409990299fd3afeb35968bc06b02f4b0137718ba)] - fix๏ผšadd the doc test on windows (#3654) (Maledong <>) +- [[`17fab1c1d`](http://github.com/eggjs/egg/commit/17fab1c1d645076bda76be351fcb3c6f86cea4ca)] - docs: httpclient upload files (#3682) (TZ | ๅคฉ็Œช <>) +- [[`da2d439d6`](http://github.com/eggjs/egg/commit/da2d439d6f79f767055021bf96f7ef73207a751a)] - docs๏ผˆlifecyle): fix typo (#3681) (+v <>) ## 2019-04-30, Version 2.22.2 @atian25 ### Notable changes -* **fixes** - * optimize declaration of httpclient +- **fixes** + - optimize declaration of httpclient ### Commits - * [[`670ba3475`](http://github.com/eggjs/egg/commit/670ba34751af0b3869dd656064b4587affb888ec)] - fix(typings): optimize declaration of httpclient (#3665) (ๅ–็Œฉ <>) +- [[`670ba3475`](http://github.com/eggjs/egg/commit/670ba34751af0b3869dd656064b4587affb888ec)] - fix(typings): optimize declaration of httpclient (#3665) (ๅ–็Œฉ <>) ## 2019-04-29, Version 2.22.1 @atian25 ### Notable changes -* **fixes** - * should restore agent messenger first +- **fixes** + - should restore agent messenger first ### Commits - * [[`04adcf93b`](http://github.com/eggjs/egg/commit/04adcf93b8f0a8c48c35015e8d2a279fc7d06b24)] - fix: should restore agent messenger first (#3658) (TZ | ๅคฉ็Œช <>) - * [[`99eb75398`](http://github.com/eggjs/egg/commit/99eb7539850c117d3d8b05f669cae5a9e9269be8)] - docs: fix history time (#3655) (TZ | ๅคฉ็Œช <>) +- [[`04adcf93b`](http://github.com/eggjs/egg/commit/04adcf93b8f0a8c48c35015e8d2a279fc7d06b24)] - fix: should restore agent messenger first (#3658) (TZ | ๅคฉ็Œช <>) +- [[`99eb75398`](http://github.com/eggjs/egg/commit/99eb7539850c117d3d8b05f669cae5a9e9269be8)] - docs: fix history time (#3655) (TZ | ๅคฉ็Œช <>) ## 2019-04-29, Version 2.22.0 @atian25 ### Notable changes -* **features** - * switch httpclient to httpclient2 for retry feature - * add BaseHookClass +- **features** + - switch httpclient to httpclient2 for retry feature + - add BaseHookClass -* **fixes** - * loadCustomLoader should be run before loadCustomApp +- **fixes** + - loadCustomLoader should be run before loadCustomApp -* **docs** - * d.ts for single mode +- **docs** + - d.ts for single mode ### Commits - * [[`d3b1cb5d9`](http://github.com/eggjs/egg/commit/d3b1cb5d9d2dd91330778966ba9813f56476a47b)] - fix: loadCustomLoader should be run before loadCustomApp (#3652) (Haoliang Gao <>) - * [[`7cc8aab02`](http://github.com/eggjs/egg/commit/7cc8aab02d89869b4ce460b2fa186aedcf00b64b)] - chore: update packages,remove 'plugin' and validations of doc generation (#3643) (Maledong <>) - * [[`bffb6448f`](http://github.com/eggjs/egg/commit/bffb6448f201ce0d61bd3a32b91f673cf5c074f4)] - docs: fix httpclient proxy (#3638) (TZ | ๅคฉ็Œช <>) - * [[`e7fbd68f3`](http://github.com/eggjs/egg/commit/e7fbd68f32054041b74bc860f11aca05c025c0a9)] - feat: switch httpclient to httpclient2 for retry feature (#3626) (TZ | ๅคฉ็Œช <>) - * [[`8bb7c7e7d`](http://github.com/eggjs/egg/commit/8bb7c7e7d59d6aeca4b2ed1eb580368dcb731a4d)] - feat: add BaseHookClass (#3581) (killa <>) - * [[`459454354`](http://github.com/eggjs/egg/commit/4594543543290a8c714fe3b9047c84578bf2f9a6)] - feat: index.d.tsๆทปๅŠ ๅ•่ฟ›็จ‹ๆจกๅผ (#3628) (jasine <>) - * [[`4b13a1ffb`](http://github.com/eggjs/egg/commit/4b13a1ffbed0895731bf38f72d5786d4b15f263f)] - chore: fix jsdocs (#3627) (TZ | ๅคฉ็Œช <>) +- [[`d3b1cb5d9`](http://github.com/eggjs/egg/commit/d3b1cb5d9d2dd91330778966ba9813f56476a47b)] - fix: loadCustomLoader should be run before loadCustomApp (#3652) (Haoliang Gao <>) +- [[`7cc8aab02`](http://github.com/eggjs/egg/commit/7cc8aab02d89869b4ce460b2fa186aedcf00b64b)] - chore: update packages,remove 'plugin' and validations of doc generation (#3643) (Maledong <>) +- [[`bffb6448f`](http://github.com/eggjs/egg/commit/bffb6448f201ce0d61bd3a32b91f673cf5c074f4)] - docs: fix httpclient proxy (#3638) (TZ | ๅคฉ็Œช <>) +- [[`e7fbd68f3`](http://github.com/eggjs/egg/commit/e7fbd68f32054041b74bc860f11aca05c025c0a9)] - feat: switch httpclient to httpclient2 for retry feature (#3626) (TZ | ๅคฉ็Œช <>) +- [[`8bb7c7e7d`](http://github.com/eggjs/egg/commit/8bb7c7e7d59d6aeca4b2ed1eb580368dcb731a4d)] - feat: add BaseHookClass (#3581) (killa <>) +- [[`459454354`](http://github.com/eggjs/egg/commit/4594543543290a8c714fe3b9047c84578bf2f9a6)] - feat: index.d.tsๆทปๅŠ ๅ•่ฟ›็จ‹ๆจกๅผ (#3628) (jasine <>) +- [[`4b13a1ffb`](http://github.com/eggjs/egg/commit/4b13a1ffbed0895731bf38f72d5786d4b15f263f)] - chore: fix jsdocs (#3627) (TZ | ๅคฉ็Œช <>) ## 2019-04-12, Version 2.21.1 @dead-horse ### Notable changes -* **fixes** - * Revert "feat: switch httpclient to httpclient2 for retry feature(which is a breaking change) +- **fixes** + - Revert "feat: switch httpclient to httpclient2 for retry feature(which is a breaking change) ### Commits - * [[`89872a76f`](http://github.com/eggjs/egg/commit/89872a76fc09cefb9ff92221a5c3b9977d206f7c)] - Revert "feat: switch httpclient to httpclient2 for retry feature (#36โ€ฆ (#3622) (Yiyu He <>) +- [[`89872a76f`](http://github.com/eggjs/egg/commit/89872a76fc09cefb9ff92221a5c3b9977d206f7c)] - Revert "feat: switch httpclient to httpclient2 for retry feature (#36โ€ฆ (#3622) (Yiyu He <>) ## 2019-04-11, Version 2.21.0 @dead-horse ### Notable changes -* **features** - * support config.maxProxyCount to help get the real client ip - * switch httpclient to httpclient2 for retry feature +- **features** + - support config.maxProxyCount to help get the real client ip + - switch httpclient to httpclient2 for retry feature -* **docs** - * add how to config egg behind a proxy - * update http_proxy usage - * change `egg-init` to `npm init egg` +- **docs** + - add how to config egg behind a proxy + - update http_proxy usage + - change `egg-init` to `npm init egg` ### Commits - * [[`01b9588a3`](http://github.com/eggjs/egg/commit/01b9588a35ba33a7088e79f6d3e08c713c4de963)] - feat: support config.maxProxyCount to help get the real client ip (#3612) (Yiyu He <>) - * [[`eead31862`](http://github.com/eggjs/egg/commit/eead318625347bb9de8f9d7ffc6fae5ae1b33901)] - feat: switch httpclient to httpclient2 for retry feature (#3606) (TZ | ๅคฉ็Œช <>) - * [[`879fe93a6`](http://github.com/eggjs/egg/commit/879fe93a6dde156101318c766a3c29ca07f1e18d)] - docs: add how to config egg behind a proxy (#3614) (Yiyu He <>) - * [[`2357fbc1e`](http://github.com/eggjs/egg/commit/2357fbc1ee18cf0a8ee8692ed2d62d2224acfe3b)] - docs: remove egg-ts-helper && inspect-brk (#3603) (TZ | ๅคฉ็Œช <>) - * [[`e0a1d8fc6`](http://github.com/eggjs/egg/commit/e0a1d8fc6806acc0a4141bc4cf67149069bfbdf0)] - docs: change egg-init to `npm init egg` (#3588) (TZ | ๅคฉ็Œช <>) - * [[`763923cd7`](http://github.com/eggjs/egg/commit/763923cd76be30496fee9f733db9500c1d8188f2)] - chore: remove unused plugins.puml link (#3579) (TZ | ๅคฉ็Œช <>) - * [[`b1746468d`](http://github.com/eggjs/egg/commit/b1746468dae2d02aeef37f6e8d85414624c79880)] - docs(httpclient): update http_proxy usage (#3569) (TZ | ๅคฉ็Œช <>) - +- [[`01b9588a3`](http://github.com/eggjs/egg/commit/01b9588a35ba33a7088e79f6d3e08c713c4de963)] - feat: support config.maxProxyCount to help get the real client ip (#3612) (Yiyu He <>) +- [[`eead31862`](http://github.com/eggjs/egg/commit/eead318625347bb9de8f9d7ffc6fae5ae1b33901)] - feat: switch httpclient to httpclient2 for retry feature (#3606) (TZ | ๅคฉ็Œช <>) +- [[`879fe93a6`](http://github.com/eggjs/egg/commit/879fe93a6dde156101318c766a3c29ca07f1e18d)] - docs: add how to config egg behind a proxy (#3614) (Yiyu He <>) +- [[`2357fbc1e`](http://github.com/eggjs/egg/commit/2357fbc1ee18cf0a8ee8692ed2d62d2224acfe3b)] - docs: remove egg-ts-helper && inspect-brk (#3603) (TZ | ๅคฉ็Œช <>) +- [[`e0a1d8fc6`](http://github.com/eggjs/egg/commit/e0a1d8fc6806acc0a4141bc4cf67149069bfbdf0)] - docs: change egg-init to `npm init egg` (#3588) (TZ | ๅคฉ็Œช <>) +- [[`763923cd7`](http://github.com/eggjs/egg/commit/763923cd76be30496fee9f733db9500c1d8188f2)] - chore: remove unused plugins.puml link (#3579) (TZ | ๅคฉ็Œช <>) +- [[`b1746468d`](http://github.com/eggjs/egg/commit/b1746468dae2d02aeef37f6e8d85414624c79880)] - docs(httpclient): update http_proxy usage (#3569) (TZ | ๅคฉ็Œช <>) ## 2019-03-25, Version 2.20.2 @whxaxes ### Notable changes -* **fixes** - * onClientError remove content-length header +- **fixes** + - onClientError remove content-length header -* **types** - * add custom loader typing - * import types from egg-core +- **types** + - add custom loader typing + - import types from egg-core ### Commits - * [[`f31cd38aa`](http://github.com/eggjs/egg/commit/f31cd38aa1c1cb58f4fb6b08020b0b49a9b5c1a8)] - fix(types): add custom loader typing (#3533) (ๅ–็Œฉ <>) - * [[`a73cfd067`](http://github.com/eggjs/egg/commit/a73cfd067b48b2c2301e50d5ab431dfecebddef4)] - fix(types): import types from egg-core (#3545) (ๅ–็Œฉ <>) - * [[`04adb930d`](http://github.com/eggjs/egg/commit/04adb930de61f6c3d1b7b9b4e7f49800e3b49602)] - fix: onClientError remove content-length header (#3544) (Yiyu He <>) +- [[`f31cd38aa`](http://github.com/eggjs/egg/commit/f31cd38aa1c1cb58f4fb6b08020b0b49a9b5c1a8)] - fix(types): add custom loader typing (#3533) (ๅ–็Œฉ <>) +- [[`a73cfd067`](http://github.com/eggjs/egg/commit/a73cfd067b48b2c2301e50d5ab431dfecebddef4)] - fix(types): import types from egg-core (#3545) (ๅ–็Œฉ <>) +- [[`04adb930d`](http://github.com/eggjs/egg/commit/04adb930de61f6c3d1b7b9b4e7f49800e3b49602)] - fix: onClientError remove content-length header (#3544) (Yiyu He <>) ## 2019-03-12, Version 2.20.1 @dead-horse ### Notable changes -* **fixes** - * empty querystring must be cached - * add Singleton class declare typings +- **fixes** + - empty querystring must be cached + - add Singleton class declare typings ### Commits - * [[`2fc241a86`](http://github.com/eggjs/egg/commit/2fc241a8648d64faab78196ccd0377c781287e5e)] - fix: add Singleton class declare typings (#3522) (mars <>) - * [[`981bad58b`](http://github.com/eggjs/egg/commit/981bad58ba6c4644b8bbbd818a43bf0dd62e206f)] - fix: empty querystring must be cached (#3535) (Yiyu He <>) - +- [[`2fc241a86`](http://github.com/eggjs/egg/commit/2fc241a8648d64faab78196ccd0377c781287e5e)] - fix: add Singleton class declare typings (#3522) (mars <>) +- [[`981bad58b`](http://github.com/eggjs/egg/commit/981bad58ba6c4644b8bbbd818a43bf0dd62e206f)] - fix: empty querystring must be cached (#3535) (Yiyu He <>) ## 2019-03-07, Version 2.20.0 @popomore ### Notable changes -* **features** - * support customLoader +- **features** + - support customLoader -* **chore** - * fix typo - * fix testcase +- **chore** + - fix typo + - fix testcase ### Commits - * [[`4cf06da27`](http://github.com/eggjs/egg/commit/4cf06da272a3f71b864efb6780ddfe2e6c1ad37c)] - feat: support customLoader (#3484) (Haoliang Gao <>) - * [[`2f2bd69bb`](http://github.com/eggjs/egg/commit/2f2bd69bb5a5ef5f9d45514c0640f3849bc64293)] - chore๏ผšFix some typos in Chinese and English (#3514) (Maledong <>) - * [[`65bdd158c`](http://github.com/eggjs/egg/commit/65bdd158caf38abfc945de9aad8367a8567b1a18)] - Fix(cluster-client.test.js)๏ผšRollback to previous (#3507) (Maledong <>) +- [[`4cf06da27`](http://github.com/eggjs/egg/commit/4cf06da272a3f71b864efb6780ddfe2e6c1ad37c)] - feat: support customLoader (#3484) (Haoliang Gao <>) +- [[`2f2bd69bb`](http://github.com/eggjs/egg/commit/2f2bd69bb5a5ef5f9d45514c0640f3849bc64293)] - chore๏ผšFix some typos in Chinese and English (#3514) (Maledong <>) +- [[`65bdd158c`](http://github.com/eggjs/egg/commit/65bdd158caf38abfc945de9aad8367a8567b1a18)] - Fix(cluster-client.test.js)๏ผšRollback to previous (#3507) (Maledong <>) ## 2019-02-28, Version 2.19.0 @dead-horse ### Notable changes -* **features** - * single mode support ignore warning +- **features** + - single mode support ignore warning -* **fixes** - * fix type defined +- **fixes** + - fix type defined ### Commits - * [[`18efac152`](http://github.com/eggjs/egg/commit/18efac152dd5cf789d1e79b1c1fb1fb4ec2013a1)] - feat: single mode support ignore warning (#3501) (Yiyu He <>) - * [[`f9eea2a4d`](http://github.com/eggjs/egg/commit/f9eea2a4da805a1b2f0e8883860266d68eb432ff)] - fix(types): getFileStream options types (#3500) (kayikay <<469797590@qq.com>>) +- [[`18efac152`](http://github.com/eggjs/egg/commit/18efac152dd5cf789d1e79b1c1fb1fb4ec2013a1)] - feat: single mode support ignore warning (#3501) (Yiyu He <>) +- [[`f9eea2a4d`](http://github.com/eggjs/egg/commit/f9eea2a4da805a1b2f0e8883860266d68eb432ff)] - fix(types): getFileStream options types (#3500) (kayikay <<469797590@qq.com>>) ## 2019-02-26, Version 2.18.0 @dead-horse ### Notable changes -* **features** - * cluster-client support single process mode +- **features** + - cluster-client support single process mode -* **fixes** - * fix type defined +- **fixes** + - fix type defined ### Commits - * [[`db1093128`](http://github.com/eggjs/egg/commit/db10931281dd39106e5c657e358117abd39b2103)] - feat: cluster-client support single cpu mode (#3497) (zลng yว” <>) - * [[`f7e6ab535`](http://github.com/eggjs/egg/commit/f7e6ab535df378b35dfe6b6b49d7e009dc2bcf3f)] - doc (typescript.md): Chinese translation for the beginning of TypeScript's Introduction (#3488) (Maledong <>) - * [[`ac7e9a6b6`](http://github.com/eggjs/egg/commit/ac7e9a6b6d732d946dc238d9bad3eaabb81a1b70)] - fix: helper type (#3483) (ๅ–็Œฉ <>) - +- [[`db1093128`](http://github.com/eggjs/egg/commit/db10931281dd39106e5c657e358117abd39b2103)] - feat: cluster-client support single cpu mode (#3497) (zลng yว” <>) +- [[`f7e6ab535`](http://github.com/eggjs/egg/commit/f7e6ab535df378b35dfe6b6b49d7e009dc2bcf3f)] - doc (typescript.md): Chinese translation for the beginning of TypeScript's Introduction (#3488) (Maledong <>) +- [[`ac7e9a6b6`](http://github.com/eggjs/egg/commit/ac7e9a6b6d732d946dc238d9bad3eaabb81a1b70)] - fix: helper type (#3483) (ๅ–็Œฉ <>) ## 2019-02-21, Version 2.17.0 @dead-horse ### Notable changes -* **features** - * agent context can be extended +- **features** + - agent context can be extended -* **fixes** - * createAnonymousContext add host in headers +- **fixes** + - createAnonymousContext add host in headers ### Commits -* [[`7147b23cf`](http://github.com/eggjs/egg/commit/7147b23cf7edaa98a8f009d98de7ef2aaa5303a0)] - feat: agent context can be extended (#3478) (Hongcai Deng <>) -* [[`a2f0d9620`](http://github.com/eggjs/egg/commit/a2f0d96204e05f11c5586ff0fa9441f4e3ab5dff)] - fix: createAnonymousContext add host in headers (#3477) (Yiyu He <>) -* [[`5952d1240`](http://github.com/eggjs/egg/commit/5952d12404ae896a2338ee4ee79d68876ffbb205)] - docs(typescript): fix wrong path of LifeCycle (#3475) (CHANG, TZU-YEN <>) + +- [[`7147b23cf`](http://github.com/eggjs/egg/commit/7147b23cf7edaa98a8f009d98de7ef2aaa5303a0)] - feat: agent context can be extended (#3478) (Hongcai Deng <>) +- [[`a2f0d9620`](http://github.com/eggjs/egg/commit/a2f0d96204e05f11c5586ff0fa9441f4e3ab5dff)] - fix: createAnonymousContext add host in headers (#3477) (Yiyu He <>) +- [[`5952d1240`](http://github.com/eggjs/egg/commit/5952d12404ae896a2338ee4ee79d68876ffbb205)] - docs(typescript): fix wrong path of LifeCycle (#3475) (CHANG, TZU-YEN <>) ## 2019-02-18, Version 2.16.2 @dead-horse ### Notable changes -* **fixes** - * fix: messenger in single process mode support send without `to` +- **fixes** + - fix: messenger in single process mode support send without `to` ### Commits - * [[`eac494184`](http://github.com/eggjs/egg/commit/eac4941846948ca6bb8a357d525ad82737425005)] - fix: support send without to argument (#3472) (Yiyu He <>) - +- [[`eac494184`](http://github.com/eggjs/egg/commit/eac4941846948ca6bb8a357d525ad82737425005)] - fix: support send without to argument (#3472) (Yiyu He <>) ## 2019-02-15, Version 2.16.1 @atian25 ### Notable changes -* **docs** - * remove declaration of view +- **docs** + - remove declaration of view -* **others** - * update dependencies +- **others** + - update dependencies ### Commits - * [[`1e859f2e2`](http://github.com/eggjs/egg/commit/1e859f2e200260cab95ac0b860d85609eb3eec06)] - feat(types): remove declaration of view (#3466) (ๅ–็Œฉ <>) - * [[`4a3ab5ac0`](http://github.com/eggjs/egg/commit/4a3ab5ac0324537fc3cdbcc0e84e3085b8a34586)] - deps: update dependencies (#3464) (Yiyu He <>) +- [[`1e859f2e2`](http://github.com/eggjs/egg/commit/1e859f2e200260cab95ac0b860d85609eb3eec06)] - feat(types): remove declaration of view (#3466) (ๅ–็Œฉ <>) +- [[`4a3ab5ac0`](http://github.com/eggjs/egg/commit/4a3ab5ac0324537fc3cdbcc0e84e3085b8a34586)] - deps: update dependencies (#3464) (Yiyu He <>) ## 2019-02-14, Version 2.16.0 @dead-horse ### Notable changes -* **features** - * allow ctx.router setter +- **features** + - allow ctx.router setter -* **others** - * more document improvement +- **others** + - more document improvement ### Commits - * [[`0b67c85f6`](http://github.com/eggjs/egg/commit/0b67c85f6f1798b2d3f377fb5ea336c96b60b6e3)] - feat: allow ctx.router setter (#3460) (fengmk2 <>) - * [[`ae5f56f3e`](http://github.com/eggjs/egg/commit/ae5f56f3e9b60eaa3507db44736020f3a13ec6f1)] - chore: Add principles for English titles and change all English titles (#3444) (Maledong <>) - * [[`a9bee07da`](http://github.com/eggjs/egg/commit/a9bee07daff1530da7350f9ad1ea56e21aa3eead)] - docs(sequelize): fix init doc (#3456) (Yiyu He <>) - * [[`f76c23052`](http://github.com/eggjs/egg/commit/f76c23052c86afcf158087f8b13a7e47ef76f67c)] - docs(logger): add logger.outputJSON to docs (#3425) (FX <>) - +- [[`0b67c85f6`](http://github.com/eggjs/egg/commit/0b67c85f6f1798b2d3f377fb5ea336c96b60b6e3)] - feat: allow ctx.router setter (#3460) (fengmk2 <>) +- [[`ae5f56f3e`](http://github.com/eggjs/egg/commit/ae5f56f3e9b60eaa3507db44736020f3a13ec6f1)] - chore: Add principles for English titles and change all English titles (#3444) (Maledong <>) +- [[`a9bee07da`](http://github.com/eggjs/egg/commit/a9bee07daff1530da7350f9ad1ea56e21aa3eead)] - docs(sequelize): fix init doc (#3456) (Yiyu He <>) +- [[`f76c23052`](http://github.com/eggjs/egg/commit/f76c23052c86afcf158087f8b13a7e47ef76f67c)] - docs(logger): add logger.outputJSON to docs (#3425) (FX <>) ## 2019-02-04, Version 2.15.1 @dead-horse ### Notable changes -* **fixes** - * add missing framework support for single process mode +- **fixes** + - add missing framework support for single process mode ### Commits - * [[`277c024cf`](http://github.com/eggjs/egg/commit/277c024cf565948547dbc7a518d39d7f55318f58)] - fix: add missing framework support for single process mode (#3445) (Yiyu He <>) +- [[`277c024cf`](http://github.com/eggjs/egg/commit/277c024cf565948547dbc7a518d39d7f55318f58)] - fix: add missing framework support for single process mode (#3445) (Yiyu He <>) ## 2019-02-03, Version 2.15.0 @dead-horse ### Notable changes -* **features** - * [EXPERIMENT FEATURE] support single process mode - -* **fixes** - * [TYPE] array supporting for config.static.dir - * [TYPE] fix IMiddleware type is incompatible - * [TYPE] fix type error while esModuleInterop is true - -* **others** - * more document improvement - -### Commits - - * [[`83c423a0a`](http://github.com/eggjs/egg/commit/83c423a0a985e701bfaef7f10372268b4ce8cef5)] - docs(development.md): Add English translation (Jennie <>) - * [[`d79da17bd`](http://github.com/eggjs/egg/commit/d79da17bdbe94f7b78d923caa10abf21e6c5f752)] - fix: type error while esModuleInterop is true (#3436) (ๅ–็Œฉ <>) - * [[`20ba4632b`](http://github.com/eggjs/egg/commit/20ba4632ba32e3b81e760678b4bbe00cdf05388e)] - feat: support single process mode (#3430) (Yiyu He <>) - * [[`133616961`](http://github.com/eggjs/egg/commit/133616961e5a2e95d5e2cd1254d7304c846b859c)] - docs: fix typo in socketio.md (#3431) (kilmas <>) - * [[`e899630e9`](http://github.com/eggjs/egg/commit/e899630e97865701b81d428686a19288b1c87b98)] - fix: array supporting for config.static.dir (#3421) (Gray <>) - * [[`43f2e3c44`](http://github.com/eggjs/egg/commit/43f2e3c449a7b448506d2484ed729618b06bffec)] - fix: IMiddleware type is incompatible (#3419) (ๅ–็Œฉ <>) - * [[`b3256b54e`](http://github.com/eggjs/egg/commit/b3256b54eeb09b2cee3cfdb75e98d6c090844a10)] - doc๏ผšAdd new loaderUpdate.md (#3395) (Maledong <>) - * [[`71768002a`](http://github.com/eggjs/egg/commit/71768002a468a8fd30b9516c0bed85fa27b99b0a)] - docs: Wrong words are corrected (#3418) (ๅทงๅ…‹ๅŠ›ๅ†ฐๆฟ€ๅ‡Œ <<121017405@qq.com>>) - * [[`20d56c7a8`](http://github.com/eggjs/egg/commit/20d56c7a83a74bb81ee47b0b8c2785db15519996)] - fix: fix ts ci (#3416) (ๅ–็Œฉ <>) - * [[`8beacd13e`](http://github.com/eggjs/egg/commit/8beacd13e3bcfff6b6a1e02eea72cafdd343858c)] - docs(logger): add logger.disableConsoleAfterReady to docs (#3384) (ๅ–็Œฉ <>) - * [[`271bc6372`](http://github.com/eggjs/egg/commit/271bc63722723531556bbec06d621f964ad1db33)] - chore: typo "submit an PR" should be "submit a PR" (#3408) (DAI JIE <>) - * [[`688f67c9f`](http://github.com/eggjs/egg/commit/688f67c9f329c71ea4469b9d28d5ee41815831ed)] - Chore: Fix some chore issues (#3400) (Maledong <>) - * [[`cfcebc623`](http://github.com/eggjs/egg/commit/cfcebc6234c62780c6aecf84db3862efd74e430c)] - doc (typescript.md): Sync the English translation (#3397) (Maledong <>) - * [[`7e5ef2181`](http://github.com/eggjs/egg/commit/7e5ef21811f98e5d55884f2574092e6f2e7b619b)] - docs(typescript): optimize docs of typescript (#3374) (ๅ–็Œฉ <>) - * [[`2a801f789`](http://github.com/eggjs/egg/commit/2a801f789f6e60427657b507951de8fc8e4a830f)] - chore: comments typo fix (#3392) (Jeff <>) - * [[`9a4b72062`](http://github.com/eggjs/egg/commit/9a4b7206212a27d37a37a1d68b4739be306b1a7a)] - chore: fix issue template (#3369) (Suyi <>) - * [[`ef73396a5`](http://github.com/eggjs/egg/commit/ef73396a5828c6b4e55c85cd2b27c3830bd306e5)] - docs: improve debug docs (#3370) (TZ | ๅคฉ็Œช <>) - * [[`874e57fda`](http://github.com/eggjs/egg/commit/874e57fda480d3295c1b1b30198ca3493f57814d)] - docs(sequelize): fix init (#3372) (Yiyu He <>) - * [[`b2152c56f`](http://github.com/eggjs/egg/commit/b2152c56f525a87fe0c1cfe66949005f308e1569)] - Chore: Fix some typo translations (#3361) (Maledong <>) - * [[`d275929d1`](http://github.com/eggjs/egg/commit/d275929d17830c95a2c828611b5ca54ffb747270)] - docs(boot): update app start document (#3348) (Yiyu He <>) - * [[`9a8652beb`](http://github.com/eggjs/egg/commit/9a8652bebc29f3d097039196b10daa2575f49695)] - Fix: Change the diagram of "starting process" (#3358) (Maledong <>) - * [[`ac0f13bc6`](http://github.com/eggjs/egg/commit/ac0f13bc604ebfc08185b336a106ec7e5d1bc98f)] - Chore: Add missing links for "Sails" and union the spellings of "Plugin" (#3356) (Maledong <>) - * [[`cd52b063b`](http://github.com/eggjs/egg/commit/cd52b063b60e15bc78c440fdebc00ddd3dca9909)] - docs(cluster-and-ipc.md): fix typos and formatting errors (#3357) (Darren Poon <>) - * [[`37e3c1aba`](http://github.com/eggjs/egg/commit/37e3c1abab31f47fc492574464657a57ff686b2b)] - Chroe: Fix something in articles (#3349) (Maledong <>) +- **features** + - [EXPERIMENT FEATURE] support single process mode + +- **fixes** + - [TYPE] array supporting for config.static.dir + - [TYPE] fix IMiddleware type is incompatible + - [TYPE] fix type error while esModuleInterop is true + +- **others** + - more document improvement + +### Commits + +- [[`83c423a0a`](http://github.com/eggjs/egg/commit/83c423a0a985e701bfaef7f10372268b4ce8cef5)] - docs(development.md): Add English translation (Jennie <>) +- [[`d79da17bd`](http://github.com/eggjs/egg/commit/d79da17bdbe94f7b78d923caa10abf21e6c5f752)] - fix: type error while esModuleInterop is true (#3436) (ๅ–็Œฉ <>) +- [[`20ba4632b`](http://github.com/eggjs/egg/commit/20ba4632ba32e3b81e760678b4bbe00cdf05388e)] - feat: support single process mode (#3430) (Yiyu He <>) +- [[`133616961`](http://github.com/eggjs/egg/commit/133616961e5a2e95d5e2cd1254d7304c846b859c)] - docs: fix typo in socketio.md (#3431) (kilmas <>) +- [[`e899630e9`](http://github.com/eggjs/egg/commit/e899630e97865701b81d428686a19288b1c87b98)] - fix: array supporting for config.static.dir (#3421) (Gray <>) +- [[`43f2e3c44`](http://github.com/eggjs/egg/commit/43f2e3c449a7b448506d2484ed729618b06bffec)] - fix: IMiddleware type is incompatible (#3419) (ๅ–็Œฉ <>) +- [[`b3256b54e`](http://github.com/eggjs/egg/commit/b3256b54eeb09b2cee3cfdb75e98d6c090844a10)] - doc๏ผšAdd new loaderUpdate.md (#3395) (Maledong <>) +- [[`71768002a`](http://github.com/eggjs/egg/commit/71768002a468a8fd30b9516c0bed85fa27b99b0a)] - docs: Wrong words are corrected (#3418) (ๅทงๅ…‹ๅŠ›ๅ†ฐๆฟ€ๅ‡Œ <<121017405@qq.com>>) +- [[`20d56c7a8`](http://github.com/eggjs/egg/commit/20d56c7a83a74bb81ee47b0b8c2785db15519996)] - fix: fix ts ci (#3416) (ๅ–็Œฉ <>) +- [[`8beacd13e`](http://github.com/eggjs/egg/commit/8beacd13e3bcfff6b6a1e02eea72cafdd343858c)] - docs(logger): add logger.disableConsoleAfterReady to docs (#3384) (ๅ–็Œฉ <>) +- [[`271bc6372`](http://github.com/eggjs/egg/commit/271bc63722723531556bbec06d621f964ad1db33)] - chore: typo "submit an PR" should be "submit a PR" (#3408) (DAI JIE <>) +- [[`688f67c9f`](http://github.com/eggjs/egg/commit/688f67c9f329c71ea4469b9d28d5ee41815831ed)] - Chore: Fix some chore issues (#3400) (Maledong <>) +- [[`cfcebc623`](http://github.com/eggjs/egg/commit/cfcebc6234c62780c6aecf84db3862efd74e430c)] - doc (typescript.md): Sync the English translation (#3397) (Maledong <>) +- [[`7e5ef2181`](http://github.com/eggjs/egg/commit/7e5ef21811f98e5d55884f2574092e6f2e7b619b)] - docs(typescript): optimize docs of typescript (#3374) (ๅ–็Œฉ <>) +- [[`2a801f789`](http://github.com/eggjs/egg/commit/2a801f789f6e60427657b507951de8fc8e4a830f)] - chore: comments typo fix (#3392) (Jeff <>) +- [[`9a4b72062`](http://github.com/eggjs/egg/commit/9a4b7206212a27d37a37a1d68b4739be306b1a7a)] - chore: fix issue template (#3369) (Suyi <>) +- [[`ef73396a5`](http://github.com/eggjs/egg/commit/ef73396a5828c6b4e55c85cd2b27c3830bd306e5)] - docs: improve debug docs (#3370) (TZ | ๅคฉ็Œช <>) +- [[`874e57fda`](http://github.com/eggjs/egg/commit/874e57fda480d3295c1b1b30198ca3493f57814d)] - docs(sequelize): fix init (#3372) (Yiyu He <>) +- [[`b2152c56f`](http://github.com/eggjs/egg/commit/b2152c56f525a87fe0c1cfe66949005f308e1569)] - Chore: Fix some typo translations (#3361) (Maledong <>) +- [[`d275929d1`](http://github.com/eggjs/egg/commit/d275929d17830c95a2c828611b5ca54ffb747270)] - docs(boot): update app start document (#3348) (Yiyu He <>) +- [[`9a8652beb`](http://github.com/eggjs/egg/commit/9a8652bebc29f3d097039196b10daa2575f49695)] - Fix: Change the diagram of "starting process" (#3358) (Maledong <>) +- [[`ac0f13bc6`](http://github.com/eggjs/egg/commit/ac0f13bc604ebfc08185b336a106ec7e5d1bc98f)] - Chore: Add missing links for "Sails" and union the spellings of "Plugin" (#3356) (Maledong <>) +- [[`cd52b063b`](http://github.com/eggjs/egg/commit/cd52b063b60e15bc78c440fdebc00ddd3dca9909)] - docs(cluster-and-ipc.md): fix typos and formatting errors (#3357) (Darren Poon <>) +- [[`37e3c1aba`](http://github.com/eggjs/egg/commit/37e3c1abab31f47fc492574464657a57ff686b2b)] - Chroe: Fix something in articles (#3349) (Maledong <>) ## 2018-12-20, Version 2.14.2 @atian25 ### Notable changes -* **fixes** - * fix d.ts context declaration not works +- **fixes** + - fix d.ts context declaration not works -* **docs** - * more document improvement +- **docs** + - more document improvement ### Commits - * [[`edfe66093`](http://github.com/eggjs/egg/commit/edfe66093c9ffe730ffd9804da1e2b264a48c38e)] - fix: Add comments for re-writing properties from Koa (#3332) (Maledong <>) - * [[`f312db78f`](http://github.com/eggjs/egg/commit/f312db78fc330da2bfe6efdb0f095d7b3b363beb)] - fix: fix context declaration not works (#3329) (Axes <>) - * [[`ef47a2746`](http://github.com/eggjs/egg/commit/ef47a274625a6ae8696857bef01b2c679dd65395)] - docs: fix config heading level (#3327) (Suyi <>) - * [[`cddd91ded`](http://github.com/eggjs/egg/commit/cddd91ded2fac1395487e2847caaf92afaafcf8e)] - chore: adjust template (TZ <>) - * [[`7319727a0`](http://github.com/eggjs/egg/commit/7319727a0b8a4fa210746ac201631a4b7db4359b)] - chore: Update issue templates (#3326) (TZ | ๅคฉ็Œช <>) - * [[`0cb246e26`](http://github.com/eggjs/egg/commit/0cb246e2663a288395a013ee78a1b34ab5b7c641)] - doc: Fix some translations with some icons (#3315) (Maledong <>) - * [[`9dc20377e`](http://github.com/eggjs/egg/commit/9dc20377e18e53278bcfac037e15a5a761cccdb3)] - doc: session special usage tip (#3304) (Jerry Wu <>) - * [[`6f4e91274`](http://github.com/eggjs/egg/commit/6f4e91274daa0685ba0ed8983ad5b6fd457322bc)] - docs: Update httpclient.md (#3276) (Albert <>) - * [[`64e88abfd`](http://github.com/eggjs/egg/commit/64e88abfd24d50096aa2d4ef442aafd46101429a)] - docs(egg-passport): add redirection desc while auth succeed (#3260) (Suyi <>) + +- [[`edfe66093`](http://github.com/eggjs/egg/commit/edfe66093c9ffe730ffd9804da1e2b264a48c38e)] - fix: Add comments for re-writing properties from Koa (#3332) (Maledong <>) +- [[`f312db78f`](http://github.com/eggjs/egg/commit/f312db78fc330da2bfe6efdb0f095d7b3b363beb)] - fix: fix context declaration not works (#3329) (Axes <>) +- [[`ef47a2746`](http://github.com/eggjs/egg/commit/ef47a274625a6ae8696857bef01b2c679dd65395)] - docs: fix config heading level (#3327) (Suyi <>) +- [[`cddd91ded`](http://github.com/eggjs/egg/commit/cddd91ded2fac1395487e2847caaf92afaafcf8e)] - chore: adjust template (TZ <>) +- [[`7319727a0`](http://github.com/eggjs/egg/commit/7319727a0b8a4fa210746ac201631a4b7db4359b)] - chore: Update issue templates (#3326) (TZ | ๅคฉ็Œช <>) +- [[`0cb246e26`](http://github.com/eggjs/egg/commit/0cb246e2663a288395a013ee78a1b34ab5b7c641)] - doc: Fix some translations with some icons (#3315) (Maledong <>) +- [[`9dc20377e`](http://github.com/eggjs/egg/commit/9dc20377e18e53278bcfac037e15a5a761cccdb3)] - doc: session special usage tip (#3304) (Jerry Wu <>) +- [[`6f4e91274`](http://github.com/eggjs/egg/commit/6f4e91274daa0685ba0ed8983ad5b6fd457322bc)] - docs: Update httpclient.md (#3276) (Albert <>) +- [[`64e88abfd`](http://github.com/eggjs/egg/commit/64e88abfd24d50096aa2d4ef442aafd46101429a)] - docs(egg-passport): add redirection desc while auth succeed (#3260) (Suyi <>) ## 2018-11-24, Version 2.14.1 @atian25 ### Notable changes -* **fixes** - * remove timeout log msg +- **fixes** + - remove timeout log msg -* **others** - * use circular-json-for-egg to remove deprecate message +- **others** + - use circular-json-for-egg to remove deprecate message ### Commits - * [[`0fb5a96c0`](http://github.com/eggjs/egg/commit/0fb5a96c023e916cb9c14c5960df62547ed391d8)] - fix: remove timeout log msg (#3229) (TZ | ๅคฉ็Œช <>) - * [[`de81caef1`](http://github.com/eggjs/egg/commit/de81caef1d91c229effadd25ddf752297c2a08f5)] - deps: use circular-json-for-egg to remove deprecate message (#3211) (Yiyu He <>) +- [[`0fb5a96c0`](http://github.com/eggjs/egg/commit/0fb5a96c023e916cb9c14c5960df62547ed391d8)] - fix: remove timeout log msg (#3229) (TZ | ๅคฉ็Œช <>) +- [[`de81caef1`](http://github.com/eggjs/egg/commit/de81caef1d91c229effadd25ddf752297c2a08f5)] - deps: use circular-json-for-egg to remove deprecate message (#3211) (Yiyu He <>) ## 2018-11-17, Version 2.14.0 @dead-horse ### Notable changes -* **features** - * add create anonymous context to agent - * support server timeout +- **features** + - add create anonymous context to agent + - support server timeout -* **fixes** - * curl: allow request timeout bigger than agent timeout - * triggerServerDidReady should be triggered only once +- **fixes** + - curl: allow request timeout bigger than agent timeout + - triggerServerDidReady should be triggered only once ### Commits - * [[`db999d3f7`](http://github.com/eggjs/egg/commit/db999d3f7afa210c855f3f1a4518e83f7d8c1dc6)] - docs: add serverTimeout to d.ts (#3200) (TZ | ๅคฉ็Œช <>) - * [[`a43fef4e1`](http://github.com/eggjs/egg/commit/a43fef4e1828937d3d84469989582df273de1493)] - docs(index.d.ts): curl ๅขžๅŠ ๆณ›ๅž‹ (#3197) (The Rock <>) - * [[`d40124a25`](http://github.com/eggjs/egg/commit/d40124a25fcd1b52ab862ee297139a022458b81d)] - feat: add create anonymous context to agent (#3193) (Hongcai Deng <>) - * [[`9dfd19ead`](http://github.com/eggjs/egg/commit/9dfd19eada8bae7be212155a2989d0ccc410e8eb)] - fix: triggerServerDidReady should be triggered only once (#3190) (killa <>) - * [[`7802528e1`](http://github.com/eggjs/egg/commit/7802528e122691eb2cb78174e1c1490d0a382c08)] - feat: support server timeout (#3133) (TZ | -ๅคฉ็Œช <>) - * [[`ff79101b5`](http://github.com/eggjs/egg/commit/ff79101b592d59ad12d110dd26dd7fa3d044b968)] - docs: Update service.md (#3191) (่‚–้‡‘ <>) - * [[`327fa174f`](http://github.com/eggjs/egg/commit/327fa174ffd74a67a77520d839eac282c916e8c0)] - fix: allow request timeout bigger than agent timeout (#3146) (fengmk2 <>) - * [[`86093c03a`](http://github.com/eggjs/egg/commit/86093c03a822a2b925de94cfda96198dc8159ade)] - docs: remove promo logo (#3176) (Suyi <>) +- [[`db999d3f7`](http://github.com/eggjs/egg/commit/db999d3f7afa210c855f3f1a4518e83f7d8c1dc6)] - docs: add serverTimeout to d.ts (#3200) (TZ | ๅคฉ็Œช <>) +- [[`a43fef4e1`](http://github.com/eggjs/egg/commit/a43fef4e1828937d3d84469989582df273de1493)] - docs(index.d.ts): curl ๅขžๅŠ ๆณ›ๅž‹ (#3197) (The Rock <>) +- [[`d40124a25`](http://github.com/eggjs/egg/commit/d40124a25fcd1b52ab862ee297139a022458b81d)] - feat: add create anonymous context to agent (#3193) (Hongcai Deng <>) +- [[`9dfd19ead`](http://github.com/eggjs/egg/commit/9dfd19eada8bae7be212155a2989d0ccc410e8eb)] - fix: triggerServerDidReady should be triggered only once (#3190) (killa <>) +- [[`7802528e1`](http://github.com/eggjs/egg/commit/7802528e122691eb2cb78174e1c1490d0a382c08)] - feat: support server timeout (#3133) (TZ | + ๅคฉ็Œช <>) +- [[`ff79101b5`](http://github.com/eggjs/egg/commit/ff79101b592d59ad12d110dd26dd7fa3d044b968)] - docs: Update service.md (#3191) (่‚–้‡‘ <>) +- [[`327fa174f`](http://github.com/eggjs/egg/commit/327fa174ffd74a67a77520d839eac282c916e8c0)] - fix: allow request timeout bigger than agent timeout (#3146) (fengmk2 <>) +- [[`86093c03a`](http://github.com/eggjs/egg/commit/86093c03a822a2b925de94cfda96198dc8159ade)] - docs: remove promo logo (#3176) (Suyi <>) ## 2018-11-07, Version 2.13.0 @mansonchor ### Notable changes -* **feature** - * emit event when runInBackground catch error - -* **perf** - * better TypeScript support +- **feature** + - emit event when runInBackground catch error -* **docs** - * supplement documentation +- **perf** + - better TypeScript support +- **docs** + - supplement documentation ### Commits - * [[`03378b8c3`](https://github.com/mansonchor/egg.git/commit/03378b8c3e48e7000a580a4acf5375f9ffcac4dc)] - docs(plugin.md): fix 'path' declaration example (#3152) (maigozhang <>) - * [[`3c25221bd`](https://github.com/mansonchor/egg.git/commit/3c25221bd24a0a39cd06540fad46884e4dda363c)] - chore: use is.string() in utils.js for consistency (#3153) (ZYSzys <>) - * [[`a9b0fcec6`](https://github.com/mansonchor/egg.git/commit/a9b0fcec636f7241d0f578dca6b99444dabfeb83)] - chore(typings): add method `beforeClose` in index.d.ts (#3120) (Erona <>) - * [[`4709db746`](https://github.com/mansonchor/egg.git/commit/4709db746d8f97de99c04558f1ba86443e394668)] - feature(context): emit event when runInBackground catch error (#3118) (mansonchor <>) - * [[`e1dc2a7a4`](https://github.com/mansonchor/egg.git/commit/e1dc2a7a409a8bf56a817773229d5fc6dcde796b)] - docs: add promo logo (#3113) (Haoliang Gao <>) - * [[`51e9c1578`](https://github.com/mansonchor/egg.git/commit/51e9c1578496ed2afb44c47fdfd77867a95fec52)] - chore(typings): add interface IBoot (#3098) (killa <>) - * [[`8052d7ff7`](https://github.com/mansonchor/egg.git/commit/8052d7ff7bf6278e8ce4b4de46e0e6324d0d3861)] - doc: Update the `configWillLoad` explainations (#3116) (Maledong <>) - * [[`c3c4e2e3e`](https://github.com/mansonchor/egg.git/commit/c3c4e2e3e04a924595d6837ab15c7b292e3529f6)] - docs: add configWillLoad to lifecycle (#3101) (fengmk2 <>) - * [[`4abdb4980`](https://github.com/mansonchor/egg.git/commit/4abdb49801ebb3075b408d6fb3b72eba1a70c056)] - docs(CONTRIBUTION): Add missing link for `Accquire the submitted files` (#3102) (Maledong <>) - * [[`c7061ec62`](https://github.com/mansonchor/egg.git/commit/c7061ec6255faa250c6565a4c102f64c0498683c)] - fix(docs): Grammar of "lots of" (#3100) (waiting <>) - * [[`92181e83f`](https://github.com/mansonchor/egg.git/commit/92181e83f98d55bd1a796a871ab5d438d02c8e84)] - doc (CONTRIBUTION): Add missing English translations and clearify dns (#3035) (Maledong <>) - * [[`0a7497987`](https://github.com/mansonchor/egg.git/commit/0a7497987067ce1c3376dfc30676c35f484a5ccc)] - doc(logger.md): Fix incorrect description on default log output level. (#3082) (TX-Kunkun <>) - +- [[`03378b8c3`](https://github.com/mansonchor/egg.git/commit/03378b8c3e48e7000a580a4acf5375f9ffcac4dc)] - docs(plugin.md): fix 'path' declaration example (#3152) (maigozhang <>) +- [[`3c25221bd`](https://github.com/mansonchor/egg.git/commit/3c25221bd24a0a39cd06540fad46884e4dda363c)] - chore: use is.string() in utils.js for consistency (#3153) (ZYSzys <>) +- [[`a9b0fcec6`](https://github.com/mansonchor/egg.git/commit/a9b0fcec636f7241d0f578dca6b99444dabfeb83)] - chore(typings): add method `beforeClose` in index.d.ts (#3120) (Erona <>) +- [[`4709db746`](https://github.com/mansonchor/egg.git/commit/4709db746d8f97de99c04558f1ba86443e394668)] - feature(context): emit event when runInBackground catch error (#3118) (mansonchor <>) +- [[`e1dc2a7a4`](https://github.com/mansonchor/egg.git/commit/e1dc2a7a409a8bf56a817773229d5fc6dcde796b)] - docs: add promo logo (#3113) (Haoliang Gao <>) +- [[`51e9c1578`](https://github.com/mansonchor/egg.git/commit/51e9c1578496ed2afb44c47fdfd77867a95fec52)] - chore(typings): add interface IBoot (#3098) (killa <>) +- [[`8052d7ff7`](https://github.com/mansonchor/egg.git/commit/8052d7ff7bf6278e8ce4b4de46e0e6324d0d3861)] - doc: Update the `configWillLoad` explainations (#3116) (Maledong <>) +- [[`c3c4e2e3e`](https://github.com/mansonchor/egg.git/commit/c3c4e2e3e04a924595d6837ab15c7b292e3529f6)] - docs: add configWillLoad to lifecycle (#3101) (fengmk2 <>) +- [[`4abdb4980`](https://github.com/mansonchor/egg.git/commit/4abdb49801ebb3075b408d6fb3b72eba1a70c056)] - docs(CONTRIBUTION): Add missing link for `Accquire the submitted files` (#3102) (Maledong <>) +- [[`c7061ec62`](https://github.com/mansonchor/egg.git/commit/c7061ec6255faa250c6565a4c102f64c0498683c)] - fix(docs): Grammar of "lots of" (#3100) (waiting <>) +- [[`92181e83f`](https://github.com/mansonchor/egg.git/commit/92181e83f98d55bd1a796a871ab5d438d02c8e84)] - doc (CONTRIBUTION): Add missing English translations and clearify dns (#3035) (Maledong <>) +- [[`0a7497987`](https://github.com/mansonchor/egg.git/commit/0a7497987067ce1c3376dfc30676c35f484a5ccc)] - doc(logger.md): Fix incorrect description on default log output level. (#3082) (TX-Kunkun <>) ## 2018-10-08, Version 2.12.0 @dead-horse ### Notable changes -* **feature** - * add Subscription base class on app instance +- **feature** + - add Subscription base class on app instance -* **fix** - * upgrade to egg-logger@2, don't write log when stream was destroyed. - * pin circular-json@0.5.5 to avoid output deprecate message - -* **docs** - * corrected lots of documentation errors, thanks @Maledong - * use egg-logger definition +- **fix** + - upgrade to egg-logger@2, don't write log when stream was destroyed. + - pin circular-json@0.5.5 to avoid output deprecate message +- **docs** + - corrected lots of documentation errors, thanks @Maledong + - use egg-logger definition ### Commits - * [[`eb1eae736`](http://github.com/eggjs/egg/commit/eb1eae736c0fc541e6d21fb726d52d971d6a95da)] - refactor(typescript): use egg-logger definition (#3078) (Haoliang Gao <>) - * [[`04d9a3b85`](http://github.com/eggjs/egg/commit/04d9a3b85ef54819c0ad3ac505e7806db6a7e9b3)] - deps: egg-logger@2 (#3073) (Yiyu He <>) - * [[`886d9ad8f`](http://github.com/eggjs/egg/commit/886d9ad8fd11e1fbbd1712dd53ef464658f525b5)] - feat: add Subscription base class on app instance (#3058) (fengmk2 <>) - * [[`4c6fb2a17`](http://github.com/eggjs/egg/commit/4c6fb2a175c2481aa61aaad131f6812517bc7022)] - doc (socket.io): Make 'uws' cannot use anymore clear (#3068) (Maledong <>) - * [[`0d6798d22`](http://github.com/eggjs/egg/commit/0d6798d22d0e5016b0f7f25e5fa15ffe6900e16c)] - docs (Controller.md): Add new feat description (#3066) (Maledong <>) - * [[`399902680`](http://github.com/eggjs/egg/commit/39990268081d1da3fdb2d575802ea46cdf67bcd5)] - doc(typescript.md): Clarify the middleware's usages (#3039) (Maledong <>) - * [[`6bf812f73`](http://github.com/eggjs/egg/commit/6bf812f73603e967e405a815dcb2cc94dcb8384c)] - chore: fix middleware docs typo (#3060) (TZ | ๅคฉ็Œช <>) - * [[`b13d904d3`](http://github.com/eggjs/egg/commit/b13d904d302639c3b6068f109d4bcfa5aff12c61)] - test: avoid DNS pollution on local env (#3034) (fengmk2 <>) - * [[`bace2433b`](http://github.com/eggjs/egg/commit/bace2433bcc96d1507403c34711b2a2e450e6a6a)] - fix: remove loader.loadBootHook (Yiyu He <>) - * [[`6a7db2a35`](http://github.com/eggjs/egg/commit/6a7db2a3591a03b187bc3b52c67b37fde7984d34)] - doc (objects.md): Fix number and code errors (#3029) (Maledong <>) - * [[`c65a64899`](http://github.com/eggjs/egg/commit/c65a648991900b95a8ef0b21dcd8e3f715523df7)] - doc (TypeScript): Formation errors with missing translations (#3020) (Maledong <>) - * [[`abd8d1286`](http://github.com/eggjs/egg/commit/abd8d12861e17ff8fe5e950d589c00d17625beae)] - deps: pin circular-json@0.5.5 to avoid output deprecate message (#3023) (Yiyu He <>) - * [[`e3ffcbe64`](http://github.com/eggjs/egg/commit/e3ffcbe6449b95b50ea40583a28383e734c72fe1)] - docs (typescript.md): Add missing trans in English for TypeScript (#2998) (Maledong <>) +- [[`eb1eae736`](http://github.com/eggjs/egg/commit/eb1eae736c0fc541e6d21fb726d52d971d6a95da)] - refactor(typescript): use egg-logger definition (#3078) (Haoliang Gao <>) +- [[`04d9a3b85`](http://github.com/eggjs/egg/commit/04d9a3b85ef54819c0ad3ac505e7806db6a7e9b3)] - deps: egg-logger@2 (#3073) (Yiyu He <>) +- [[`886d9ad8f`](http://github.com/eggjs/egg/commit/886d9ad8fd11e1fbbd1712dd53ef464658f525b5)] - feat: add Subscription base class on app instance (#3058) (fengmk2 <>) +- [[`4c6fb2a17`](http://github.com/eggjs/egg/commit/4c6fb2a175c2481aa61aaad131f6812517bc7022)] - doc (socket.io): Make 'uws' cannot use anymore clear (#3068) (Maledong <>) +- [[`0d6798d22`](http://github.com/eggjs/egg/commit/0d6798d22d0e5016b0f7f25e5fa15ffe6900e16c)] - docs (Controller.md): Add new feat description (#3066) (Maledong <>) +- [[`399902680`](http://github.com/eggjs/egg/commit/39990268081d1da3fdb2d575802ea46cdf67bcd5)] - doc(typescript.md): Clarify the middleware's usages (#3039) (Maledong <>) +- [[`6bf812f73`](http://github.com/eggjs/egg/commit/6bf812f73603e967e405a815dcb2cc94dcb8384c)] - chore: fix middleware docs typo (#3060) (TZ | ๅคฉ็Œช <>) +- [[`b13d904d3`](http://github.com/eggjs/egg/commit/b13d904d302639c3b6068f109d4bcfa5aff12c61)] - test: avoid DNS pollution on local env (#3034) (fengmk2 <>) +- [[`bace2433b`](http://github.com/eggjs/egg/commit/bace2433bcc96d1507403c34711b2a2e450e6a6a)] - fix: remove loader.loadBootHook (Yiyu He <>) +- [[`6a7db2a35`](http://github.com/eggjs/egg/commit/6a7db2a3591a03b187bc3b52c67b37fde7984d34)] - doc (objects.md): Fix number and code errors (#3029) (Maledong <>) +- [[`c65a64899`](http://github.com/eggjs/egg/commit/c65a648991900b95a8ef0b21dcd8e3f715523df7)] - doc (TypeScript): Formation errors with missing translations (#3020) (Maledong <>) +- [[`abd8d1286`](http://github.com/eggjs/egg/commit/abd8d12861e17ff8fe5e950d589c00d17625beae)] - deps: pin circular-json@0.5.5 to avoid output deprecate message (#3023) (Yiyu He <>) +- [[`e3ffcbe64`](http://github.com/eggjs/egg/commit/e3ffcbe6449b95b50ea40583a28383e734c72fe1)] - docs (typescript.md): Add missing trans in English for TypeScript (#2998) (Maledong <>) ## 2018-09-19, Version 2.11.2 @XadillaX ### Notable changes -* **fix** - * typescript: add missing 'ignore', 'match' -* **refactor** - * separate dumping config object and config file +- **fix** + - typescript: add missing 'ignore', 'match' +- **refactor** + - separate dumping config object and config file ### Commits - * [[`1d30166e0`](http://github.com/eggjs/egg/commit/1d30166e037e8890fc850e51bdba02af76772485)] - refactor: separate dumping config object and config file (#3014) (Khaidi Chu <>) - * [[`e3f183e96`](http://github.com/eggjs/egg/commit/e3f183e9658e603c74850376f2257bd88bc4a043)] - fix (typescript): Add missing 'ignore','match' (#3010) (Maledong <>) +- [[`1d30166e0`](http://github.com/eggjs/egg/commit/1d30166e037e8890fc850e51bdba02af76772485)] - refactor: separate dumping config object and config file (#3014) (Khaidi Chu <>) +- [[`e3f183e96`](http://github.com/eggjs/egg/commit/e3f183e9658e603c74850376f2257bd88bc4a043)] - fix (typescript): Add missing 'ignore','match' (#3010) (Maledong <>) ## 2018-09-14, Version 2.11.1 @popomore ### Notable changes -* **fix** - * httpclient: can't use runInBackground in agent +- **fix** + - httpclient: can't use runInBackground in agent -* **deps** - * upgrade to debug@4 and coffee@5 +- **deps** + - upgrade to debug@4 and coffee@5 ### Commits - * [[`eed74e861`](http://github.com/eggjs/egg/commit/eed74e8610e1ea189beed1c3526b38f0b59c48ab)] - chore: update deps, debug@4 and coffee@5 (#2995) (TZ | ๅคฉ็Œช <>) - * [[`a8a3dfb04`](http://github.com/eggjs/egg/commit/a8a3dfb04f11b1c48ed1f01154e4d4311bfafa4b)] - fix(httpclient): can't use runInBackground in agent (#3003) (Haoliang Gao <>) - * [[`4faf68f4b`](http://github.com/eggjs/egg/commit/4faf68f4b6dad160a151b3d76041a0521261b530)] - doc (loader.md): Add missing English translations (#2996) (Maledong <>) +- [[`eed74e861`](http://github.com/eggjs/egg/commit/eed74e8610e1ea189beed1c3526b38f0b59c48ab)] - chore: update deps, debug@4 and coffee@5 (#2995) (TZ | ๅคฉ็Œช <>) +- [[`a8a3dfb04`](http://github.com/eggjs/egg/commit/a8a3dfb04f11b1c48ed1f01154e4d4311bfafa4b)] - fix(httpclient): can't use runInBackground in agent (#3003) (Haoliang Gao <>) +- [[`4faf68f4b`](http://github.com/eggjs/egg/commit/4faf68f4b6dad160a151b3d76041a0521261b530)] - doc (loader.md): Add missing English translations (#2996) (Maledong <>) ## 2018-09-11, Version 2.11.0 @atian25 ### Notable changes -* **feature** - * support boot lifecycle, see https://github.com/eggjs/egg/issues/2520 - * `dnshttpclient` now use async function instead of Promise - -* **fix** - * don't log when rawPacket is empty - -* **docs** - * add sequelize guide docs - * more document and typings improvement - -### Commits - - * [[`0d876c71a`](http://github.com/eggjs/egg/commit/0d876c71a9c4862b93cb039f564ae3d3171e1cad)] - feat: support boot lifecyle (#2972) (killa <>) - * [[`b02ce1547`](http://github.com/eggjs/egg/commit/b02ce154777fc78a6d344fe45d915d013096bea3)] - chroe(doc): Fix some typos (#2988) (Maledong <>) - * [[`688067ae0`](http://github.com/eggjs/egg/commit/688067ae09071316cbf5310b17d92d4fec39b42a)] - docs: fix 2 typos (#2982) (Jeff <>) - * [[`a719fd345`](http://github.com/eggjs/egg/commit/a719fd34507ebbfcf800768fb58adc81aa9c5e36)] - docs: Fix and add missing typos (#2935) (Maledong <>) - * [[`815c27879`](http://github.com/eggjs/egg/commit/815c278792e94ccf85822b3496f10396236e6628)] - fix (typings): Upgrade to the latest version of 'egg-cookie' to fetch (#2958) (Maledong <>) - * [[`a2df5ad13`](http://github.com/eggjs/egg/commit/a2df5ad137dea5faf7724d480edcc482a1df9393)] - docs: fixed typo. (#2961) (Ariel Yang <>) - * [[`b971e6633`](http://github.com/eggjs/egg/commit/b971e66336af4c8e241303866c8fa9acaaf4e66f)] - test: fix sitefile icon test (#2940) (Yiyu He <>) - * [[`81826ed1a`](http://github.com/eggjs/egg/commit/81826ed1a826a3436f8c42b7b5466295c60f241e)] - docs: fix link to angular commit-message-format (#2939) (Vincent <>) - * [[`45e302459`](http://github.com/eggjs/egg/commit/45e30245952619e4ed95867b2f76b0bdd06e94cc)] - fix: don't log when rawPacket is empty (#2924) (Haoliang Gao <>) - * [[`db1286de7`](http://github.com/eggjs/egg/commit/db1286de73de2cd987dc8f28c0616e9a683824a6)] - chore(typings): add class EggLoader (#2321) (waiting <>) - * [[`80528ccec`](http://github.com/eggjs/egg/commit/80528cceced500b5ae49ebf6d9df242ba2ce5ea4)] - refactor(dnshttpclient): use async function instead of Promise (#2774) (Haoliang Gao <>) - * [[`fe9e95654`](http://github.com/eggjs/egg/commit/fe9e9565472c7de9ff8dfb8894917764fe26fa0b)] - doc (package.json,README.zh-CN): Fix some typos (#2927) (Maledong <>) - * [[`289e96278`](http://github.com/eggjs/egg/commit/289e96278359a1468e366a6f3f7b2094dd3b7d6c)] - docs(sequelize): hostname shoule be host (#2921) (Will <<1078954008@qq.com>>) - * [[`72cd808b8`](http://github.com/eggjs/egg/commit/72cd808b86f37847cf340d88ec4eb73b9d7a7aa0)] - docs: fix sequelize link (#2909) (Yiyu He <>) - * [[`ae9ec30b4`](http://github.com/eggjs/egg/commit/ae9ec30b410bba3f8a99ba741e59fdb13e51c806)] - docs: add sequelize (#2902) (Yiyu He <>) - * [[`68135608b`](http://github.com/eggjs/egg/commit/68135608b3518b7d3dbd852453061179f63d5e4f)] - docs(deployment): fix typo on grep (#2898) (Baffin Lee <>) - * [[`6bfe70b3d`](http://github.com/eggjs/egg/commit/6bfe70b3d64206c85dea19c308abb40c46c6e347)] - doc (en,zh-cn): Fix translations error (#2885) (Maledong <>) - * [[`96ed020ce`](http://github.com/eggjs/egg/commit/96ed020ce04919049181808cee217029586d11c3)] - docs: fix config and socketio error (#2884) (Suyi <>) - +- **feature** + - support boot lifecycle, see https://github.com/eggjs/egg/issues/2520 + - `dnshttpclient` now use async function instead of Promise + +- **fix** + - don't log when rawPacket is empty + +- **docs** + - add sequelize guide docs + - more document and typings improvement + +### Commits + +- [[`0d876c71a`](http://github.com/eggjs/egg/commit/0d876c71a9c4862b93cb039f564ae3d3171e1cad)] - feat: support boot lifecyle (#2972) (killa <>) +- [[`b02ce1547`](http://github.com/eggjs/egg/commit/b02ce154777fc78a6d344fe45d915d013096bea3)] - chroe(doc): Fix some typos (#2988) (Maledong <>) +- [[`688067ae0`](http://github.com/eggjs/egg/commit/688067ae09071316cbf5310b17d92d4fec39b42a)] - docs: fix 2 typos (#2982) (Jeff <>) +- [[`a719fd345`](http://github.com/eggjs/egg/commit/a719fd34507ebbfcf800768fb58adc81aa9c5e36)] - docs: Fix and add missing typos (#2935) (Maledong <>) +- [[`815c27879`](http://github.com/eggjs/egg/commit/815c278792e94ccf85822b3496f10396236e6628)] - fix (typings): Upgrade to the latest version of 'egg-cookie' to fetch (#2958) (Maledong <>) +- [[`a2df5ad13`](http://github.com/eggjs/egg/commit/a2df5ad137dea5faf7724d480edcc482a1df9393)] - docs: fixed typo. (#2961) (Ariel Yang <>) +- [[`b971e6633`](http://github.com/eggjs/egg/commit/b971e66336af4c8e241303866c8fa9acaaf4e66f)] - test: fix sitefile icon test (#2940) (Yiyu He <>) +- [[`81826ed1a`](http://github.com/eggjs/egg/commit/81826ed1a826a3436f8c42b7b5466295c60f241e)] - docs: fix link to angular commit-message-format (#2939) (Vincent <>) +- [[`45e302459`](http://github.com/eggjs/egg/commit/45e30245952619e4ed95867b2f76b0bdd06e94cc)] - fix: don't log when rawPacket is empty (#2924) (Haoliang Gao <>) +- [[`db1286de7`](http://github.com/eggjs/egg/commit/db1286de73de2cd987dc8f28c0616e9a683824a6)] - chore(typings): add class EggLoader (#2321) (waiting <>) +- [[`80528ccec`](http://github.com/eggjs/egg/commit/80528cceced500b5ae49ebf6d9df242ba2ce5ea4)] - refactor(dnshttpclient): use async function instead of Promise (#2774) (Haoliang Gao <>) +- [[`fe9e95654`](http://github.com/eggjs/egg/commit/fe9e9565472c7de9ff8dfb8894917764fe26fa0b)] - doc (package.json,README.zh-CN): Fix some typos (#2927) (Maledong <>) +- [[`289e96278`](http://github.com/eggjs/egg/commit/289e96278359a1468e366a6f3f7b2094dd3b7d6c)] - docs(sequelize): hostname shoule be host (#2921) (Will <<1078954008@qq.com>>) +- [[`72cd808b8`](http://github.com/eggjs/egg/commit/72cd808b86f37847cf340d88ec4eb73b9d7a7aa0)] - docs: fix sequelize link (#2909) (Yiyu He <>) +- [[`ae9ec30b4`](http://github.com/eggjs/egg/commit/ae9ec30b410bba3f8a99ba741e59fdb13e51c806)] - docs: add sequelize (#2902) (Yiyu He <>) +- [[`68135608b`](http://github.com/eggjs/egg/commit/68135608b3518b7d3dbd852453061179f63d5e4f)] - docs(deployment): fix typo on grep (#2898) (Baffin Lee <>) +- [[`6bfe70b3d`](http://github.com/eggjs/egg/commit/6bfe70b3d64206c85dea19c308abb40c46c6e347)] - doc (en,zh-cn): Fix translations error (#2885) (Maledong <>) +- [[`96ed020ce`](http://github.com/eggjs/egg/commit/96ed020ce04919049181808cee217029586d11c3)] - docs: fix config and socketio error (#2884) (Suyi <>) ## 2018-08-06, Version 2.10.0 @fengmk2 ### Notable changes -* **feature** - * allow runInBackground reuse on plugins - * use Math.floor instead of parseInt - -* **fix** - * use cache-content-type - -* **docs** - * add lifecycle doc - * add sequelize guide - * add allowDebugAtProd in document - * egg-scripts support windows - * schedule add env description - * more document and typings improvement - -### Commits - - * [[`ff7431d5c`](http://github.com/eggjs/egg/commit/ff7431d5c4ea1e1d40fd7e3656dc5ab52ca55726)] - feat: allow runInBackground reuse on plugins (#2872) (fengmk2 <>) - * [[`422b342b1`](http://github.com/eggjs/egg/commit/422b342b1fa419db145323927f4f2d2a8996b7fb)] - feat: Update index.d.ts (#2853) (Ben <>) - * [[`2ca8f0184`](http://github.com/eggjs/egg/commit/2ca8f018473274fa544234c91fc608fa9bf09032)] - feat(typings): define Messenger['on'] and Messenger['once'] (#2763) (waiting <>) - * [[`9f8926d7c`](http://github.com/eggjs/egg/commit/9f8926d7cc55ae103b6a37751538870cc70aa12d)] - fix: use cache-content-type (#2793) (Yiyu He <>) - * [[`033fe0ce1`](http://github.com/eggjs/egg/commit/033fe0ce1d39bd63346de1ec60c97b159be867aa)] - docs: optimize egg-validate usage (#2852) (Sean Zou <<405495715@qq.com>>) - * [[`c0b0bb834`](http://github.com/eggjs/egg/commit/c0b0bb8345df83bbd2949b0af34bb397b5185e17)] - docs(session): fix bug in example code of modify session value (#2824) (Baffin Lee <>) - * [[`b55b303ed`](http://github.com/eggjs/egg/commit/b55b303eddbaf545cdb06fd81df624fd3070110a)] - test: test on travis with node 10 (#2461) (Yiyu He <>) - * [[`38a472f24`](http://github.com/eggjs/egg/commit/38a472f24cf68acb9c64fafa2e4374115d578220)] - docs: add allowDebugAtProd in document (#2803) (Yiyu He <>) - * [[`e86669937`](http://github.com/eggjs/egg/commit/e866699379bc570f8bfcef9a090f1bdb5cddee32)] - perf: use Math.floor instead of parseInt (Eason <>) - * [[`67d538e0e`](http://github.com/eggjs/egg/commit/67d538e0e175e96fe2a64b9c8d17b063537236f7)] - docs(plugin): add details for plugin.js (#2780) (TZ | ๅคฉ็Œช <>) - * [[`8d0b29cc9`](http://github.com/eggjs/egg/commit/8d0b29cc9b0a3b8eefad1ab64a05478c81709144)] - docs(deployment): egg-scripts support windows (#2788) (Baffin Lee <>) - * [[`aaf8faf4f`](http://github.com/eggjs/egg/commit/aaf8faf4fd8d813c7938baa1533d768b9d205fc7)] - test: skip test (#2773) (Haoliang Gao <>) - * [[`eb70335bd`](http://github.com/eggjs/egg/commit/eb70335bd61b6887ffeb33f103340b89c857312a)] - docs(schedule): add env description (#2753) (TZ | ๅคฉ็Œช <>) - * [[`ef20ff756`](http://github.com/eggjs/egg/commit/ef20ff75633b6e83b115d32af603d0f4f34cb1e1)] - docs: add http://www.sofastack.tech (#2752) (Haoliang Gao <>) - * [[`1ecb521c5`](http://github.com/eggjs/egg/commit/1ecb521c50b6238397f9a0b628448c0d2b5ec4fa)] - doc: add lifecyle doc (#2708) (killa <>) - * [[`7930f0419`](http://github.com/eggjs/egg/commit/7930f0419fee741bcf6de73693bcdf1e9986f31e)] - docs: fix ws engine error (#2717) (Suyi <>) +- **feature** + - allow runInBackground reuse on plugins + - use Math.floor instead of parseInt + +- **fix** + - use cache-content-type + +- **docs** + - add lifecycle doc + - add sequelize guide + - add allowDebugAtProd in document + - egg-scripts support windows + - schedule add env description + - more document and typings improvement + +### Commits + +- [[`ff7431d5c`](http://github.com/eggjs/egg/commit/ff7431d5c4ea1e1d40fd7e3656dc5ab52ca55726)] - feat: allow runInBackground reuse on plugins (#2872) (fengmk2 <>) +- [[`422b342b1`](http://github.com/eggjs/egg/commit/422b342b1fa419db145323927f4f2d2a8996b7fb)] - feat: Update index.d.ts (#2853) (Ben <>) +- [[`2ca8f0184`](http://github.com/eggjs/egg/commit/2ca8f018473274fa544234c91fc608fa9bf09032)] - feat(typings): define Messenger['on'] and Messenger['once'] (#2763) (waiting <>) +- [[`9f8926d7c`](http://github.com/eggjs/egg/commit/9f8926d7cc55ae103b6a37751538870cc70aa12d)] - fix: use cache-content-type (#2793) (Yiyu He <>) +- [[`033fe0ce1`](http://github.com/eggjs/egg/commit/033fe0ce1d39bd63346de1ec60c97b159be867aa)] - docs: optimize egg-validate usage (#2852) (Sean Zou <<405495715@qq.com>>) +- [[`c0b0bb834`](http://github.com/eggjs/egg/commit/c0b0bb8345df83bbd2949b0af34bb397b5185e17)] - docs(session): fix bug in example code of modify session value (#2824) (Baffin Lee <>) +- [[`b55b303ed`](http://github.com/eggjs/egg/commit/b55b303eddbaf545cdb06fd81df624fd3070110a)] - test: test on travis with node 10 (#2461) (Yiyu He <>) +- [[`38a472f24`](http://github.com/eggjs/egg/commit/38a472f24cf68acb9c64fafa2e4374115d578220)] - docs: add allowDebugAtProd in document (#2803) (Yiyu He <>) +- [[`e86669937`](http://github.com/eggjs/egg/commit/e866699379bc570f8bfcef9a090f1bdb5cddee32)] - perf: use Math.floor instead of parseInt (Eason <>) +- [[`67d538e0e`](http://github.com/eggjs/egg/commit/67d538e0e175e96fe2a64b9c8d17b063537236f7)] - docs(plugin): add details for plugin.js (#2780) (TZ | ๅคฉ็Œช <>) +- [[`8d0b29cc9`](http://github.com/eggjs/egg/commit/8d0b29cc9b0a3b8eefad1ab64a05478c81709144)] - docs(deployment): egg-scripts support windows (#2788) (Baffin Lee <>) +- [[`aaf8faf4f`](http://github.com/eggjs/egg/commit/aaf8faf4fd8d813c7938baa1533d768b9d205fc7)] - test: skip test (#2773) (Haoliang Gao <>) +- [[`eb70335bd`](http://github.com/eggjs/egg/commit/eb70335bd61b6887ffeb33f103340b89c857312a)] - docs(schedule): add env description (#2753) (TZ | ๅคฉ็Œช <>) +- [[`ef20ff756`](http://github.com/eggjs/egg/commit/ef20ff75633b6e83b115d32af603d0f4f34cb1e1)] - docs: add http://www.sofastack.tech (#2752) (Haoliang Gao <>) +- [[`1ecb521c5`](http://github.com/eggjs/egg/commit/1ecb521c50b6238397f9a0b628448c0d2b5ec4fa)] - doc: add lifecyle doc (#2708) (killa <>) +- [[`7930f0419`](http://github.com/eggjs/egg/commit/7930f0419fee741bcf6de73693bcdf1e9986f31e)] - docs: fix ws engine error (#2717) (Suyi <>) ## 2018-06-14, Version 2.9.1 @dead-horse ### Notable changes -* **perf** - * improve set type performance +- **perf** + - improve set type performance -* **docs** - * fix socketio's browser demo - * add Messenger in tsd +- **docs** + - fix socketio's browser demo + - add Messenger in tsd ### Commits - * [[`1a820bd44`](http://github.com/eggjs/egg/commit/1a820bd4408b36cf3e48eda62f392006081c17a3)] - perf: improve set type performance by lru cache (#2697) (fengmk2 <>) - * [[`239ce03ef`](http://github.com/eggjs/egg/commit/239ce03efaf60d3d961ced29cf4bf95e44bde2db)] - docs: fix socketio's browser demo (#2645) (xcold <>) - * [[`73ca1b7a3`](http://github.com/eggjs/egg/commit/73ca1b7a3ef6546d4f8a3d227055121a93b80188)] - chore(typings): add Messenger (#2688) (waiting <>) +- [[`1a820bd44`](http://github.com/eggjs/egg/commit/1a820bd4408b36cf3e48eda62f392006081c17a3)] - perf: improve set type performance by lru cache (#2697) (fengmk2 <>) +- [[`239ce03ef`](http://github.com/eggjs/egg/commit/239ce03efaf60d3d961ced29cf4bf95e44bde2db)] - docs: fix socketio's browser demo (#2645) (xcold <>) +- [[`73ca1b7a3`](http://github.com/eggjs/egg/commit/73ca1b7a3ef6546d4f8a3d227055121a93b80188)] - chore(typings): add Messenger (#2688) (waiting <>) ## 2018-06-01, Version 2.9.0 @popomore ### Notable changes -* **feature** - * dump timing data for loader +- **feature** + - dump timing data for loader -* **fix** - * the default value of config.allowDebugAtProd is false - * make definition of app.locals and ctx.locals definitions merge available - * add key any to Context in typescript define +- **fix** + - the default value of config.allowDebugAtProd is false + - make definition of app.locals and ctx.locals definitions merge available + - add key any to Context in typescript define -* **docs** - * more document improvement +- **docs** + - more document improvement ### Commits - * [[`e5737d545`](http://github.com/eggjs/egg/commit/e5737d5455d536b908f37ba367446e511f30e663)] - fix: add key any to Context (#2650) (Axes <>) - * [[`65a43aa9e`](http://github.com/eggjs/egg/commit/65a43aa9e47ad2f799e328e4e0ab91a63669c5e3)] - feat: dump timing data for loader (#2521) (#2621) (Haoliang Gao <>) - * [[`48c6d3c9d`](http://github.com/eggjs/egg/commit/48c6d3c9d524e1cbba3e301e6613436741696cc0)] - fix: typo (#2615) (Yanan Che <>) - * [[`c91e67cc0`](http://github.com/eggjs/egg/commit/c91e67cc0246a22efee126ebd01866b05b8312dc)] - docs(logger): the unit of maxFileSize should be byte (#2575) (Haoliang Gao <>) - * [[`26c274174`](http://github.com/eggjs/egg/commit/26c274174c9a48ef1636933fbb2be9777d38f522)] - docs: tweek doc style (#2613) (Haoliang Gao <>) - * [[`3ee7fcf12`](http://github.com/eggjs/egg/commit/3ee7fcf1291a4968197fab4648e951176dfa2714)] - docs: fix quickstart typo error (#2578) (Zhuxy <>) - * [[`8b7c8bd35`](http://github.com/eggjs/egg/commit/8b7c8bd35f8695f4459cfd623f9961c276e0d5a6)] - docs(d.ts): add property of EggAppConfig.development (#2561) (SinaVee <>) - * [[`16a61231d`](http://github.com/eggjs/egg/commit/16a61231d12c91ae609e68509d29aac669e1b83c)] - docs: add d.ts for bodyparser (#2548) (wangtao0101 <>) - * [[`e7696a7d2`](http://github.com/eggjs/egg/commit/e7696a7d2b4bc8eb6fb984aaaa0e0f2422d1c048)] - fix(d.ts): make app.locals and ctx.locals definitions merging available (#2546) (Tony Hawking <>) - * [[`e5d47524e`](http://github.com/eggjs/egg/commit/e5d47524ef96138172c86e774014a6b26d5cac09)] - chroe: Correct an error syntax of English (#2544) (DongWei <>) - * [[`c0f4bd12d`](http://github.com/eggjs/egg/commit/c0f4bd12d422554351b1d1e9866a7b9bbc444e76)] - fix: config.allowDebugAtProd default to false (ZhangJan <>) - * [[`0723cd230`](http://github.com/eggjs/egg/commit/0723cd230514b623c4454120dae988fd5a68ec44)] - docs(cookie): how to get frontend cookie (#2542) (Yiyu He <>) - * [[`9fea64ee9`](http://github.com/eggjs/egg/commit/9fea64ee993de7c3ee2e239d7bba91f5f3b3408a)] - docs: Fix an error link, change a comment into English (#2535) (DongWei <>) - * [[`e96ddb6a8`](http://github.com/eggjs/egg/commit/e96ddb6a884ef767c8653242c666dcc7381222b7)] - docs: Modifications of comments and full translations (DongWei <>) +- [[`e5737d545`](http://github.com/eggjs/egg/commit/e5737d5455d536b908f37ba367446e511f30e663)] - fix: add key any to Context (#2650) (Axes <>) +- [[`65a43aa9e`](http://github.com/eggjs/egg/commit/65a43aa9e47ad2f799e328e4e0ab91a63669c5e3)] - feat: dump timing data for loader (#2521) (#2621) (Haoliang Gao <>) +- [[`48c6d3c9d`](http://github.com/eggjs/egg/commit/48c6d3c9d524e1cbba3e301e6613436741696cc0)] - fix: typo (#2615) (Yanan Che <>) +- [[`c91e67cc0`](http://github.com/eggjs/egg/commit/c91e67cc0246a22efee126ebd01866b05b8312dc)] - docs(logger): the unit of maxFileSize should be byte (#2575) (Haoliang Gao <>) +- [[`26c274174`](http://github.com/eggjs/egg/commit/26c274174c9a48ef1636933fbb2be9777d38f522)] - docs: tweek doc style (#2613) (Haoliang Gao <>) +- [[`3ee7fcf12`](http://github.com/eggjs/egg/commit/3ee7fcf1291a4968197fab4648e951176dfa2714)] - docs: fix quickstart typo error (#2578) (Zhuxy <>) +- [[`8b7c8bd35`](http://github.com/eggjs/egg/commit/8b7c8bd35f8695f4459cfd623f9961c276e0d5a6)] - docs(d.ts): add property of EggAppConfig.development (#2561) (SinaVee <>) +- [[`16a61231d`](http://github.com/eggjs/egg/commit/16a61231d12c91ae609e68509d29aac669e1b83c)] - docs: add d.ts for bodyparser (#2548) (wangtao0101 <>) +- [[`e7696a7d2`](http://github.com/eggjs/egg/commit/e7696a7d2b4bc8eb6fb984aaaa0e0f2422d1c048)] - fix(d.ts): make app.locals and ctx.locals definitions merging available (#2546) (Tony Hawking <>) +- [[`e5d47524e`](http://github.com/eggjs/egg/commit/e5d47524ef96138172c86e774014a6b26d5cac09)] - chroe: Correct an error syntax of English (#2544) (DongWei <>) +- [[`c0f4bd12d`](http://github.com/eggjs/egg/commit/c0f4bd12d422554351b1d1e9866a7b9bbc444e76)] - fix: config.allowDebugAtProd default to false (ZhangJan <>) +- [[`0723cd230`](http://github.com/eggjs/egg/commit/0723cd230514b623c4454120dae988fd5a68ec44)] - docs(cookie): how to get frontend cookie (#2542) (Yiyu He <>) +- [[`9fea64ee9`](http://github.com/eggjs/egg/commit/9fea64ee993de7c3ee2e239d7bba91f5f3b3408a)] - docs: Fix an error link, change a comment into English (#2535) (DongWei <>) +- [[`e96ddb6a8`](http://github.com/eggjs/egg/commit/e96ddb6a884ef767c8653242c666dcc7381222b7)] - docs: Modifications of comments and full translations (DongWei <>) ## 2018-05-05, Version 2.8.1 @atian25 ### Notable changes -* **docs** - * fix missing d.ts +- **docs** + - fix missing d.ts ### Commits - * [[`20356bffc`](http://github.com/eggjs/egg/commit/20356bffcf7e99970b44f230a6fc2a8f9547a380)] - feat(d.ts): add createAnonymousContext & runInBackground (#2501) (Hengfei Zhuang <>) - * [[`c013ef3e6`](http://github.com/eggjs/egg/commit/c013ef3e64e049c6ef48e29d289f6d756b6ca1f7)] - feat(d.ts): add runSchedule & Subscription define (#2504) (Hengfei Zhuang <>) +- [[`20356bffc`](http://github.com/eggjs/egg/commit/20356bffcf7e99970b44f230a6fc2a8f9547a380)] - feat(d.ts): add createAnonymousContext & runInBackground (#2501) (Hengfei Zhuang <>) +- [[`c013ef3e6`](http://github.com/eggjs/egg/commit/c013ef3e64e049c6ef48e29d289f6d756b6ca1f7)] - feat(d.ts): add runSchedule & Subscription define (#2504) (Hengfei Zhuang <>) ## 2018-05-03, Version 2.8.0 @dead-horse ### Notable changes -* **feature** - * add time duration for dump config +- **feature** + - add time duration for dump config -* **fix** - * make singleton work for unextensible or frozen instance +- **fix** + - make singleton work for unextensible or frozen instance -* **docs** - * switch to English document - * add middleware to Application and other ts improvement (typescript) - * update wxapp-socket-io project to weapp.socket.io - * update title and remove unused files +- **docs** + - switch to English document + - add middleware to Application and other ts improvement (typescript) + - update wxapp-socket-io project to weapp.socket.io + - update title and remove unused files ### Commits - * [[`4b602d037`](http://github.com/eggjs/egg/commit/4b602d037554b72c8261b7abb7efd94f8f59f3fe)] - fix: make singleton work for unextensible or frozen instance (#2472) (Yiyu He <>) - * [[`824200c11`](http://github.com/eggjs/egg/commit/824200c11cac8e20b2c275daa7f5a4a365c71259)] - feat: add time duration for dump config (#2485) (Haoliang Gao <>) - * [[`73dac083d`](http://github.com/eggjs/egg/commit/73dac083d2a029f893e9b6737080c921027e308f)] - docs: update wxapp-socket-io project to weapp.socket.io (#2421) (liuguili <>) - * [[`1ada8e384`](http://github.com/eggjs/egg/commit/1ada8e3848be9f09680d7cac091fb14206df5a11)] - feat(d.ts): add middleware to Application and other ts improvement (#2465) (Axes <>) - * [[`437785315`](http://github.com/eggjs/egg/commit/437785315f28a828ea0cf7bece80223d5b796dc5)] - docs: fix the code error of LOCALS in view.md (#2464) (zjz19901029 <<346663801@qq.com>>) - * [[`f341b9fb8`](http://github.com/eggjs/egg/commit/f341b9fb8bdf36b6280500578e8448c59aec10f1)] - chore: update title and remove unused files (#2433) (TZ | -ๅคฉ็Œช <>) - * [[`a5ab29cbd`](http://github.com/eggjs/egg/commit/a5ab29cbd1de0f5425019085258a496b4bce8b45)] - docs: switch to English document (#2426) (Haoliang Gao <>) - * [[`4ab7df25f`](http://github.com/eggjs/egg/commit/4ab7df25f152609d494745eac2794b78e66444f0)] - deps: update dependencies, add @types/urllib to autod config (#2423) (Yiyu He <>) +- [[`4b602d037`](http://github.com/eggjs/egg/commit/4b602d037554b72c8261b7abb7efd94f8f59f3fe)] - fix: make singleton work for unextensible or frozen instance (#2472) (Yiyu He <>) +- [[`824200c11`](http://github.com/eggjs/egg/commit/824200c11cac8e20b2c275daa7f5a4a365c71259)] - feat: add time duration for dump config (#2485) (Haoliang Gao <>) +- [[`73dac083d`](http://github.com/eggjs/egg/commit/73dac083d2a029f893e9b6737080c921027e308f)] - docs: update wxapp-socket-io project to weapp.socket.io (#2421) (liuguili <>) +- [[`1ada8e384`](http://github.com/eggjs/egg/commit/1ada8e3848be9f09680d7cac091fb14206df5a11)] - feat(d.ts): add middleware to Application and other ts improvement (#2465) (Axes <>) +- [[`437785315`](http://github.com/eggjs/egg/commit/437785315f28a828ea0cf7bece80223d5b796dc5)] - docs: fix the code error of LOCALS in view.md (#2464) (zjz19901029 <<346663801@qq.com>>) +- [[`f341b9fb8`](http://github.com/eggjs/egg/commit/f341b9fb8bdf36b6280500578e8448c59aec10f1)] - chore: update title and remove unused files (#2433) (TZ | + ๅคฉ็Œช <>) +- [[`a5ab29cbd`](http://github.com/eggjs/egg/commit/a5ab29cbd1de0f5425019085258a496b4bce8b45)] - docs: switch to English document (#2426) (Haoliang Gao <>) +- [[`4ab7df25f`](http://github.com/eggjs/egg/commit/4ab7df25f152609d494745eac2794b78e66444f0)] - deps: update dependencies, add @types/urllib to autod config (#2423) (Yiyu He <>) ## 2018-04-17, Version 2.7.1 @dead-horse ### Notable changes -* **fix** - * imporve compatibility of singleton +- **fix** + - imporve compatibility of singleton ### Commits - * [[`e4d219f`](http://github.com/eggjs/egg/commit/e4d219f1aaecbca13601c7813e57c67934e8c32b)] - fix: imporve compatibility of singleton (#2410) (Yiyu He <>) +- [[`e4d219f`](http://github.com/eggjs/egg/commit/e4d219f1aaecbca13601c7813e57c67934e8c32b)] - fix: imporve compatibility of singleton (#2410) (Yiyu He <>) ## 2018-04-16, Version 2.7.0 @dead-horse [DEPRECATED] ### Notable changes -* **feature** - * singleton support asynchronous create function +- **feature** + - singleton support asynchronous create function -* **fix** - * dump config support circular json +- **fix** + - dump config support circular json -* **docs** - * improve router and typescript +- **docs** + - improve router and typescript ### Commits - * [[`3d499a9`](http://github.com/eggjs/egg/commit/3d499a90bab7095569e115e223de40e63812f2f5)] - docs(plugin): add singleton support async create function (#2392) (Yiyu He <>) - * [[`05d925f`](http://github.com/eggjs/egg/commit/05d925fea4e0b2d8efa48cb01ced2133c0c059cd)] - docs: change English document on Readme (#2397) (Haoliang Gao <>) - * [[`590bd8c`](http://github.com/eggjs/egg/commit/590bd8cb400845706ec7cc84232b812cb468c8ac)] - fix: dumpConfig support circular json (#2394) (Yiyu He <>) - * [[`3a489b6`](http://github.com/eggjs/egg/commit/3a489b6f47b39ff2ec31efe936504918300b3f08)] - feat(singleton): support async create function (#2382) (Yiyu He <>) - * [[`a5b6731`](http://github.com/eggjs/egg/commit/a5b673133b35e9b005e19c1e3267a2ff3d58e32b)] - docs: chore for router and typescript (#2390) (TZ | ๅคฉ็Œช <>) - * [[`ee2d2b3`](http://github.com/eggjs/egg/commit/ee2d2b3c33671a822b45a6c474d3710aab5e70d5)] - docs(passport): translation for passport tutorial (#2235) (Cemre Mengu <>) - * [[`6fad4e1`](http://github.com/eggjs/egg/commit/6fad4e1bed3c388e964fc656244e5e606b258085)] - chore: update package.json for release (#2381) (TZ | ๅคฉ็Œช <>) +- [[`3d499a9`](http://github.com/eggjs/egg/commit/3d499a90bab7095569e115e223de40e63812f2f5)] - docs(plugin): add singleton support async create function (#2392) (Yiyu He <>) +- [[`05d925f`](http://github.com/eggjs/egg/commit/05d925fea4e0b2d8efa48cb01ced2133c0c059cd)] - docs: change English document on Readme (#2397) (Haoliang Gao <>) +- [[`590bd8c`](http://github.com/eggjs/egg/commit/590bd8cb400845706ec7cc84232b812cb468c8ac)] - fix: dumpConfig support circular json (#2394) (Yiyu He <>) +- [[`3a489b6`](http://github.com/eggjs/egg/commit/3a489b6f47b39ff2ec31efe936504918300b3f08)] - feat(singleton): support async create function (#2382) (Yiyu He <>) +- [[`a5b6731`](http://github.com/eggjs/egg/commit/a5b673133b35e9b005e19c1e3267a2ff3d58e32b)] - docs: chore for router and typescript (#2390) (TZ | ๅคฉ็Œช <>) +- [[`ee2d2b3`](http://github.com/eggjs/egg/commit/ee2d2b3c33671a822b45a6c474d3710aab5e70d5)] - docs(passport): translation for passport tutorial (#2235) (Cemre Mengu <>) +- [[`6fad4e1`](http://github.com/eggjs/egg/commit/6fad4e1bed3c388e964fc656244e5e606b258085)] - chore: update package.json for release (#2381) (TZ | ๅคฉ็Œช <>) ## 2018-04-12, Version 2.6.1 @atian25 ### Notable changes -* **docs** - * TypeScript Guide (#2324) - * fix d.ts with ts support - * docs improve +- **docs** + - TypeScript Guide (#2324) + - fix d.ts with ts support + - docs improve ### Commits - * [[`2998bf733`](http://github.com/eggjs/egg/commit/2998bf733268d4d88d5fc77e05943b3fa0f824d4)] - chore(typings): add index signature of EggAppConfig (#2359) (waiting <>) - * [[`5f2358bbd`](http://github.com/eggjs/egg/commit/5f2358bbdd6e21a1ab387a8425d0fefc30954227)] - docs: intro session.renew in the doc (#2375) (Yiyu He <>) - * [[`f0e7773f2`](http://github.com/eggjs/egg/commit/f0e7773f28eb7a233230a847ff2f8bc737aa3c01)] - docs: add TypeScript Guide (#2324) (TZ | ๅคฉ็Œช <>) - * [[`cd418f57a`](http://github.com/eggjs/egg/commit/cd418f57a843b504dcac6d8c25b99026e1edf072)] - docs(controller): add ctx.redirect (#2373) (Yiyu He <>) - * [[`2fafb16b8`](http://github.com/eggjs/egg/commit/2fafb16b8810e41b86d15f51257c2a0531c78357)] - docs(socketio): update demo & solve problem on chrome (#2354) (Suyi <>) - * [[`ba708ca4e`](http://github.com/eggjs/egg/commit/ba708ca4e911a345d2ee6aea5d4cf5845f93212b)] - feat: support customized client error (#2283) (Khaidi Chu <>) - * [[`8697140d6`](http://github.com/eggjs/egg/commit/8697140d6ab10f42980ea301e7122331b6e5573a)] - chore: add export to declarations (#2344) (Axes <>) - * [[`441884145`](http://github.com/eggjs/egg/commit/4418841452a20a4fcca212e17dad0fbe9ff97646)] - chore(typings): export PowerPartial (#2327) (waiting <>) - * [[`33d39519e`](http://github.com/eggjs/egg/commit/33d39519e1bd9bb1451776abe4986cdf4dee7626)] - docs(passport): config passport-github behind of proxy (#2318) (Suyi <>) - * [[`84e0dc4e7`](http://github.com/eggjs/egg/commit/84e0dc4e74e4e907d39b5485e1b19c3900aec393)] - fix(d.ts): add modifier to plugin and add middleware to config (#2322) (Axes <>) +- [[`2998bf733`](http://github.com/eggjs/egg/commit/2998bf733268d4d88d5fc77e05943b3fa0f824d4)] - chore(typings): add index signature of EggAppConfig (#2359) (waiting <>) +- [[`5f2358bbd`](http://github.com/eggjs/egg/commit/5f2358bbdd6e21a1ab387a8425d0fefc30954227)] - docs: intro session.renew in the doc (#2375) (Yiyu He <>) +- [[`f0e7773f2`](http://github.com/eggjs/egg/commit/f0e7773f28eb7a233230a847ff2f8bc737aa3c01)] - docs: add TypeScript Guide (#2324) (TZ | ๅคฉ็Œช <>) +- [[`cd418f57a`](http://github.com/eggjs/egg/commit/cd418f57a843b504dcac6d8c25b99026e1edf072)] - docs(controller): add ctx.redirect (#2373) (Yiyu He <>) +- [[`2fafb16b8`](http://github.com/eggjs/egg/commit/2fafb16b8810e41b86d15f51257c2a0531c78357)] - docs(socketio): update demo & solve problem on chrome (#2354) (Suyi <>) +- [[`ba708ca4e`](http://github.com/eggjs/egg/commit/ba708ca4e911a345d2ee6aea5d4cf5845f93212b)] - feat: support customized client error (#2283) (Khaidi Chu <>) +- [[`8697140d6`](http://github.com/eggjs/egg/commit/8697140d6ab10f42980ea301e7122331b6e5573a)] - chore: add export to declarations (#2344) (Axes <>) +- [[`441884145`](http://github.com/eggjs/egg/commit/4418841452a20a4fcca212e17dad0fbe9ff97646)] - chore(typings): export PowerPartial (#2327) (waiting <>) +- [[`33d39519e`](http://github.com/eggjs/egg/commit/33d39519e1bd9bb1451776abe4986cdf4dee7626)] - docs(passport): config passport-github behind of proxy (#2318) (Suyi <>) +- [[`84e0dc4e7`](http://github.com/eggjs/egg/commit/84e0dc4e74e4e907d39b5485e1b19c3900aec393)] - fix(d.ts): add modifier to plugin and add middleware to config (#2322) (Axes <>) ## 2018-04-04, Version 2.6.0 @atian25 ### Notable changes -* **feature** - * TypeScript tool support (#2272) +- **feature** + - TypeScript tool support (#2272) -* **docs** - * improve d.ts with ts support (#2306) - * docs improve and translation +- **docs** + - improve d.ts with ts support (#2306) + - docs improve and translation ### Commits - * [[`406142758`](http://github.com/eggjs/egg/commit/40614275845f49512e80d1c8c00d1997ee91b113)] - chore: improve d.ts with ts support (#2306) (Axes <>) - * [[`7fba689b7`](http://github.com/eggjs/egg/commit/7fba689b73fa46fdf7447844338a7f538ad78665)] - docs(controller): session example bug (#2313) (Suyi <>) - * [[`e0e7ed146`](http://github.com/eggjs/egg/commit/e0e7ed146adfe932558628b815caa2d8c64d6939)] - chore(typings): change export interface to class definition (#2293) (waiting <>) - * [[`161107929`](http://github.com/eggjs/egg/commit/1611079291ddcf8cc82dba40a2406dcad20b75b5)] - docs(plugin): add config notice for `addSingleton` function (#2305) (Shangbin Yang <>) - * [[`1c74a8491`](http://github.com/eggjs/egg/commit/1c74a84918869ec035c5767884501a87cce945d5)] - docs: add assets document (#2220) (Haoliang Gao <>) - * [[`e4531e563`](http://github.com/eggjs/egg/commit/e4531e563214472e54b4c467e0d2879e6390cb52)] - docs: EN translation for view plugin dev doc (#2240) (Cemre Mengu <>) - * [[`348ff18d8`](http://github.com/eggjs/egg/commit/348ff18d82e357d9bceba5136c339ef7dfb44bda)] - docs: EN translation for style guide doc (#2239) (Cemre Mengu <>) - * [[`d9c4ec2bb`](http://github.com/eggjs/egg/commit/d9c4ec2bbb3aa29ddcba2efceec6edfa879267d7)] - EN translation for resources doc (#2238) (Cemre Mengu <>) - * [[`46217a5d2`](http://github.com/eggjs/egg/commit/46217a5d2e451433ec86614cfb65336300a074d9)] - docs(security): add ssrf in security (#2274) (Yiyu He <>) - * [[`c3586eab5`](http://github.com/eggjs/egg/commit/c3586eab535ee540ffac664f0311c656ef7adca2)] - docs: deprecate ignoreJSON (#2270) (Yiyu He <>) - * [[`a86334c59`](http://github.com/eggjs/egg/commit/a86334c595530c5f4e9cf65204a4591dfd26bcf0)] - docs: example for custom id when mysql update (#2165) (OnedayLiu <>) - * [[`10327e185`](http://github.com/eggjs/egg/commit/10327e185015098c9c29747abbaf79a352f975d7)] - docs: EN translation for socketio tutorial doc (#2167) (Cemre Mengu <>) - * [[`5b059db6a`](http://github.com/eggjs/egg/commit/5b059db6a879abb3ffe7b30e95855afc8a660107)] - docs: add boilerplate type desc (#2250) (QiChang Li <>) - * [[`9007b5847`](http://github.com/eggjs/egg/commit/9007b5847e67b678f6624da4610b6bdff9457c52)] - chore: update package.json for release (#2244) (Haoliang Gao <>) +- [[`406142758`](http://github.com/eggjs/egg/commit/40614275845f49512e80d1c8c00d1997ee91b113)] - chore: improve d.ts with ts support (#2306) (Axes <>) +- [[`7fba689b7`](http://github.com/eggjs/egg/commit/7fba689b73fa46fdf7447844338a7f538ad78665)] - docs(controller): session example bug (#2313) (Suyi <>) +- [[`e0e7ed146`](http://github.com/eggjs/egg/commit/e0e7ed146adfe932558628b815caa2d8c64d6939)] - chore(typings): change export interface to class definition (#2293) (waiting <>) +- [[`161107929`](http://github.com/eggjs/egg/commit/1611079291ddcf8cc82dba40a2406dcad20b75b5)] - docs(plugin): add config notice for `addSingleton` function (#2305) (Shangbin Yang <>) +- [[`1c74a8491`](http://github.com/eggjs/egg/commit/1c74a84918869ec035c5767884501a87cce945d5)] - docs: add assets document (#2220) (Haoliang Gao <>) +- [[`e4531e563`](http://github.com/eggjs/egg/commit/e4531e563214472e54b4c467e0d2879e6390cb52)] - docs: EN translation for view plugin dev doc (#2240) (Cemre Mengu <>) +- [[`348ff18d8`](http://github.com/eggjs/egg/commit/348ff18d82e357d9bceba5136c339ef7dfb44bda)] - docs: EN translation for style guide doc (#2239) (Cemre Mengu <>) +- [[`d9c4ec2bb`](http://github.com/eggjs/egg/commit/d9c4ec2bbb3aa29ddcba2efceec6edfa879267d7)] - EN translation for resources doc (#2238) (Cemre Mengu <>) +- [[`46217a5d2`](http://github.com/eggjs/egg/commit/46217a5d2e451433ec86614cfb65336300a074d9)] - docs(security): add ssrf in security (#2274) (Yiyu He <>) +- [[`c3586eab5`](http://github.com/eggjs/egg/commit/c3586eab535ee540ffac664f0311c656ef7adca2)] - docs: deprecate ignoreJSON (#2270) (Yiyu He <>) +- [[`a86334c59`](http://github.com/eggjs/egg/commit/a86334c595530c5f4e9cf65204a4591dfd26bcf0)] - docs: example for custom id when mysql update (#2165) (OnedayLiu <>) +- [[`10327e185`](http://github.com/eggjs/egg/commit/10327e185015098c9c29747abbaf79a352f975d7)] - docs: EN translation for socketio tutorial doc (#2167) (Cemre Mengu <>) +- [[`5b059db6a`](http://github.com/eggjs/egg/commit/5b059db6a879abb3ffe7b30e95855afc8a660107)] - docs: add boilerplate type desc (#2250) (QiChang Li <>) +- [[`9007b5847`](http://github.com/eggjs/egg/commit/9007b5847e67b678f6624da4610b6bdff9457c52)] - chore: update package.json for release (#2244) (Haoliang Gao <>) ## 2018-03-20, Version 2.5.0 @atian25 ### Notable changes -* **feature** - * display router when log app (#2230) - * update `favicon.png` - * upgrade cluster-client to 2.x (#2236) +- **feature** + - display router when log app (#2230) + - update `favicon.png` + - upgrade cluster-client to 2.x (#2236) -* **docs** - * improve d.ts - * add socket.io webchat description (#2198) +- **docs** + - improve d.ts + - add socket.io webchat description (#2198) ### Commits - * [[`6040d6f8f`](http://github.com/eggjs/egg/commit/6040d6f8f1a67282ff697c6d86945bc0cb487fe6)] - chore: fix spelling error rotator (#2242) (HE ZIQIANG <>) - * [[`1554da57e`](http://github.com/eggjs/egg/commit/1554da57ef9d8b0fd2cb023a0cc68b50bee6b69f)] - chore: upgrade cluster-client to 2.x (#2236) (zลng yว” <>) - * [[`9faa052bf`](http://github.com/eggjs/egg/commit/9faa052bfdffe887c1557126a73a62fe2e462dc5)] - feat: tsd add init module (#2233) (Eward Song <>) - * [[`d5f9059f1`](http://github.com/eggjs/egg/commit/d5f9059f1935a67748033143081755811664df9d)] - docs: translation for basic plugin (#2166) (Cemre Mengu <>) - * [[`7afc7e24b`](http://github.com/eggjs/egg/commit/7afc7e24b60776a71702ae5495d637b1ac4a3d06)] - feat: display router when log app (#2230) (Kiho ยท Cham <>) - * [[`5e99fd6fd`](http://github.com/eggjs/egg/commit/5e99fd6fd86be4de5a2eca24bc2025f120cef6aa)] - docs: egg-passsport-local -> egg-passport-local (ๆฅŠๅ‚‘ๆ–‡ Chuck Yang <>) - * [[`c042366df`](http://github.com/eggjs/egg/commit/c042366df6a691e56c528f16083516a53e114944)] - docs(socket.io): add webchat description (#2198) (TZ | ๅคฉ็Œช <>) - * [[`5cce8795a`](http://github.com/eggjs/egg/commit/5cce8795a733c9096de6e050fec5a87be99b0002)] - chore: fix typo. (#2172) (่–›ๅฎš่ฐ”็š„็Œซ <>) +- [[`6040d6f8f`](http://github.com/eggjs/egg/commit/6040d6f8f1a67282ff697c6d86945bc0cb487fe6)] - chore: fix spelling error rotator (#2242) (HE ZIQIANG <>) +- [[`1554da57e`](http://github.com/eggjs/egg/commit/1554da57ef9d8b0fd2cb023a0cc68b50bee6b69f)] - chore: upgrade cluster-client to 2.x (#2236) (zลng yว” <>) +- [[`9faa052bf`](http://github.com/eggjs/egg/commit/9faa052bfdffe887c1557126a73a62fe2e462dc5)] - feat: tsd add init module (#2233) (Eward Song <>) +- [[`d5f9059f1`](http://github.com/eggjs/egg/commit/d5f9059f1935a67748033143081755811664df9d)] - docs: translation for basic plugin (#2166) (Cemre Mengu <>) +- [[`7afc7e24b`](http://github.com/eggjs/egg/commit/7afc7e24b60776a71702ae5495d637b1ac4a3d06)] - feat: display router when log app (#2230) (Kiho ยท Cham <>) +- [[`5e99fd6fd`](http://github.com/eggjs/egg/commit/5e99fd6fd86be4de5a2eca24bc2025f120cef6aa)] - docs: egg-passsport-local -> egg-passport-local (ๆฅŠๅ‚‘ๆ–‡ Chuck Yang <>) +- [[`c042366df`](http://github.com/eggjs/egg/commit/c042366df6a691e56c528f16083516a53e114944)] - docs(socket.io): add webchat description (#2198) (TZ | ๅคฉ็Œช <>) +- [[`5cce8795a`](http://github.com/eggjs/egg/commit/5cce8795a733c9096de6e050fec5a87be99b0002)] - chore: fix typo. (#2172) (่–›ๅฎš่ฐ”็š„็Œซ <>) ## 2018-03-05, Version 2.4.1 @dead-horse ### Notable changes -* **fix** - * [security] don't allow x-forwarded-host header by default - * `ctx.runInBackground` will try to use custom function name first +- **fix** + - [security] don't allow x-forwarded-host header by default + - `ctx.runInBackground` will try to use custom function name first -* **docs** - * improve d.ts - * add regexp as type of path in Router - * fix type of `render` - * more semantic and moment installation in quickstart +- **docs** + - improve d.ts + - add regexp as type of path in Router + - fix type of `render` + - more semantic and moment installation in quickstart ### Commits - * [[`0eabce6`](http://github.com/eggjs/egg/commit/0eabce6389190cecc00011512ec7e4e63fd0471e)] - fix: don't allow x-forwarded-host header (#2163) (Haoliang Gao <>) - * [[`f0edf96`](http://github.com/eggjs/egg/commit/f0edf9622b6a18831f285e6ceb5a0e2b25b04fd0)] - fix: try to use custom function name first (#2161) (fengmk2 <>) - * [[`1a73720`](http://github.com/eggjs/egg/commit/1a73720d8ba14c612cc6fd38d419212e032049f8)] - fix(typings): add regexp as type of path (#2157) (AngrySean <>) - * [[`b55e908`](http://github.com/eggjs/egg/commit/b55e908643dc2ef1a21c7a4b11559e1785985792)] - doc(quickstart): more semantic and moment installation (#2154) (Kiho ยท Cham <>) - * [[`951e236`](http://github.com/eggjs/egg/commit/951e236586f3fdc988504f4138351b2c7778e67c)] - Fix type of `render` (#2155) (Arniu Tseng <>) +- [[`0eabce6`](http://github.com/eggjs/egg/commit/0eabce6389190cecc00011512ec7e4e63fd0471e)] - fix: don't allow x-forwarded-host header (#2163) (Haoliang Gao <>) +- [[`f0edf96`](http://github.com/eggjs/egg/commit/f0edf9622b6a18831f285e6ceb5a0e2b25b04fd0)] - fix: try to use custom function name first (#2161) (fengmk2 <>) +- [[`1a73720`](http://github.com/eggjs/egg/commit/1a73720d8ba14c612cc6fd38d419212e032049f8)] - fix(typings): add regexp as type of path (#2157) (AngrySean <>) +- [[`b55e908`](http://github.com/eggjs/egg/commit/b55e908643dc2ef1a21c7a4b11559e1785985792)] - doc(quickstart): more semantic and moment installation (#2154) (Kiho ยท Cham <>) +- [[`951e236`](http://github.com/eggjs/egg/commit/951e236586f3fdc988504f4138351b2c7778e67c)] - Fix type of `render` (#2155) (Arniu Tseng <>) ## 2018-02-28, Version 2.4.0, @fengmk2 ### Notable changes -* **feature** - * support Keep-Alive Header - -* **fix** - * add logger in base_context_class - -* **docs** - * Lots of d.ts improved. - * add context - * add urllib - * add resources & logger - * new documents - * how to call the service - * socket.io tutorial - * add events on application - -### Commits - - * [[`79927324a`](http://github.com/eggjs/egg/commit/79927324a5aeb1f826fc9f133bed253d8324c62e)] - fix: add logger in base_context_class (#2149) (Axes <>) - * [[`a73900231`](http://github.com/eggjs/egg/commit/a7390023150ff4d5a7ec069276a94542a7ef67fa)] - feat: support Keep-Alive Header (#2146) (fengmk2 <>) - * [[`c8284367c`](http://github.com/eggjs/egg/commit/c8284367c727aa2da453a1a485c4d7f97cfb3967)] - docs(ts): fix some d.ts (#2144) (TZ | ๅคฉ็Œช <>) - * [[`e0282b923`](http://github.com/eggjs/egg/commit/e0282b923375132fcc3b936b471999a84eb1e941)] - docs(router): add definition of ctx (#2136) (้‡ๅบ† <<1756260160@qq.com>>) - * [[`3e7ef6aa5`](http://github.com/eggjs/egg/commit/3e7ef6aa566d800411822d9a4195c9df34634789)] - docs(app-start): how to call service (#2133) (TZ | ๅคฉ็Œช <>) - * [[`9472b5828`](http://github.com/eggjs/egg/commit/9472b5828c95cd1dec2910b657d1e6c34372a6a2)] - docs(schedule): fix log dir (#2123) (TZ | ๅคฉ็Œช <>) - * [[`ede433fc5`](http://github.com/eggjs/egg/commit/ede433fc594c915683a519bf9b409209812806cf)] - docs(unittest):fix some mistakes (#2110) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`2d03c79a1`](http://github.com/eggjs/egg/commit/2d03c79a1842846c4caf2f3b971a5bae5fc9f24d)] - chore: add urllib declaration support in index.d.ts (#2117) (SoraYama <>) - * [[`fd6fa2495`](http://github.com/eggjs/egg/commit/fd6fa24955a7a7bceaad7b2f754123282b7e1cbe)] - docs(2.x-advanced-plugin):fix some descriptions (#2111) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`0a208d741`](http://github.com/eggjs/egg/commit/0a208d7413d77f12048df91b6bdb6e2dfd047c89)] - docs: translation for advanced/plugin.md (#2075) (DukeFightLife <>) - * [[`42e4ea4c1`](http://github.com/eggjs/egg/commit/42e4ea4c12a542671bac7ca92931e83d0fc439f4)] - docs(schedule):fix some places (#2105) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`63278c229`](http://github.com/eggjs/egg/commit/63278c2293b0899165386288c38cac44aa7a0b71)] - docs(2.x-basic-extend):fix some mistakes (#2107) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`7a604d37f`](http://github.com/eggjs/egg/commit/7a604d37f5184c268263779fa2b8ca459e3d6f5b)] - docs(2.x-basic-service):fix some mistakes of service (#2102) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`a1a4e7dd3`](http://github.com/eggjs/egg/commit/a1a4e7dd32bf040b69e8c8bfbdcae3e483eee335)] - docs(plugin): add description for plugin.local.js (#2104) (TZ | ๅคฉ็Œช <>) - * [[`2cdfcc249`](http://github.com/eggjs/egg/commit/2cdfcc249863630dbb298374dbbe2b45864a0e1c)] - docs(development): adjust to new version vscode (#2098) (TZ | ๅคฉ็Œช <>) - * [[`bb4b29002`](http://github.com/eggjs/egg/commit/bb4b290027a6dcf8404ae357e29aaa6a76d5413a)] - docs(faq): add the most common mistake of config (#2086) (TZ | ๅคฉ็Œช <>) - * [[`5621a8574`](http://github.com/eggjs/egg/commit/5621a8574b60d61dab79f601105b69710559831c)] - docs(schedule): logging && args (#2091) (TZ | ๅคฉ็Œช <>) - * [[`03a894439`](http://github.com/eggjs/egg/commit/03a89443904211785ca600ec74f78d75bbf7a299)] - docs: d.ts of resources& logger (#2079) (x22x22 <>) - * [[`bbfacc5a7`](http://github.com/eggjs/egg/commit/bbfacc5a75984a7ddc111195b51d7da8bd6d0713)] - docs(middleware): use app.middleware instead of app.middlewares (#2077) (x22x22 <>) - * [[`7e9f330ee`](http://github.com/eggjs/egg/commit/7e9f330eea2efcc26e99eb89ad3fb40c517e0101)] - docs(socket.io): add tutorial (#1913) (Suyi <>) - * [[`1224dd65f`](http://github.com/eggjs/egg/commit/1224dd65f2e4dadcce70d9a6e8e66122d93fbdd7)] - docs(2.x-basic-controller):fix some descriptions of basic-controller (#2043) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`fa5bdaeb5`](http://github.com/eggjs/egg/commit/fa5bdaeb5fec6385f81bc4c3781036df3fa6d870)] - style(app/extend/request.js): Some Comments from Chinese To English in union (#2051) (DongWei <>) - * [[`06e7710c7`](http://github.com/eggjs/egg/commit/06e7710c73c5f4ad313d08b770e5874919e21b88)] - docs: add events on application (#2039) (Yiyu He <>) - * [[`65e038132`](http://github.com/eggjs/egg/commit/65e038132c9183c66c11fb50e3a8bc6358cdae4c)] - docs(advanced/loader): translate (#1654) (Weilun Xiong <>) +- **feature** + - support Keep-Alive Header + +- **fix** + - add logger in base_context_class + +- **docs** + - Lots of d.ts improved. + - add context + - add urllib + - add resources & logger + - new documents + - how to call the service + - socket.io tutorial + - add events on application + +### Commits + +- [[`79927324a`](http://github.com/eggjs/egg/commit/79927324a5aeb1f826fc9f133bed253d8324c62e)] - fix: add logger in base_context_class (#2149) (Axes <>) +- [[`a73900231`](http://github.com/eggjs/egg/commit/a7390023150ff4d5a7ec069276a94542a7ef67fa)] - feat: support Keep-Alive Header (#2146) (fengmk2 <>) +- [[`c8284367c`](http://github.com/eggjs/egg/commit/c8284367c727aa2da453a1a485c4d7f97cfb3967)] - docs(ts): fix some d.ts (#2144) (TZ | ๅคฉ็Œช <>) +- [[`e0282b923`](http://github.com/eggjs/egg/commit/e0282b923375132fcc3b936b471999a84eb1e941)] - docs(router): add definition of ctx (#2136) (้‡ๅบ† <<1756260160@qq.com>>) +- [[`3e7ef6aa5`](http://github.com/eggjs/egg/commit/3e7ef6aa566d800411822d9a4195c9df34634789)] - docs(app-start): how to call service (#2133) (TZ | ๅคฉ็Œช <>) +- [[`9472b5828`](http://github.com/eggjs/egg/commit/9472b5828c95cd1dec2910b657d1e6c34372a6a2)] - docs(schedule): fix log dir (#2123) (TZ | ๅคฉ็Œช <>) +- [[`ede433fc5`](http://github.com/eggjs/egg/commit/ede433fc594c915683a519bf9b409209812806cf)] - docs(unittest):fix some mistakes (#2110) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`2d03c79a1`](http://github.com/eggjs/egg/commit/2d03c79a1842846c4caf2f3b971a5bae5fc9f24d)] - chore: add urllib declaration support in index.d.ts (#2117) (SoraYama <>) +- [[`fd6fa2495`](http://github.com/eggjs/egg/commit/fd6fa24955a7a7bceaad7b2f754123282b7e1cbe)] - docs(2.x-advanced-plugin):fix some descriptions (#2111) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`0a208d741`](http://github.com/eggjs/egg/commit/0a208d7413d77f12048df91b6bdb6e2dfd047c89)] - docs: translation for advanced/plugin.md (#2075) (DukeFightLife <>) +- [[`42e4ea4c1`](http://github.com/eggjs/egg/commit/42e4ea4c12a542671bac7ca92931e83d0fc439f4)] - docs(schedule):fix some places (#2105) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`63278c229`](http://github.com/eggjs/egg/commit/63278c2293b0899165386288c38cac44aa7a0b71)] - docs(2.x-basic-extend):fix some mistakes (#2107) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`7a604d37f`](http://github.com/eggjs/egg/commit/7a604d37f5184c268263779fa2b8ca459e3d6f5b)] - docs(2.x-basic-service):fix some mistakes of service (#2102) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`a1a4e7dd3`](http://github.com/eggjs/egg/commit/a1a4e7dd32bf040b69e8c8bfbdcae3e483eee335)] - docs(plugin): add description for plugin.local.js (#2104) (TZ | ๅคฉ็Œช <>) +- [[`2cdfcc249`](http://github.com/eggjs/egg/commit/2cdfcc249863630dbb298374dbbe2b45864a0e1c)] - docs(development): adjust to new version vscode (#2098) (TZ | ๅคฉ็Œช <>) +- [[`bb4b29002`](http://github.com/eggjs/egg/commit/bb4b290027a6dcf8404ae357e29aaa6a76d5413a)] - docs(faq): add the most common mistake of config (#2086) (TZ | ๅคฉ็Œช <>) +- [[`5621a8574`](http://github.com/eggjs/egg/commit/5621a8574b60d61dab79f601105b69710559831c)] - docs(schedule): logging && args (#2091) (TZ | ๅคฉ็Œช <>) +- [[`03a894439`](http://github.com/eggjs/egg/commit/03a89443904211785ca600ec74f78d75bbf7a299)] - docs: d.ts of resources& logger (#2079) (x22x22 <>) +- [[`bbfacc5a7`](http://github.com/eggjs/egg/commit/bbfacc5a75984a7ddc111195b51d7da8bd6d0713)] - docs(middleware): use app.middleware instead of app.middlewares (#2077) (x22x22 <>) +- [[`7e9f330ee`](http://github.com/eggjs/egg/commit/7e9f330eea2efcc26e99eb89ad3fb40c517e0101)] - docs(socket.io): add tutorial (#1913) (Suyi <>) +- [[`1224dd65f`](http://github.com/eggjs/egg/commit/1224dd65f2e4dadcce70d9a6e8e66122d93fbdd7)] - docs(2.x-basic-controller):fix some descriptions of basic-controller (#2043) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`fa5bdaeb5`](http://github.com/eggjs/egg/commit/fa5bdaeb5fec6385f81bc4c3781036df3fa6d870)] - style(app/extend/request.js): Some Comments from Chinese To English in union (#2051) (DongWei <>) +- [[`06e7710c7`](http://github.com/eggjs/egg/commit/06e7710c73c5f4ad313d08b770e5874919e21b88)] - docs: add events on application (#2039) (Yiyu He <>) +- [[`65e038132`](http://github.com/eggjs/egg/commit/65e038132c9183c66c11fb50e3a8bc6358cdae4c)] - docs(advanced/loader): translate (#1654) (Weilun Xiong <>) ## 2018-01-26, Version 2.3.0, @dead-horse ### Notable changes -* **feature** - * emit `request` and `response` event in every request +- **feature** + - emit `request` and `response` event in every request -* **docs** - * improve english docs - * add alinode usage +- **docs** + - improve english docs + - add alinode usage ### Commits - * [[`50a0f8a`](http://github.com/eggjs/egg/commit/50a0f8ac8fe246d664f73f171b8886f9b9c2eda7)] - doc: fix deploy example (dead-horse <>) - * [[`3b7a313`](http://github.com/eggjs/egg/commit/3b7a313965f9c8ae6e20a16dd74533b1885f216f)] - docs(deploy): more about alinode (#2036) (TZ | ๅคฉ็Œช <>) - * [[`950b9e6`](http://github.com/eggjs/egg/commit/950b9e684f2441674ed85a3c0152002991d2ff86)] - doc: fix deploy docs (dead-horse <>) - * [[`18d6436`](http://github.com/eggjs/egg/commit/18d6436195ca1a73098c643d39ce4560b20e7d76)] - docs: translate advanced/cluster-client.md (#1839) (ๅญฆ็ฉถ <>) - * [[`287c761`](http://github.com/eggjs/egg/commit/287c7615ad425b130e2c669a41409bfa763feef2)] - Update deployment.md (#1979) (juju <>) - * [[`22dfaa7`](http://github.com/eggjs/egg/commit/22dfaa72e3851196153f4ecb7f3599d2951e9b1b)] - feat: emit request and response event (#2020) (Yiyu He <>) - * [[`ddbb4b3`](http://github.com/eggjs/egg/commit/ddbb4b3c0ec7cfc5c9b1baa7e678770613bd4761)] - docs(deploy): add alinode (#2025) (TZ | ๅคฉ็Œช <>) - * [[`b5d823f`](http://github.com/eggjs/egg/commit/b5d823f52a770f879da46c6968adadd3fa14e8d7)] - docs(core/unittest): fix path of helper.js(#2029) (#2030) (Jiulong Hu <>) - * [[`1e3a4b3`](http://github.com/eggjs/egg/commit/1e3a4b35801e136dd4f1fbaf3c49b771a50c0f72)] - docs(basic-router):fix some places of basic-router (#2012) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`50a0f8a`](http://github.com/eggjs/egg/commit/50a0f8ac8fe246d664f73f171b8886f9b9c2eda7)] - doc: fix deploy example (dead-horse <>) +- [[`3b7a313`](http://github.com/eggjs/egg/commit/3b7a313965f9c8ae6e20a16dd74533b1885f216f)] - docs(deploy): more about alinode (#2036) (TZ | ๅคฉ็Œช <>) +- [[`950b9e6`](http://github.com/eggjs/egg/commit/950b9e684f2441674ed85a3c0152002991d2ff86)] - doc: fix deploy docs (dead-horse <>) +- [[`18d6436`](http://github.com/eggjs/egg/commit/18d6436195ca1a73098c643d39ce4560b20e7d76)] - docs: translate advanced/cluster-client.md (#1839) (ๅญฆ็ฉถ <>) +- [[`287c761`](http://github.com/eggjs/egg/commit/287c7615ad425b130e2c669a41409bfa763feef2)] - Update deployment.md (#1979) (juju <>) +- [[`22dfaa7`](http://github.com/eggjs/egg/commit/22dfaa72e3851196153f4ecb7f3599d2951e9b1b)] - feat: emit request and response event (#2020) (Yiyu He <>) +- [[`ddbb4b3`](http://github.com/eggjs/egg/commit/ddbb4b3c0ec7cfc5c9b1baa7e678770613bd4761)] - docs(deploy): add alinode (#2025) (TZ | ๅคฉ็Œช <>) +- [[`b5d823f`](http://github.com/eggjs/egg/commit/b5d823f52a770f879da46c6968adadd3fa14e8d7)] - docs(core/unittest): fix path of helper.js(#2029) (#2030) (Jiulong Hu <>) +- [[`1e3a4b3`](http://github.com/eggjs/egg/commit/1e3a4b35801e136dd4f1fbaf3c49b771a50c0f72)] - docs(basic-router):fix some places of basic-router (#2012) (ๆฌ็ซน <<2632807692@qq.com>>) ## 2018-01-22, Version 2.2.1, @dead-horse ### Notable changes -* **fix** - * log cookie's key when cookie exceed limit length - -* **document** - * improve english documents, fix some grammars - * add link to alicloud node.js perfomance platform - * use PATCH method in resource router - -### Commits - - * [[`aa46eb2`](http://github.com/eggjs/egg/commit/aa46eb26d45012036c69c524db512ed16fde7b6b)] - fix: log cookie's key when cookie exceed limit length (#1996) (Yiyu He <>) - * [[`7993b45`](http://github.com/eggjs/egg/commit/7993b45ec2af8c2d96d82370d877476786504dc8)] - docs(basic-middleware):fix some descriptions of basic-middleware (#1998) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`b2d09e1`](http://github.com/eggjs/egg/commit/b2d09e150da70a08c1886b00031c0f07eeb7d830)] - docs: put => patch. (#1793) (#1938) (ๅดๅปบ้‡‘ <>) - * [[`dede240`](http://github.com/eggjs/egg/commit/dede240340570c00e3baed8098853a44c902dc21)] - feat: add helper interface in d.ts (#1989) (Axes <>) - * [[`19fe608`](http://github.com/eggjs/egg/commit/19fe6085fedabfc09eb9c26534df237decf4d28e)] - docs: add deer stat (#1974) (TZ | ๅคฉ็Œช <>) - * [[`cef371e`](http://github.com/eggjs/egg/commit/cef371e4a176c62d9b44c0f1e55668e992921d2d)] - docs(basic-env): fix some descriptions base on the Chinese version (#1930) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`55d08bd`](http://github.com/eggjs/egg/commit/55d08bded812b81efeee96a0e3465728c7f4f5a2)] - fix(ts): error declare of route.resource (#1959) (AntSworD <>) - * [[`32d7c81`](http://github.com/eggjs/egg/commit/32d7c8199611b00cd5117e6adcf8904ea0b33ff5)] - docs: fix word error (#1965) (jxDeveloper <<896222652@qq.com>>) - * [[`3acf45f`](http://github.com/eggjs/egg/commit/3acf45f77ef791b1e6467bd4047511d867d46cc9)] - docs(basic-config): fix some word spelling (#1931) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`0e90819`](http://github.com/eggjs/egg/commit/0e9081954a765228ee9d590f01f3bfaaf1a4e5d8)] - docs(advanced/framework): translation (#1668) (freebyron <>) - * [[`ab1b08e`](http://github.com/eggjs/egg/commit/ab1b08ef520ab8db4cddd8f6cf52f1aa87d6975f)] - docs: fix en index (#1915) (Weilun Xiong <>) - * [[`2270f7f`](http://github.com/eggjs/egg/commit/2270f7f0417f9c78958c6b51e70ad7a0d838d6ec)] - docs(basic-objects): fix some descriptions (#1903) (ๆฌ็ซน <<2632807692@qq.com>>) - * [[`c136470`](http://github.com/eggjs/egg/commit/c136470861b35a5f796d4edcdd8f6fbce41f7314)] - test: use Buffer.alloc, Buffer.from. (#1895) (่–›ๅฎš่ฐ”็š„็Œซ <>) - * [[`73bc636`](http://github.com/eggjs/egg/commit/73bc636ddb82bd73fa14fb5f56e8ffe6260b46cc)] - docs(links): Add link to alicloud node.js perfomance platform (#1894) (Jackson Tian <>) - * [[`55d1b0e`](http://github.com/eggjs/egg/commit/55d1b0eb5c4ca27668559b94259f0670b60d57b6)] - docs(deploy): add --ignore-stderr (#1876) (TZ | ๅคฉ็Œช <>) - * [[`532110a`](http://github.com/eggjs/egg/commit/532110abbc01cf3f225c47ed6219d9434c48808c)] - fix: fix 404 page url (#1881) (sam <<289623783@qq.com>>) +- **fix** + - log cookie's key when cookie exceed limit length + +- **document** + - improve english documents, fix some grammars + - add link to alicloud node.js perfomance platform + - use PATCH method in resource router + +### Commits + +- [[`aa46eb2`](http://github.com/eggjs/egg/commit/aa46eb26d45012036c69c524db512ed16fde7b6b)] - fix: log cookie's key when cookie exceed limit length (#1996) (Yiyu He <>) +- [[`7993b45`](http://github.com/eggjs/egg/commit/7993b45ec2af8c2d96d82370d877476786504dc8)] - docs(basic-middleware):fix some descriptions of basic-middleware (#1998) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`b2d09e1`](http://github.com/eggjs/egg/commit/b2d09e150da70a08c1886b00031c0f07eeb7d830)] - docs: put => patch. (#1793) (#1938) (ๅดๅปบ้‡‘ <>) +- [[`dede240`](http://github.com/eggjs/egg/commit/dede240340570c00e3baed8098853a44c902dc21)] - feat: add helper interface in d.ts (#1989) (Axes <>) +- [[`19fe608`](http://github.com/eggjs/egg/commit/19fe6085fedabfc09eb9c26534df237decf4d28e)] - docs: add deer stat (#1974) (TZ | ๅคฉ็Œช <>) +- [[`cef371e`](http://github.com/eggjs/egg/commit/cef371e4a176c62d9b44c0f1e55668e992921d2d)] - docs(basic-env): fix some descriptions base on the Chinese version (#1930) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`55d08bd`](http://github.com/eggjs/egg/commit/55d08bded812b81efeee96a0e3465728c7f4f5a2)] - fix(ts): error declare of route.resource (#1959) (AntSworD <>) +- [[`32d7c81`](http://github.com/eggjs/egg/commit/32d7c8199611b00cd5117e6adcf8904ea0b33ff5)] - docs: fix word error (#1965) (jxDeveloper <<896222652@qq.com>>) +- [[`3acf45f`](http://github.com/eggjs/egg/commit/3acf45f77ef791b1e6467bd4047511d867d46cc9)] - docs(basic-config): fix some word spelling (#1931) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`0e90819`](http://github.com/eggjs/egg/commit/0e9081954a765228ee9d590f01f3bfaaf1a4e5d8)] - docs(advanced/framework): translation (#1668) (freebyron <>) +- [[`ab1b08e`](http://github.com/eggjs/egg/commit/ab1b08ef520ab8db4cddd8f6cf52f1aa87d6975f)] - docs: fix en index (#1915) (Weilun Xiong <>) +- [[`2270f7f`](http://github.com/eggjs/egg/commit/2270f7f0417f9c78958c6b51e70ad7a0d838d6ec)] - docs(basic-objects): fix some descriptions (#1903) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`c136470`](http://github.com/eggjs/egg/commit/c136470861b35a5f796d4edcdd8f6fbce41f7314)] - test: use Buffer.alloc, Buffer.from. (#1895) (่–›ๅฎš่ฐ”็š„็Œซ <>) +- [[`73bc636`](http://github.com/eggjs/egg/commit/73bc636ddb82bd73fa14fb5f56e8ffe6260b46cc)] - docs(links): Add link to alicloud node.js perfomance platform (#1894) (Jackson Tian <>) +- [[`55d1b0e`](http://github.com/eggjs/egg/commit/55d1b0eb5c4ca27668559b94259f0670b60d57b6)] - docs(deploy): add --ignore-stderr (#1876) (TZ | ๅคฉ็Œช <>) +- [[`532110a`](http://github.com/eggjs/egg/commit/532110abbc01cf3f225c47ed6219d9434c48808c)] - fix: fix 404 page url (#1881) (sam <<289623783@qq.com>>) ## 2017-12-26, Version 2.2.0, @dead-horse ### Notable changes -* **feature** - * `config.meta.logging` to enable log every request when received +- **feature** + - `config.meta.logging` to enable log every request when received -* **document** - * fix some grammars - * add rule for issue +- **document** + - fix some grammars + - add rule for issue ### Commits -* [[`9fe5b85`](http://github.com/eggjs/egg/commit/9fe5b8563958d313b02482e5b3fe69c342acfa71)] - feat: enable request started log on meta middleware (#1877) (fengmk2 <>) -* [[`8ce9611`](http://github.com/eggjs/egg/commit/8ce9611e2e2e5098a7a4557e0f8d29cd93ab468c)] - docs(objects): fix some grammars (#1806) (ๆฌ็ซน <<2632807692@qq.com>>) -* [[`e43aa2b`](http://github.com/eggjs/egg/commit/e43aa2bad227475744ef6422f376475d0ee266c4)] - docs(error-handling): fix some words (#1874) (Fan <>) -* [[`4c1617a`](http://github.com/eggjs/egg/commit/4c1617a16ee3df1b455f5eeb1cb31e37e5f593c1)] - docs(faq): add rule for issue (#1861) (TZ | ๅคฉ็Œช <>) +- [[`9fe5b85`](http://github.com/eggjs/egg/commit/9fe5b8563958d313b02482e5b3fe69c342acfa71)] - feat: enable request started log on meta middleware (#1877) (fengmk2 <>) +- [[`8ce9611`](http://github.com/eggjs/egg/commit/8ce9611e2e2e5098a7a4557e0f8d29cd93ab468c)] - docs(objects): fix some grammars (#1806) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`e43aa2b`](http://github.com/eggjs/egg/commit/e43aa2bad227475744ef6422f376475d0ee266c4)] - docs(error-handling): fix some words (#1874) (Fan <>) +- [[`4c1617a`](http://github.com/eggjs/egg/commit/4c1617a16ee3df1b455f5eeb1cb31e37e5f593c1)] - docs(faq): add rule for issue (#1861) (TZ | ๅคฉ็Œช <>) ## 2017-12-15, Version 2.1.0, @dead-horse ### Notable changes -* **feature** - * add 400 response for broken client request to instead of empty response - * dump application router json - -* **fix** - * fix: run dumpConfig at the last ready callback - -* **document** - * migrate docs to egg 2 - * add document for passport - -### Commits - -* [[`40df153`](http://github.com/eggjs/egg/commit/40df153dd7ca8124a7502ba6cdc838835388a0ae)] - feat: add 400 response for broken client request to instead of empty response (#1829) (Khaidi Chu <>) -* [[`d0ee9f2`](http://github.com/eggjs/egg/commit/d0ee9f2500e69a1e0662c9ea597bf97db3418041)] - docs(passport): fix some description (#1828) (TZ | ๅคฉ็Œช <>) -* [[`f7c6a0a`](http://github.com/eggjs/egg/commit/f7c6a0a835ea950e98e40a0b4b83736912b5ab82)] - docs(passport): add description (#1825) (TZ | ๅคฉ็Œช <>) -* [[`f66d9be`](http://github.com/eggjs/egg/commit/f66d9be57807c04058511b47611afa890884b2a5)] - docs(passport): the missing docs for passport (#1824) (TZ | ๅคฉ็Œช <>) -* [[`18f93f0`](http://github.com/eggjs/egg/commit/18f93f0b927a08e6bd356f9fcc6a3141e813e85f)] - docs(core/view.md): translation (#1577) (Zhongyuan <>) -* [[`7e05669`](http://github.com/eggjs/egg/commit/7e056692506f5801390fd804d75bf6756991a54b)] - 1. docs(error-handle): missing function keywords. (#1819) (M.Y.Akashi <>) -* [[`89e114c`](http://github.com/eggjs/egg/commit/89e114cb88ef1ef96e479001bf0f8250867111c9)] - docs: add AntV links (#1809) (TZ | ๅคฉ็Œช <>) -* [[`bdfd3cc`](http://github.com/eggjs/egg/commit/bdfd3cc62b8377cadac2a6c108944d86eaca3df0)] - docs(router): new style & remove app.verb (#1803) (TZ | ๅคฉ็Œช <>) -* [[`4c9eacb`](http://github.com/eggjs/egg/commit/4c9eacbb7d4560924602103e5e23ae578ac34a52)] - docs(middleware): add description of import koa middleware (#1805) (TZ | ๅคฉ็Œช <>) -* [[`c152dee`](http://github.com/eggjs/egg/commit/c152deec69c3dbb06ce87433a46bab0bc61e295b)] - docs(loader): adjust extends way (#1729) (TZ | ๅคฉ็Œช <>) -* [[`289f8cd`](http://github.com/eggjs/egg/commit/289f8cd3d90cc24c55fa51e3d75f5750233af7ee)] - docs(progressive):changes some grammar (#1773) (ๆฌ็ซน <<2632807692@qq.com>>) -* [[`ae87460`](http://github.com/eggjs/egg/commit/ae87460d6aacb38f4d60d703450f8085c72d3b0d)] - docs(migration): add description for plugin breakchange (#1766) (TZ | ๅคฉ็Œช <>) -* [[`a2788a8`](http://github.com/eggjs/egg/commit/a2788a870175d6c1abdad3c379bbb9adc6c24ba9)] - docs(controller): import base controller directly (#1771) (Yiyu He <>) -* [[`7ebfc9b`](http://github.com/eggjs/egg/commit/7ebfc9b96b03a6b1bdffc3da65c6940902dc3086)] - docs(quickstart): fix typo in code example (#1765) (Darren Poon <>) -* [[`6ff6998`](http://github.com/eggjs/egg/commit/6ff699824dce6962d7aa9e9e48f41a50a994834f)] - docs: add security english translation (#1691) (Adams <>) -* [[`a061f21`](http://github.com/eggjs/egg/commit/a061f21178b2253b587dab780ba74f19605109a4)] - docs(intro): make some changes for egg-and-koa (#1739) (ๆฌ็ซน <<2632807692@qq.com>>) -* [[`d752b3b`](http://github.com/eggjs/egg/commit/d752b3b795cc0c5a579770695fcadd3db713ff6f)] - docs(deployment): adjust with new version egg-scripts (#1757) (TZ | ๅคฉ็Œช <>) -* [[`1b12b51`](http://github.com/eggjs/egg/commit/1b12b519937e80728d133ea24ff88a2568b72a57)] - docs(cookie-session): use async (#1723) (TZ | ๅคฉ็Œช <>) -* [[`5c88026`](http://github.com/eggjs/egg/commit/5c880266f9968a2e9b102db7c0eea2c7b0f09a43)] - docs(plugin): use async (#1730) (TZ | ๅคฉ็Œช <>) -* [[`ebb8adf`](http://github.com/eggjs/egg/commit/ebb8adfadcf21ba29997c65d5adc5a92235ffa8d)] - some changes of docs(what is egg) (#1734) (ๆฌ็ซน <<2632807692@qq.com>>) -* [[`2da00fc`](http://github.com/eggjs/egg/commit/2da00fca45d9bc161cae5ab9754a3fcc0321b9c7)] - docs(framework): use new way (#1728) (TZ | ๅคฉ็Œช <>) -* [[`47fbee5`](http://github.com/eggjs/egg/commit/47fbee574b94d9f6420d44e7a8f0ccec035d94f4)] - docs(cluster-client): use async (#1727) (TZ | ๅคฉ็Œช <>) -* [[`1420682`](http://github.com/eggjs/egg/commit/1420682dc5b6fb14342373d9b70614c3de0c015b)] - docs(ipc): use async (#1722) (TZ | ๅคฉ็Œช <>) -* [[`503b69b`](http://github.com/eggjs/egg/commit/503b69b2e5c3f59b9c3c307a50e711cd8eb8d967)] - feat: dump application router json (fengmk2 <>) -* [[`76ff783`](http://github.com/eggjs/egg/commit/76ff783b80a9d9ffc01db1b434c25fedd6e27ca7)] - fix: run dumpConfig at the last ready callback (fengmk2 <>) -* [[`50efe4c`](http://github.com/eggjs/egg/commit/50efe4ceb9a4c8ec902a503db7ad10ffe7819e1a)] - docs(httpclient): use async (#1724) (TZ | ๅคฉ็Œช <>) -* [[`d043148`](http://github.com/eggjs/egg/commit/d043148b8ee69614098b39604dd6b7d7e1a84810)] - docs: remove async-function (#1713) (TZ | ๅคฉ็Œช <>) -* [[`e3ef3ec`](http://github.com/eggjs/egg/commit/e3ef3ec65c5e2874c813f6cda18b61b630d137be)] - docs(restful): use async (#1709) (TZ | ๅคฉ็Œช <>) -* [[`b042937`](http://github.com/eggjs/egg/commit/b042937b1e77b8206206a248c9f3e3ab82b7d6d8)] - docs(error-handling): use async (#1721) (TZ | ๅคฉ็Œช <>) -* [[`80ab243`](http://github.com/eggjs/egg/commit/80ab2439d508e9e0574df31061b5bb14988c2e3e)] - docs(i18n): use async (#1720) (TZ | ๅคฉ็Œช <>) -* [[`6741999`](http://github.com/eggjs/egg/commit/67419996a3abd403ab8d67755ecb98c3a9b97338)] - docs(logger): use async (#1719) (TZ | ๅคฉ็Œช <>) -* [[`f39c105`](http://github.com/eggjs/egg/commit/f39c105067e08fe416f86d0a415f5475ce66ba17)] - docs(view): use async (#1717) (TZ | ๅคฉ็Œช <>) -* [[`cf3de0f`](http://github.com/eggjs/egg/commit/cf3de0f248e3435a7d6ac41ece16dea55f5e86c9)] - docs(unittest): use async (#1716) (TZ | ๅคฉ็Œช <>) -* [[`cb9c9a4`](http://github.com/eggjs/egg/commit/cb9c9a43015a47347273bf8a09d971205b0d57ec)] - docs(mysql): use async (#1711) (TZ | ๅคฉ็Œช <>) +- **feature** + - add 400 response for broken client request to instead of empty response + - dump application router json + +- **fix** + - fix: run dumpConfig at the last ready callback + +- **document** + - migrate docs to egg 2 + - add document for passport + +### Commits + +- [[`40df153`](http://github.com/eggjs/egg/commit/40df153dd7ca8124a7502ba6cdc838835388a0ae)] - feat: add 400 response for broken client request to instead of empty response (#1829) (Khaidi Chu <>) +- [[`d0ee9f2`](http://github.com/eggjs/egg/commit/d0ee9f2500e69a1e0662c9ea597bf97db3418041)] - docs(passport): fix some description (#1828) (TZ | ๅคฉ็Œช <>) +- [[`f7c6a0a`](http://github.com/eggjs/egg/commit/f7c6a0a835ea950e98e40a0b4b83736912b5ab82)] - docs(passport): add description (#1825) (TZ | ๅคฉ็Œช <>) +- [[`f66d9be`](http://github.com/eggjs/egg/commit/f66d9be57807c04058511b47611afa890884b2a5)] - docs(passport): the missing docs for passport (#1824) (TZ | ๅคฉ็Œช <>) +- [[`18f93f0`](http://github.com/eggjs/egg/commit/18f93f0b927a08e6bd356f9fcc6a3141e813e85f)] - docs(core/view.md): translation (#1577) (Zhongyuan <>) +- [[`7e05669`](http://github.com/eggjs/egg/commit/7e056692506f5801390fd804d75bf6756991a54b)] - 1. docs(error-handle): missing function keywords. (#1819) (M.Y.Akashi <>) +- [[`89e114c`](http://github.com/eggjs/egg/commit/89e114cb88ef1ef96e479001bf0f8250867111c9)] - docs: add AntV links (#1809) (TZ | ๅคฉ็Œช <>) +- [[`bdfd3cc`](http://github.com/eggjs/egg/commit/bdfd3cc62b8377cadac2a6c108944d86eaca3df0)] - docs(router): new style & remove app.verb (#1803) (TZ | ๅคฉ็Œช <>) +- [[`4c9eacb`](http://github.com/eggjs/egg/commit/4c9eacbb7d4560924602103e5e23ae578ac34a52)] - docs(middleware): add description of import koa middleware (#1805) (TZ | ๅคฉ็Œช <>) +- [[`c152dee`](http://github.com/eggjs/egg/commit/c152deec69c3dbb06ce87433a46bab0bc61e295b)] - docs(loader): adjust extends way (#1729) (TZ | ๅคฉ็Œช <>) +- [[`289f8cd`](http://github.com/eggjs/egg/commit/289f8cd3d90cc24c55fa51e3d75f5750233af7ee)] - docs(progressive):changes some grammar (#1773) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`ae87460`](http://github.com/eggjs/egg/commit/ae87460d6aacb38f4d60d703450f8085c72d3b0d)] - docs(migration): add description for plugin breakchange (#1766) (TZ | ๅคฉ็Œช <>) +- [[`a2788a8`](http://github.com/eggjs/egg/commit/a2788a870175d6c1abdad3c379bbb9adc6c24ba9)] - docs(controller): import base controller directly (#1771) (Yiyu He <>) +- [[`7ebfc9b`](http://github.com/eggjs/egg/commit/7ebfc9b96b03a6b1bdffc3da65c6940902dc3086)] - docs(quickstart): fix typo in code example (#1765) (Darren Poon <>) +- [[`6ff6998`](http://github.com/eggjs/egg/commit/6ff699824dce6962d7aa9e9e48f41a50a994834f)] - docs: add security english translation (#1691) (Adams <>) +- [[`a061f21`](http://github.com/eggjs/egg/commit/a061f21178b2253b587dab780ba74f19605109a4)] - docs(intro): make some changes for egg-and-koa (#1739) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`d752b3b`](http://github.com/eggjs/egg/commit/d752b3b795cc0c5a579770695fcadd3db713ff6f)] - docs(deployment): adjust with new version egg-scripts (#1757) (TZ | ๅคฉ็Œช <>) +- [[`1b12b51`](http://github.com/eggjs/egg/commit/1b12b519937e80728d133ea24ff88a2568b72a57)] - docs(cookie-session): use async (#1723) (TZ | ๅคฉ็Œช <>) +- [[`5c88026`](http://github.com/eggjs/egg/commit/5c880266f9968a2e9b102db7c0eea2c7b0f09a43)] - docs(plugin): use async (#1730) (TZ | ๅคฉ็Œช <>) +- [[`ebb8adf`](http://github.com/eggjs/egg/commit/ebb8adfadcf21ba29997c65d5adc5a92235ffa8d)] - some changes of docs(what is egg) (#1734) (ๆฌ็ซน <<2632807692@qq.com>>) +- [[`2da00fc`](http://github.com/eggjs/egg/commit/2da00fca45d9bc161cae5ab9754a3fcc0321b9c7)] - docs(framework): use new way (#1728) (TZ | ๅคฉ็Œช <>) +- [[`47fbee5`](http://github.com/eggjs/egg/commit/47fbee574b94d9f6420d44e7a8f0ccec035d94f4)] - docs(cluster-client): use async (#1727) (TZ | ๅคฉ็Œช <>) +- [[`1420682`](http://github.com/eggjs/egg/commit/1420682dc5b6fb14342373d9b70614c3de0c015b)] - docs(ipc): use async (#1722) (TZ | ๅคฉ็Œช <>) +- [[`503b69b`](http://github.com/eggjs/egg/commit/503b69b2e5c3f59b9c3c307a50e711cd8eb8d967)] - feat: dump application router json (fengmk2 <>) +- [[`76ff783`](http://github.com/eggjs/egg/commit/76ff783b80a9d9ffc01db1b434c25fedd6e27ca7)] - fix: run dumpConfig at the last ready callback (fengmk2 <>) +- [[`50efe4c`](http://github.com/eggjs/egg/commit/50efe4ceb9a4c8ec902a503db7ad10ffe7819e1a)] - docs(httpclient): use async (#1724) (TZ | ๅคฉ็Œช <>) +- [[`d043148`](http://github.com/eggjs/egg/commit/d043148b8ee69614098b39604dd6b7d7e1a84810)] - docs: remove async-function (#1713) (TZ | ๅคฉ็Œช <>) +- [[`e3ef3ec`](http://github.com/eggjs/egg/commit/e3ef3ec65c5e2874c813f6cda18b61b630d137be)] - docs(restful): use async (#1709) (TZ | ๅคฉ็Œช <>) +- [[`b042937`](http://github.com/eggjs/egg/commit/b042937b1e77b8206206a248c9f3e3ab82b7d6d8)] - docs(error-handling): use async (#1721) (TZ | ๅคฉ็Œช <>) +- [[`80ab243`](http://github.com/eggjs/egg/commit/80ab2439d508e9e0574df31061b5bb14988c2e3e)] - docs(i18n): use async (#1720) (TZ | ๅคฉ็Œช <>) +- [[`6741999`](http://github.com/eggjs/egg/commit/67419996a3abd403ab8d67755ecb98c3a9b97338)] - docs(logger): use async (#1719) (TZ | ๅคฉ็Œช <>) +- [[`f39c105`](http://github.com/eggjs/egg/commit/f39c105067e08fe416f86d0a415f5475ce66ba17)] - docs(view): use async (#1717) (TZ | ๅคฉ็Œช <>) +- [[`cf3de0f`](http://github.com/eggjs/egg/commit/cf3de0f248e3435a7d6ac41ece16dea55f5e86c9)] - docs(unittest): use async (#1716) (TZ | ๅคฉ็Œช <>) +- [[`cb9c9a4`](http://github.com/eggjs/egg/commit/cb9c9a43015a47347273bf8a09d971205b0d57ec)] - docs(mysql): use async (#1711) (TZ | ๅคฉ็Œช <>) ## 2017-11-20, Version 2.0.0, @dead-horse ### Notable changes -* **performance** - * By removing the wrapper code of `co` library, performance increase over 30% (which not include the performance boost coming with Node 8), see [#14](https://github.com/eggjs/benchmark/pull/14) and [benchmark](https://eggjs.github.io/benchmark/plot/) - -* **feature** - * [BREAKING CHANGE] drop node <8 support - * upgrade to egg-core@4(base on koa 2), but still supports all the usages in egg 1 - * upgrade built-in plugins to adapt egg@2 - * `runInBackground` use location as scope name when anonymous - -* **fix** - * dump async function as AsyncFunction - -* **document** - * migrate some documents to async function - * split plugin and plugin development - * refactor the description about cluster client @vincenthou - * add document for how to customize error handler - * translate cookie and session @zhang-z - * translate basics/schedule.md, thanks @Azard - -### Commits - - * [[`8197826`](http://github.com/eggjs/egg/commit/8197826a8dca062c91ba45c235cec66a93f335a4)] - docs: refine egg-and-koa with egg 2 (#1686) (Yiyu He <>) - * [[`757f275`](http://github.com/eggjs/egg/commit/757f275a16741c670f210876408aaeefe5797a23)] - fix: dump async function as AsyncFunction (#1687) (Yiyu He <>) - * [[`12edd64`](http://github.com/eggjs/egg/commit/12edd64915164df6b2d5fed9e179e90954f25687)] - test: use async function instead of generator function (#1684) (Yiyu He <>) - * [[`5513456`](http://github.com/eggjs/egg/commit/5513456e2c702fdc1b7a500f8d8d58048d1041fa)] - feat: runInBackground use location as scope name when anonymous (#1683) (Yiyu He <>) - * [[`212b077`](http://github.com/eggjs/egg/commit/212b077993cff01c08c55fa4545c324adb96322c)] - doc: Add th.yml (#1682) (NatPi <<31546528+NatJNP@users.noreply.github.com>>) - * [[`3ddd67f`](http://github.com/eggjs/egg/commit/3ddd67fbbb83a783541118a05d7e0febb2fde7f3)] - docs(advanced/cluster-client): refactor the description about cluster client (#1417) (vincent.hou <>) - * [[`3d948e4`](http://github.com/eggjs/egg/commit/3d948e44e55fbb88c318a8f14fa7a0b0a8b71b4e)] - docs(plugin): split plugin and plugin development (#1663) (TZ | ๅคฉ็Œช <>) - * [[`b1343ad`](http://github.com/eggjs/egg/commit/b1343ad55f08b15f8084104c54db0b5975716323)] - docs(core/unittest): translate unittest.md (#1660) (freebyron <>) - * [[`fb2d96a`](http://github.com/eggjs/egg/commit/fb2d96ae8e1759edc9126a2920f9028b6e4d15df)] - docs(app-start): generator -> async (#1662) (TZ | ๅคฉ็Œช <>) - * [[`12c0a8a`](http://github.com/eggjs/egg/commit/12c0a8afb8cd332037670f7db8e8662566c1407f)] - docs(quickstart): fix app.Service (#1661) (TZ | ๅคฉ็Œช <>) - * [[`49b0071`](http://github.com/eggjs/egg/commit/49b00712de6eed7c386b07c7c91082ef36cc667f)] - docs(core/cookie-and-session): translate section Cookie (#1562) (Zhongyuan <>) - * [[`ac55d5e`](http://github.com/eggjs/egg/commit/ac55d5eb0b90e2333e3d92523075615e80835647)] - docs: fix typo in async function (#1657) (BccSafe <>) - * [[`9f362d8`](http://github.com/eggjs/egg/commit/9f362d878b61e1144ceab851215dbafb974fb85f)] - docs(basics/schedule.md): translate (#1648) (Weilun Xiong <>) - * [[`448d094`](http://github.com/eggjs/egg/commit/448d0945c0030d2f2bdf8e0f85ccfcbde4ba2b25)] - deps: upgrade all plugins to adapt egg@2 (#1653) (Yiyu He <>) - * [[`4993ee8`](http://github.com/eggjs/egg/commit/4993ee8fae81bf14f92c86ac1d4d952d62e1d165)] - docs(quickstart): generator -> async (#1650) (TZ | ๅคฉ็Œช <>) - * [[`8c6f16d`](http://github.com/eggjs/egg/commit/8c6f16d64834d46b0689ce079cc5d71155848ac8)] - docs: how to customize error handler (#1651) (Yiyu He <>) - * [[`8e8869a`](http://github.com/eggjs/egg/commit/8e8869a4d73908503cf1f60de3be49461639ca08)] - refactor: upgrade egg-core@4 (#1631) (Yiyu He <>) +- **performance** + - By removing the wrapper code of `co` library, performance increase over 30% (which not include the performance boost coming with Node 8), see [#14](https://github.com/eggjs/benchmark/pull/14) and [benchmark](https://eggjs.github.io/benchmark/plot/) + +- **feature** + - [BREAKING CHANGE] drop node <8 support + - upgrade to egg-core@4(base on koa 2), but still supports all the usages in egg 1 + - upgrade built-in plugins to adapt egg@2 + - `runInBackground` use location as scope name when anonymous + +- **fix** + - dump async function as AsyncFunction + +- **document** + - migrate some documents to async function + - split plugin and plugin development + - refactor the description about cluster client @vincenthou + - add document for how to customize error handler + - translate cookie and session @zhang-z + - translate basics/schedule.md, thanks @Azard + +### Commits + +- [[`8197826`](http://github.com/eggjs/egg/commit/8197826a8dca062c91ba45c235cec66a93f335a4)] - docs: refine egg-and-koa with egg 2 (#1686) (Yiyu He <>) +- [[`757f275`](http://github.com/eggjs/egg/commit/757f275a16741c670f210876408aaeefe5797a23)] - fix: dump async function as AsyncFunction (#1687) (Yiyu He <>) +- [[`12edd64`](http://github.com/eggjs/egg/commit/12edd64915164df6b2d5fed9e179e90954f25687)] - test: use async function instead of generator function (#1684) (Yiyu He <>) +- [[`5513456`](http://github.com/eggjs/egg/commit/5513456e2c702fdc1b7a500f8d8d58048d1041fa)] - feat: runInBackground use location as scope name when anonymous (#1683) (Yiyu He <>) +- [[`212b077`](http://github.com/eggjs/egg/commit/212b077993cff01c08c55fa4545c324adb96322c)] - doc: Add th.yml (#1682) (NatPi <<31546528+NatJNP@users.noreply.github.com>>) +- [[`3ddd67f`](http://github.com/eggjs/egg/commit/3ddd67fbbb83a783541118a05d7e0febb2fde7f3)] - docs(advanced/cluster-client): refactor the description about cluster client (#1417) (vincent.hou <>) +- [[`3d948e4`](http://github.com/eggjs/egg/commit/3d948e44e55fbb88c318a8f14fa7a0b0a8b71b4e)] - docs(plugin): split plugin and plugin development (#1663) (TZ | ๅคฉ็Œช <>) +- [[`b1343ad`](http://github.com/eggjs/egg/commit/b1343ad55f08b15f8084104c54db0b5975716323)] - docs(core/unittest): translate unittest.md (#1660) (freebyron <>) +- [[`fb2d96a`](http://github.com/eggjs/egg/commit/fb2d96ae8e1759edc9126a2920f9028b6e4d15df)] - docs(app-start): generator -> async (#1662) (TZ | ๅคฉ็Œช <>) +- [[`12c0a8a`](http://github.com/eggjs/egg/commit/12c0a8afb8cd332037670f7db8e8662566c1407f)] - docs(quickstart): fix app.Service (#1661) (TZ | ๅคฉ็Œช <>) +- [[`49b0071`](http://github.com/eggjs/egg/commit/49b00712de6eed7c386b07c7c91082ef36cc667f)] - docs(core/cookie-and-session): translate section Cookie (#1562) (Zhongyuan <>) +- [[`ac55d5e`](http://github.com/eggjs/egg/commit/ac55d5eb0b90e2333e3d92523075615e80835647)] - docs: fix typo in async function (#1657) (BccSafe <>) +- [[`9f362d8`](http://github.com/eggjs/egg/commit/9f362d878b61e1144ceab851215dbafb974fb85f)] - docs(basics/schedule.md): translate (#1648) (Weilun Xiong <>) +- [[`448d094`](http://github.com/eggjs/egg/commit/448d0945c0030d2f2bdf8e0f85ccfcbde4ba2b25)] - deps: upgrade all plugins to adapt egg@2 (#1653) (Yiyu He <>) +- [[`4993ee8`](http://github.com/eggjs/egg/commit/4993ee8fae81bf14f92c86ac1d4d952d62e1d165)] - docs(quickstart): generator -> async (#1650) (TZ | ๅคฉ็Œช <>) +- [[`8c6f16d`](http://github.com/eggjs/egg/commit/8c6f16d64834d46b0689ce079cc5d71155848ac8)] - docs: how to customize error handler (#1651) (Yiyu He <>) +- [[`8e8869a`](http://github.com/eggjs/egg/commit/8e8869a4d73908503cf1f60de3be49461639ca08)] - refactor: upgrade egg-core@4 (#1631) (Yiyu He <>) ## 2017-11-08, Version 1.11.0, @dead-horse ### Notable changes -* **feature** - * export global namespace at d.ts @atian25 +- **feature** + - export global namespace at d.ts @atian25 ### Commits - * [[`b131a4c`](http://github.com/eggjs/egg/commit/b131a4cec51cc783dcd4ccb8756439063c5b875c)] - feat: export global namespace at d.ts (#1633) (TZ | ๅคฉ็Œช <>) +- [[`b131a4c`](http://github.com/eggjs/egg/commit/b131a4cec51cc783dcd4ccb8756439063c5b875c)] - feat: export global namespace at d.ts (#1633) (TZ | ๅคฉ็Œช <>) ## 2017-11-08, Version 1.10.1, @dead-horse ### Notable changes -* **fix** - * use `app.options` instead of deprecated `app._options` -* **document** - * translate core/cluster-and-ipc.md, thanks @lslxdx +- **fix** + - use `app.options` instead of deprecated `app._options` +- **document** + - translate core/cluster-and-ipc.md, thanks @lslxdx ### Commits - * [[`9eec677`](http://github.com/eggjs/egg/commit/9eec677757ddbde6f7ddcff2c6a698087e07b70e)] - fix: use `app.options` instead of `app._options` (#1625) (Yiyu He <>) - * [[`fd1ff63`](http://github.com/eggjs/egg/commit/fd1ff638920fef4a3258767df982b87e70614215)] - test: fix tsc test case (#1620) (Yiyu He <>) - * [[`6804bd3`](http://github.com/eggjs/egg/commit/6804bd36cfc7a9bd54b3be2d9ce828d4e951f8b8)] - test: add node 9 and drop node 7 (#1602) (fengmk2 <>) - * [[`3878862`](http://github.com/eggjs/egg/commit/38788621ccf06fd6ac8f4068de3e49c5668e1915)] - docs: translate core/cluster-and-ipc.md (#1594) (lslxdx <>) +- [[`9eec677`](http://github.com/eggjs/egg/commit/9eec677757ddbde6f7ddcff2c6a698087e07b70e)] - fix: use `app.options` instead of `app._options` (#1625) (Yiyu He <>) +- [[`fd1ff63`](http://github.com/eggjs/egg/commit/fd1ff638920fef4a3258767df982b87e70614215)] - test: fix tsc test case (#1620) (Yiyu He <>) +- [[`6804bd3`](http://github.com/eggjs/egg/commit/6804bd36cfc7a9bd54b3be2d9ce828d4e951f8b8)] - test: add node 9 and drop node 7 (#1602) (fengmk2 <>) +- [[`3878862`](http://github.com/eggjs/egg/commit/38788621ccf06fd6ac8f4068de3e49c5668e1915)] - docs: translate core/cluster-and-ipc.md (#1594) (lslxdx <>) ## 2017-10-24, Version 1.10.0, @popomore ### Notable changes -* **feature** - * add Subscription @popomore -* **document** - * multipart example @dead_horse - * fix document @atian25 @beilunyang - * improve schedule document @atian25 +- **feature** + - add Subscription @popomore +- **document** + - multipart example @dead_horse + - fix document @atian25 @beilunyang + - improve schedule document @atian25 ### Commits - * [[`6dd1594a5`](http://github.com/eggjs/egg/commit/6dd1594a5c300f24e668b3679c7ae8df733b6a39)] - docs: fix egg-scripts (#1552) (TZ | ๅคฉ็Œช <>) - * [[`46ed6fac9`](http://github.com/eggjs/egg/commit/46ed6fac9f94d300a23903a71cfafdb5c8b1ba91)] - feat: add Subscription (#1469) (Haoliang Gao <>) - * [[`c508f9fa7`](http://github.com/eggjs/egg/commit/c508f9fa7dedbc8c3c4f6319b7233a034db463b4)] - docs: fix csrf (#1551) (TZ | ๅคฉ็Œช <>) - * [[`7fb9bbf71`](http://github.com/eggjs/egg/commit/7fb9bbf71219debf35b4e864a65be22e24a0480a)] - docs: fix typo (#1537) (ๆ‚–่ฎบ <<786220806@qq.com>>) - * [[`68c0e1a9c`](http://github.com/eggjs/egg/commit/68c0e1a9c053618133d3484043abfb77e3372a22)] - docs: adjust new schedule (#1477) (TZ | ๅคฉ็Œช <>) - * [[`aeae948ec`](http://github.com/eggjs/egg/commit/aeae948ec986f5f7204ad6a0f748403b8e6e6fe1)] - docs: adjust middleware config at framework (#1523) (TZ | ๅคฉ็Œช <>) - * [[`7b37d2393`](http://github.com/eggjs/egg/commit/7b37d2393f59f3c5efbc84cf1d5f51e9332b0cd8)] - docs: multipart example use yield parts() (#1518) (Yiyu He <>) - * [[`6846badc8`](http://github.com/eggjs/egg/commit/6846badc8da89b00483aa7be5c69b1cd2f06d797)] - docs: add plugin.js description (#1499) (TZ | ๅคฉ็Œช <>) +- [[`6dd1594a5`](http://github.com/eggjs/egg/commit/6dd1594a5c300f24e668b3679c7ae8df733b6a39)] - docs: fix egg-scripts (#1552) (TZ | ๅคฉ็Œช <>) +- [[`46ed6fac9`](http://github.com/eggjs/egg/commit/46ed6fac9f94d300a23903a71cfafdb5c8b1ba91)] - feat: add Subscription (#1469) (Haoliang Gao <>) +- [[`c508f9fa7`](http://github.com/eggjs/egg/commit/c508f9fa7dedbc8c3c4f6319b7233a034db463b4)] - docs: fix csrf (#1551) (TZ | ๅคฉ็Œช <>) +- [[`7fb9bbf71`](http://github.com/eggjs/egg/commit/7fb9bbf71219debf35b4e864a65be22e24a0480a)] - docs: fix typo (#1537) (ๆ‚–่ฎบ <<786220806@qq.com>>) +- [[`68c0e1a9c`](http://github.com/eggjs/egg/commit/68c0e1a9c053618133d3484043abfb77e3372a22)] - docs: adjust new schedule (#1477) (TZ | ๅคฉ็Œช <>) +- [[`aeae948ec`](http://github.com/eggjs/egg/commit/aeae948ec986f5f7204ad6a0f748403b8e6e6fe1)] - docs: adjust middleware config at framework (#1523) (TZ | ๅคฉ็Œช <>) +- [[`7b37d2393`](http://github.com/eggjs/egg/commit/7b37d2393f59f3c5efbc84cf1d5f51e9332b0cd8)] - docs: multipart example use yield parts() (#1518) (Yiyu He <>) +- [[`6846badc8`](http://github.com/eggjs/egg/commit/6846badc8da89b00483aa7be5c69b1cd2f06d797)] - docs: add plugin.js description (#1499) (TZ | ๅคฉ็Œช <>) ## 2017-09-25, Version 1.9.0, @gxcsoccer ### Notable changes -* **feature** - * make cluster client configurable in egg - * donโ€™t force logger to use INFO level in prod -* **document** - * correct sample codes, by @Jawnkuin - * fix devtools debug, by @atian25 - * adjust debug docs with new egg-bin debug, by @atian25 - * fix port should be number, @atian25 +- **feature** + - make cluster client configurable in egg + - donโ€™t force logger to use INFO level in prod +- **document** + - correct sample codes, by @Jawnkuin + - fix devtools debug, by @atian25 + - adjust debug docs with new egg-bin debug, by @atian25 + - fix port should be number, @atian25 ### Commits - * [[`21425e7`](https://github.com/eggjs/egg/commit/21425e7a9c451cfa07f3cb580d0b770eb5b0c890)] - feat: make cluster client configurable in egg (#1459) (gxcsoccer <>) - * [[`d0797b1`](https://github.com/eggjs/egg/commit/d0797b1c2d078d1bea97c104471388bedc5e61c9)] - docs: correct sample codes (#1434) (Jawnkuin <>) - * [[`6eac07e`](https://github.com/eggjs/egg/commit/6eac07eb287ecf158b2c182a0e36a81fa14700ce)] - refactor: httpclient args tracer to be enforced (#1421) (hui <>) - * [[`c56274b`](https://github.com/eggjs/egg/commit/c56274bb818526370f857b926d178ff520b3bea8)] - docs(development): fix devtools debug (#1428) (TZ | ๅคฉ็Œช <>) - * [[`e3f29de`](https://github.com/eggjs/egg/commit/e3f29de9bbbfb67c641cf54272883759d7256d89)] - docs(development): adjust debug docs with new egg-bin debug (#1427) (AnzerWall <>) - * [[`5a9531a`](https://github.com/eggjs/egg/commit/5a9531abbec83fbff08ddb6feb475f87498d2a3d)] - feat: donโ€™t force logger to use INFO level in prod (#1218) (TZ | ๅคฉ็Œช <>) - * [[`95fbd47`](https://github.com/eggjs/egg/commit/95fbd47f4c20797df17dd210f30a40f43d1d8900)] - docs(deployment): port should be number (#1424) (TZ | ๅคฉ็Œช <>) +- [[`21425e7`](https://github.com/eggjs/egg/commit/21425e7a9c451cfa07f3cb580d0b770eb5b0c890)] - feat: make cluster client configurable in egg (#1459) (gxcsoccer <>) +- [[`d0797b1`](https://github.com/eggjs/egg/commit/d0797b1c2d078d1bea97c104471388bedc5e61c9)] - docs: correct sample codes (#1434) (Jawnkuin <>) +- [[`6eac07e`](https://github.com/eggjs/egg/commit/6eac07eb287ecf158b2c182a0e36a81fa14700ce)] - refactor: httpclient args tracer to be enforced (#1421) (hui <>) +- [[`c56274b`](https://github.com/eggjs/egg/commit/c56274bb818526370f857b926d178ff520b3bea8)] - docs(development): fix devtools debug (#1428) (TZ | ๅคฉ็Œช <>) +- [[`e3f29de`](https://github.com/eggjs/egg/commit/e3f29de9bbbfb67c641cf54272883759d7256d89)] - docs(development): adjust debug docs with new egg-bin debug (#1427) (AnzerWall <>) +- [[`5a9531a`](https://github.com/eggjs/egg/commit/5a9531abbec83fbff08ddb6feb475f87498d2a3d)] - feat: donโ€™t force logger to use INFO level in prod (#1218) (TZ | ๅคฉ็Œช <>) +- [[`95fbd47`](https://github.com/eggjs/egg/commit/95fbd47f4c20797df17dd210f30a40f43d1d8900)] - docs(deployment): port should be number (#1424) (TZ | ๅคฉ็Œช <>) ## 2017-09-11, Version 1.8.0, @leoner ### Notable changes -* **feature** - * support app.httpclient and agent.httpclient auto set tracer -* **fix** - * should extends from egg-core BaseContextClass -* **document** - * English documents `basics/objects`,`core/docs-logger` and `core/httpclient` +- **feature** + - support app.httpclient and agent.httpclient auto set tracer +- **fix** + - should extends from egg-core BaseContextClass +- **document** + - English documents `basics/objects`,`core/docs-logger` and `core/httpclient` have been translated by @DarrenWong, @Azard and @gztchan - * documents typo fixed and improved by @vincenthou, @waitingsong and @hyj1991 + - documents typo fixed and improved by @vincenthou, @waitingsong and @hyj1991 ### Commits - * [[`54be7dc09`](http://github.com/eggjs/egg/commit/54be7dc099f47fb65b9bc3d9bb29de4d70ac25cd)] - docs(core/cluster-and-ipc): fix some typo (#1415) (vincent.hou <>) - * [[`6cf17c11a`](http://github.com/eggjs/egg/commit/6cf17c11af51220904881ed99aa65cac0f212c2b)] - docs: (core/httpclient): [translate] Done (#1409) (Darren Wong <>) - * [[`105e1947e`](http://github.com/eggjs/egg/commit/105e1947ee0863ebd6c0a1111f218b025e0e9989)] - docs: translate basics/objects (#1238) (Weilun Xiong <>) - * [[`f7c0d8520`](http://github.com/eggjs/egg/commit/f7c0d85209c9e96f7812c4a2996f000a2667770d)] - feat: support app.httpclient and agent.httpclient auto set tracer (#1393) (hui <>) - * [[`3aaee8fbe`](http://github.com/eggjs/egg/commit/3aaee8fbea4aee8b5c40921670642772835bf40d)] - fix: should extends from egg-core BaseContextClass (#1392) (fengmk2 <>) - * [[`a9936a383`](http://github.com/eggjs/egg/commit/a9936a383174fd0b2c201ee759bc5174486970a1)] - fix: typo (#1388) (waiting <>) - * [[`eef30faf6`](http://github.com/eggjs/egg/commit/eef30faf69b41f4a352a592ad65d097698d27303)] - docs: adjust webstorm debug config (#1367) (TZ | ๅคฉ็Œช <>) - * [[`499454379`](http://github.com/eggjs/egg/commit/499454379b2234a80d3946933f7511ac83c292d6)] - docs: curl(url, opts) add parameter introduction (#1351) (#1352) (hyj1991 <<66cfat66@gmail.com>>) - * [[`4daf497eb`](http://github.com/eggjs/egg/commit/4daf497eb32c05c73911a01e861b9cf761ede451)] - docs(en/core/docs-logger): finish logger.md translation in English (#1254) (Tony Chan <>) - * [[`aaacd56c9`](http://github.com/eggjs/egg/commit/aaacd56c9c60dbf0cbfd0d1fcc77366a3e3993fe)] - docs: remove egg-scripts env default description (#1318) (TZ | ๅคฉ็Œช <>) - * [[`4feae70b8`](http://github.com/eggjs/egg/commit/4feae70b8c8e69890053bff9f3df9cc7024d69cd)] - docs: add egg-scripts to deployment (#1279) (TZ | ๅคฉ็Œช <>) - * [[`08ed1b3c6`](http://github.com/eggjs/egg/commit/08ed1b3c68e242eba187640c9f6cf8a0acd7489f)] - docs(unittest): typo of egg-mock (#1284) (TZ | ๅคฉ็Œช <>) - * [[`734854c84`](http://github.com/eggjs/egg/commit/734854c84ef8b0107df3101b6aa212d96574b317)] - docs(unittest): add bootstrap usage (#1278) (Yiyu He <>) - * [[`ebbbcd574`](http://github.com/eggjs/egg/commit/ebbbcd574f5bbd4d91bec345e8b35f9adc48d6c0)] - chore: skip docs deploy at ci cron (#1268) (TZ | ๅคฉ็Œช <>) +- [[`54be7dc09`](http://github.com/eggjs/egg/commit/54be7dc099f47fb65b9bc3d9bb29de4d70ac25cd)] - docs(core/cluster-and-ipc): fix some typo (#1415) (vincent.hou <>) +- [[`6cf17c11a`](http://github.com/eggjs/egg/commit/6cf17c11af51220904881ed99aa65cac0f212c2b)] - docs: (core/httpclient): [translate] Done (#1409) (Darren Wong <>) +- [[`105e1947e`](http://github.com/eggjs/egg/commit/105e1947ee0863ebd6c0a1111f218b025e0e9989)] - docs: translate basics/objects (#1238) (Weilun Xiong <>) +- [[`f7c0d8520`](http://github.com/eggjs/egg/commit/f7c0d85209c9e96f7812c4a2996f000a2667770d)] - feat: support app.httpclient and agent.httpclient auto set tracer (#1393) (hui <>) +- [[`3aaee8fbe`](http://github.com/eggjs/egg/commit/3aaee8fbea4aee8b5c40921670642772835bf40d)] - fix: should extends from egg-core BaseContextClass (#1392) (fengmk2 <>) +- [[`a9936a383`](http://github.com/eggjs/egg/commit/a9936a383174fd0b2c201ee759bc5174486970a1)] - fix: typo (#1388) (waiting <>) +- [[`eef30faf6`](http://github.com/eggjs/egg/commit/eef30faf69b41f4a352a592ad65d097698d27303)] - docs: adjust webstorm debug config (#1367) (TZ | ๅคฉ็Œช <>) +- [[`499454379`](http://github.com/eggjs/egg/commit/499454379b2234a80d3946933f7511ac83c292d6)] - docs: curl(url, opts) add parameter introduction (#1351) (#1352) (hyj1991 <<66cfat66@gmail.com>>) +- [[`4daf497eb`](http://github.com/eggjs/egg/commit/4daf497eb32c05c73911a01e861b9cf761ede451)] - docs(en/core/docs-logger): finish logger.md translation in English (#1254) (Tony Chan <>) +- [[`aaacd56c9`](http://github.com/eggjs/egg/commit/aaacd56c9c60dbf0cbfd0d1fcc77366a3e3993fe)] - docs: remove egg-scripts env default description (#1318) (TZ | ๅคฉ็Œช <>) +- [[`4feae70b8`](http://github.com/eggjs/egg/commit/4feae70b8c8e69890053bff9f3df9cc7024d69cd)] - docs: add egg-scripts to deployment (#1279) (TZ | ๅคฉ็Œช <>) +- [[`08ed1b3c6`](http://github.com/eggjs/egg/commit/08ed1b3c68e242eba187640c9f6cf8a0acd7489f)] - docs(unittest): typo of egg-mock (#1284) (TZ | ๅคฉ็Œช <>) +- [[`734854c84`](http://github.com/eggjs/egg/commit/734854c84ef8b0107df3101b6aa212d96574b317)] - docs(unittest): add bootstrap usage (#1278) (Yiyu He <>) +- [[`ebbbcd574`](http://github.com/eggjs/egg/commit/ebbbcd574f5bbd4d91bec345e8b35f9adc48d6c0)] - chore: skip docs deploy at ci cron (#1268) (TZ | ๅคฉ็Œช <>) ## 2017-07-27, Version 1.7.0, @popomore ### Notable changes -* **feature** - * Support listen options in config.js -* **improve** - * `app.HttpClient` can be overwritten -* **document** - * Document improvement - * English documents have been translated by @gztchan +- **feature** + - Support listen options in config.js +- **improve** + - `app.HttpClient` can be overwritten +- **document** + - Document improvement + - English documents have been translated by @gztchan ### Commits - * [[`dd07cacb2`](http://github.com/eggjs/egg/commit/dd07cacb209565cc8bdc240b2a3bd7f624a3e56c)] - docs: fix typo on CONTRIBUTING.zh-CN.md (#1266) (SuperEwe <>) - * [[`773343061`](http://github.com/eggjs/egg/commit/7733430614d62392fa1b06568e223ce2ae5b3709)] - docs: only deploy docs at 8 (#1252) (TZ | ๅคฉ็Œช <>) - * [[`4f2ebfda8`](http://github.com/eggjs/egg/commit/4f2ebfda81c067ba500ee22ac30c8b201f746cac)] - docs: fix const define (#1249) (TZ | ๅคฉ็Œช <>) - * [[`45bea3cb5`](http://github.com/eggjs/egg/commit/45bea3cb55636a09160bfc66befca476994dacc8)] - docs(core-deployment): translate deployment.md in English (#1235) (Tony Chan <>) - * [[`dda386e42`](http://github.com/eggjs/egg/commit/dda386e425ce96019f3d068e66603f80af966571)] - test: add test and doc for listen options (#1246) (Haoliang Gao <>) - * [[`3ef1de952`](http://github.com/eggjs/egg/commit/3ef1de95247aa3e3fdcbda71fe83e58a892a13d6)] - feat: set cluster options, include path, port, hostname (#1231) (Haoliang Gao <>) - * [[`e9f93cf83`](http://github.com/eggjs/egg/commit/e9f93cf83d46fd84c8c6b10ec2e7e3eb2bf24f9d)] - refactor: export app.HttpClient that can be overwritten (#1234) (Haoliang Gao <>) - * [[`96b3786eb`](http://github.com/eggjs/egg/commit/96b3786eb9640c9ec2d71a5a0a0b18ee32e9e3ad)] - docs(core/error-handling): translate error-handling.md in English (#1228) (Tony Chan <>) - * [[`c3c9fce55`](http://github.com/eggjs/egg/commit/c3c9fce557a8d8c57b2a5e5391d1c11a81ceeaa7)] - docs(controller): examples use controller class (#1221) (Yiyu He <>) - * [[`24f279005`](http://github.com/eggjs/egg/commit/24f2790051c0d248f6df9850ffe8513dc11e5780)] - docs: new VScode 1.14 default protocol changed. (#1212) (Anto <>) - * [[`2b78b4cf8`](http://github.com/eggjs/egg/commit/2b78b4cf8275171ddf788550745edc3aef948ca7)] - docs: Fix config name from egg-Plugin to eggPlugin in plugin's doc (#1215) (hansen <>) +- [[`dd07cacb2`](http://github.com/eggjs/egg/commit/dd07cacb209565cc8bdc240b2a3bd7f624a3e56c)] - docs: fix typo on CONTRIBUTING.zh-CN.md (#1266) (SuperEwe <>) +- [[`773343061`](http://github.com/eggjs/egg/commit/7733430614d62392fa1b06568e223ce2ae5b3709)] - docs: only deploy docs at 8 (#1252) (TZ | ๅคฉ็Œช <>) +- [[`4f2ebfda8`](http://github.com/eggjs/egg/commit/4f2ebfda81c067ba500ee22ac30c8b201f746cac)] - docs: fix const define (#1249) (TZ | ๅคฉ็Œช <>) +- [[`45bea3cb5`](http://github.com/eggjs/egg/commit/45bea3cb55636a09160bfc66befca476994dacc8)] - docs(core-deployment): translate deployment.md in English (#1235) (Tony Chan <>) +- [[`dda386e42`](http://github.com/eggjs/egg/commit/dda386e425ce96019f3d068e66603f80af966571)] - test: add test and doc for listen options (#1246) (Haoliang Gao <>) +- [[`3ef1de952`](http://github.com/eggjs/egg/commit/3ef1de95247aa3e3fdcbda71fe83e58a892a13d6)] - feat: set cluster options, include path, port, hostname (#1231) (Haoliang Gao <>) +- [[`e9f93cf83`](http://github.com/eggjs/egg/commit/e9f93cf83d46fd84c8c6b10ec2e7e3eb2bf24f9d)] - refactor: export app.HttpClient that can be overwritten (#1234) (Haoliang Gao <>) +- [[`96b3786eb`](http://github.com/eggjs/egg/commit/96b3786eb9640c9ec2d71a5a0a0b18ee32e9e3ad)] - docs(core/error-handling): translate error-handling.md in English (#1228) (Tony Chan <>) +- [[`c3c9fce55`](http://github.com/eggjs/egg/commit/c3c9fce557a8d8c57b2a5e5391d1c11a81ceeaa7)] - docs(controller): examples use controller class (#1221) (Yiyu He <>) +- [[`24f279005`](http://github.com/eggjs/egg/commit/24f2790051c0d248f6df9850ffe8513dc11e5780)] - docs: new VScode 1.14 default protocol changed. (#1212) (Anto <>) +- [[`2b78b4cf8`](http://github.com/eggjs/egg/commit/2b78b4cf8275171ddf788550745edc3aef948ca7)] - docs: Fix config name from egg-Plugin to eggPlugin in plugin's doc (#1215) (hansen <>) ## 2017-07-19, Version 1.6.1, @fengmk2 ### Notable changes -* **fix** - * make sure config.httpclient.httpAgent.timeout >= 30000, and distinguish +- **fix** + - make sure config.httpclient.httpAgent.timeout >= 30000, and distinguish options: request, httpAgent and httpsAgent on `config.httpclient`. ### Commits - * [[`988b8c8`](http://github.com/eggjs/egg/commit/988b8c84d0f63ce0e83e00bd12cff65ebf4f2ff5)] - fix: make sure config.httpclient.httpAgent.timeout >= 30000 (#1165) (fengmk2 <>) - * [[`894005c`](http://github.com/eggjs/egg/commit/894005c8e683e764ec234c915afce89b57343f98)] - docs: (core/i18n): [translate] Done (#1194) (Darren Wong <>) - * [[`410633b`](http://github.com/eggjs/egg/commit/410633b3e47098abc30d83429895b543431929ec)] - chore: kill ssh-agent after deploy (#1204) (Haoliang Gao <>) - * [[`05f4785`](http://github.com/eggjs/egg/commit/05f47858a6d74041a10539443a9ea2e195826bc4)] - chore: add travis_wait to avoid deploying document timeout (#1201) (Haoliang Gao <>) - * [[`367e1d6`](http://github.com/eggjs/egg/commit/367e1d66ef3bdb49ee41758246cdaf49e04ea140)] - docs: fix typo (#1191) (BingqiChan <>) +- [[`988b8c8`](http://github.com/eggjs/egg/commit/988b8c84d0f63ce0e83e00bd12cff65ebf4f2ff5)] - fix: make sure config.httpclient.httpAgent.timeout >= 30000 (#1165) (fengmk2 <>) +- [[`894005c`](http://github.com/eggjs/egg/commit/894005c8e683e764ec234c915afce89b57343f98)] - docs: (core/i18n): [translate] Done (#1194) (Darren Wong <>) +- [[`410633b`](http://github.com/eggjs/egg/commit/410633b3e47098abc30d83429895b543431929ec)] - chore: kill ssh-agent after deploy (#1204) (Haoliang Gao <>) +- [[`05f4785`](http://github.com/eggjs/egg/commit/05f47858a6d74041a10539443a9ea2e195826bc4)] - chore: add travis_wait to avoid deploying document timeout (#1201) (Haoliang Gao <>) +- [[`367e1d6`](http://github.com/eggjs/egg/commit/367e1d66ef3bdb49ee41758246cdaf49e04ea140)] - docs: fix typo (#1191) (BingqiChan <>) ## 2017-07-04, Version 1.6.0, @fengmk2 ### Notable changes -* **feature** - * tsd add ctx.logger and logger.error support Error object - * ignore any key contains "secret" on dump config files - * show who define the property of the config on `run/application_config_meta.json` -* **fix** - * don't cache the intermediate locals for application - -### Commits - - * [[`5dc56fa`](http://github.com/eggjs/egg/commit/5dc56fac043eab22187f9ae1dd7e73d2160fd7ae)] - feat: ignore any key contains "secret" (#1156) (fengmk2 <>) - * [[`74c8a54`](http://github.com/eggjs/egg/commit/74c8a547cc90939253946a145655996b59373457)] - feat: dump `run/${type}_config_meta.json` (#1155) (Haoliang Gao <>) - * [[`b80bb14`](http://github.com/eggjs/egg/commit/b80bb1405c1f47c5596ff4a2c9540af7447430ec)] - fix: don't cache the intermediate locals for application (#1146) (Jackson Tian <>) - * [[`7c70beb`](http://github.com/eggjs/egg/commit/7c70beb26ecf2176cda7547f3163fec11aff450f)] - docs: change istanbul to nyc (#1150) (TZ | ๅคฉ็Œช <>) - * [[`c7a87a8`](http://github.com/eggjs/egg/commit/c7a87a8abade84769b34a1ef0ba50a3cc12dec49)] - docs: adjust objects docs (#1140) (TZ | ๅคฉ็Œช <>) - * [[`0052351`](http://github.com/eggjs/egg/commit/005235162dce4b0e87768a201c9a68c4291592d4)] - docs: improve plugin dependencies (#1061) (luicfer <>) - * [[`4322212`](http://github.com/eggjs/egg/commit/43222127b922b486d8f523230fed82ba453ee8d8)] - docs: add missing class in objects.md (kaiye <>) - * [[`daa8227`](http://github.com/eggjs/egg/commit/daa82278332d7617d6ebb3d07e8cdfd1e95cf644)] - feat(tsd): add ctx.logger and logger.error support Error object (#1108) (Eward Song <>) - * [[`7c2e436`](http://github.com/eggjs/egg/commit/7c2e43626d93049b5f91f59773ef02c4b0f478b3)] - docs: improve feature describe (#1102) (Yiyu He <>) - * [[`5ae7814`](http://github.com/eggjs/egg/commit/5ae7814632b1f92d534a496fe4f51c6737447aba)] - chore: comments in english (#1101) (Yiyu He <>) - * [[`9099be9`](http://github.com/eggjs/egg/commit/9099be91afa806d0a8258441d11e1da2318777ef)] - docs: unify config in quickstart (#1094) (Yiyu He <>) - * [[`c31bc15`](http://github.com/eggjs/egg/commit/c31bc15097c692d08596a277c69fbd44f9d3e2bf)] - test: wait logger to flush (#1090) (Haoliang Gao <>) - * [[`82d2158`](http://github.com/eggjs/egg/commit/82d2158e4c399ead9567b67dc27d13d1ef2e104e)] - docs: add Enclose.IO to Links (#1089) (Minqi Pan <>) +- **feature** + - tsd add ctx.logger and logger.error support Error object + - ignore any key contains "secret" on dump config files + - show who define the property of the config on `run/application_config_meta.json` +- **fix** + - don't cache the intermediate locals for application + +### Commits + +- [[`5dc56fa`](http://github.com/eggjs/egg/commit/5dc56fac043eab22187f9ae1dd7e73d2160fd7ae)] - feat: ignore any key contains "secret" (#1156) (fengmk2 <>) +- [[`74c8a54`](http://github.com/eggjs/egg/commit/74c8a547cc90939253946a145655996b59373457)] - feat: dump `run/${type}_config_meta.json` (#1155) (Haoliang Gao <>) +- [[`b80bb14`](http://github.com/eggjs/egg/commit/b80bb1405c1f47c5596ff4a2c9540af7447430ec)] - fix: don't cache the intermediate locals for application (#1146) (Jackson Tian <>) +- [[`7c70beb`](http://github.com/eggjs/egg/commit/7c70beb26ecf2176cda7547f3163fec11aff450f)] - docs: change istanbul to nyc (#1150) (TZ | ๅคฉ็Œช <>) +- [[`c7a87a8`](http://github.com/eggjs/egg/commit/c7a87a8abade84769b34a1ef0ba50a3cc12dec49)] - docs: adjust objects docs (#1140) (TZ | ๅคฉ็Œช <>) +- [[`0052351`](http://github.com/eggjs/egg/commit/005235162dce4b0e87768a201c9a68c4291592d4)] - docs: improve plugin dependencies (#1061) (luicfer <>) +- [[`4322212`](http://github.com/eggjs/egg/commit/43222127b922b486d8f523230fed82ba453ee8d8)] - docs: add missing class in objects.md (kaiye <>) +- [[`daa8227`](http://github.com/eggjs/egg/commit/daa82278332d7617d6ebb3d07e8cdfd1e95cf644)] - feat(tsd): add ctx.logger and logger.error support Error object (#1108) (Eward Song <>) +- [[`7c2e436`](http://github.com/eggjs/egg/commit/7c2e43626d93049b5f91f59773ef02c4b0f478b3)] - docs: improve feature describe (#1102) (Yiyu He <>) +- [[`5ae7814`](http://github.com/eggjs/egg/commit/5ae7814632b1f92d534a496fe4f51c6737447aba)] - chore: comments in english (#1101) (Yiyu He <>) +- [[`9099be9`](http://github.com/eggjs/egg/commit/9099be91afa806d0a8258441d11e1da2318777ef)] - docs: unify config in quickstart (#1094) (Yiyu He <>) +- [[`c31bc15`](http://github.com/eggjs/egg/commit/c31bc15097c692d08596a277c69fbd44f9d3e2bf)] - test: wait logger to flush (#1090) (Haoliang Gao <>) +- [[`82d2158`](http://github.com/eggjs/egg/commit/82d2158e4c399ead9567b67dc27d13d1ef2e104e)] - docs: add Enclose.IO to Links (#1089) (Minqi Pan <>) ## 2017-06-21, Version 1.5.0, @fengmk2 ### Notable changes -* **feature** - * better TypeScript support, add `index.d.ts` file. - * enable overrideMethod middleware by default. -* **document** - * Documents improved. - -### Commits - - * [[`1d02601`](http://github.com/eggjs/egg/commit/1d026019df76525d2d9117c260eb5d892388121c)] - tsd: add another properties of FileStream (#1080) (Rwing <>) - * [[`2b1644e`](http://github.com/eggjs/egg/commit/2b1644e6d56e6481ee97bce009c5f53b4dd18441)] - feat: add tsd (#1027) (Eward Song <>) - * [[`a4ba2a2`](http://github.com/eggjs/egg/commit/a4ba2a2a1ef7de49e196c01447fd73ab22ed6d34)] - feat: enable overrideMethod middleware by default (#1069) (fengmk2 <>) - * [[`bfb8df5`](http://github.com/eggjs/egg/commit/bfb8df58bcc7d7fe0fd6ff3453efcb54b715b4a0)] - docs: typo (#1060) (chenbin92 <>) - * [[`64d1b00`](http://github.com/eggjs/egg/commit/64d1b0026648e1128f09efb6e6c2cc7f632bf608)] - docs: add chrome devtools debug information (#1050) (ไป™ๆฃฎ <>) - * [[`4e510b2`](http://github.com/eggjs/egg/commit/4e510b22836096a47d562dbd5ca8affd28f94f9e)] - chore: use app.httpRequest() instead of supertest (#1041) (fengmk2 <>) - * [[`78a13d5`](http://github.com/eggjs/egg/commit/78a13d52c3b6e8b40a0015b285cda33a059c0ee4)] - docs: add more description at quickstart (#1042) (TZ | ๅคฉ็Œช <>) - * [[`ef7c864`](http://github.com/eggjs/egg/commit/ef7c864fbddf7e70afbd93a16d5176787328400d)] - docs: add ant.design link (#1037) (Haoliang Gao <>) - * [[`f1b510c`](http://github.com/eggjs/egg/commit/f1b510c34039259c5772021432ab71a7a62b89e8)] - feat: add config.logger.disableConsoleAfterReady (#1001) (fengmk2 <>) - * [[`4890eda`](http://github.com/eggjs/egg/commit/4890eda31b9bc60ea4a1a7f36460ec1bf86dc134)] - docs: Uniform the standards that we should acquire this parsed parameโ€ฆ (#1038) (Ruanyq <>) - * [[`9d705e4`](http://github.com/eggjs/egg/commit/9d705e4687cdb98d327fbd9a1061604828218dfc)] - test: make sure app close (#1030) (fengmk2 <>) - * [[`1d72e37`](http://github.com/eggjs/egg/commit/1d72e3799822e252934d6218a978c2bd21f378d3)] - docs: fix caseStyle link (#1033) (Desen Meng <>) - * [[`9b50725`](http://github.com/eggjs/egg/commit/9b507250725ef3beda0ee51ac0c2bc2b007b2ecb)] - docs: (tutorials/index.md & async-function.md ): [translate] Done (#1028) (Darren Wong <>) - * [[`3d04199`](http://github.com/eggjs/egg/commit/3d041992912d9aca1eb0edc6b226474022e08236)] - docs: typo (#1029) (Jerry Wu <>) - * [[`13b7c19`](http://github.com/eggjs/egg/commit/13b7c19531d772a2b932ada28e186a0dbd0cf5f5)] - test: node 8 (#976) (fengmk2 <>) - * [[`1b108a7`](http://github.com/eggjs/egg/commit/1b108a72a96d3d8241b332b8e728a9ec409efbb1)] - docs: remove api that is from egg-rest (#1022) (Haoliang Gao <>) - * [[`057bc47`](http://github.com/eggjs/egg/commit/057bc47e4c5e3ec8faae0de3807f656fa4ef41d4)] - test: add doc test (#989) (Haoliang Gao <>) - * [[`c6eb7b2`](http://github.com/eggjs/egg/commit/c6eb7b2f59f24fe0c6a787829d33cdf0cd4a2e77)] - doc: fix view config doc (#991) (ๅฝ“่ฝฉ <>) - * [[`52865b4`](http://github.com/eggjs/egg/commit/52865b47c4d336833ef1151bae9f30867359ceb6)] - docs: devtool inspect at 8.x (#1018) (TZ | ๅคฉ็Œช <>) - * [[`8a120fd`](http://github.com/eggjs/egg/commit/8a120fde73df60e23f8c5559a3281acaf0a393e0)] - docs: remove max time limit at schdule (#995) (TZ | ๅคฉ็Œช <>) - * [[`9084c24`](http://github.com/eggjs/egg/commit/9084c24dd10fcbcd0d436ada9639b59f36dd2edf)] - docs: add plugin list (#988) (Haoliang Gao <>) - * [[`20a5d91`](http://github.com/eggjs/egg/commit/20a5d9127f7454c899f7701f02b04eefa7c61fce)] - test: disable coverage for schedule (#987) (Haoliang Gao <>) - * [[`3de963f`](http://github.com/eggjs/egg/commit/3de963f3881ef6fb9c5b6fa207730c6695853239)] - docs(basics/structure.md): [translate] (#970) (Weilun Xiong <<330815461@qq.com>>) - * [[`2f232f3`](http://github.com/eggjs/egg/commit/2f232f30b0ba7e14ab07c43e34d363bac3906a43)] - docs: file must appear after other fiels when using getFileStream (#982) (Yiyu He <>) +- **feature** + - better TypeScript support, add `index.d.ts` file. + - enable overrideMethod middleware by default. +- **document** + - Documents improved. + +### Commits + +- [[`1d02601`](http://github.com/eggjs/egg/commit/1d026019df76525d2d9117c260eb5d892388121c)] - tsd: add another properties of FileStream (#1080) (Rwing <>) +- [[`2b1644e`](http://github.com/eggjs/egg/commit/2b1644e6d56e6481ee97bce009c5f53b4dd18441)] - feat: add tsd (#1027) (Eward Song <>) +- [[`a4ba2a2`](http://github.com/eggjs/egg/commit/a4ba2a2a1ef7de49e196c01447fd73ab22ed6d34)] - feat: enable overrideMethod middleware by default (#1069) (fengmk2 <>) +- [[`bfb8df5`](http://github.com/eggjs/egg/commit/bfb8df58bcc7d7fe0fd6ff3453efcb54b715b4a0)] - docs: typo (#1060) (chenbin92 <>) +- [[`64d1b00`](http://github.com/eggjs/egg/commit/64d1b0026648e1128f09efb6e6c2cc7f632bf608)] - docs: add chrome devtools debug information (#1050) (ไป™ๆฃฎ <>) +- [[`4e510b2`](http://github.com/eggjs/egg/commit/4e510b22836096a47d562dbd5ca8affd28f94f9e)] - chore: use app.httpRequest() instead of supertest (#1041) (fengmk2 <>) +- [[`78a13d5`](http://github.com/eggjs/egg/commit/78a13d52c3b6e8b40a0015b285cda33a059c0ee4)] - docs: add more description at quickstart (#1042) (TZ | ๅคฉ็Œช <>) +- [[`ef7c864`](http://github.com/eggjs/egg/commit/ef7c864fbddf7e70afbd93a16d5176787328400d)] - docs: add ant.design link (#1037) (Haoliang Gao <>) +- [[`f1b510c`](http://github.com/eggjs/egg/commit/f1b510c34039259c5772021432ab71a7a62b89e8)] - feat: add config.logger.disableConsoleAfterReady (#1001) (fengmk2 <>) +- [[`4890eda`](http://github.com/eggjs/egg/commit/4890eda31b9bc60ea4a1a7f36460ec1bf86dc134)] - docs: Uniform the standards that we should acquire this parsed parameโ€ฆ (#1038) (Ruanyq <>) +- [[`9d705e4`](http://github.com/eggjs/egg/commit/9d705e4687cdb98d327fbd9a1061604828218dfc)] - test: make sure app close (#1030) (fengmk2 <>) +- [[`1d72e37`](http://github.com/eggjs/egg/commit/1d72e3799822e252934d6218a978c2bd21f378d3)] - docs: fix caseStyle link (#1033) (Desen Meng <>) +- [[`9b50725`](http://github.com/eggjs/egg/commit/9b507250725ef3beda0ee51ac0c2bc2b007b2ecb)] - docs: (tutorials/index.md & async-function.md ): [translate] Done (#1028) (Darren Wong <>) +- [[`3d04199`](http://github.com/eggjs/egg/commit/3d041992912d9aca1eb0edc6b226474022e08236)] - docs: typo (#1029) (Jerry Wu <>) +- [[`13b7c19`](http://github.com/eggjs/egg/commit/13b7c19531d772a2b932ada28e186a0dbd0cf5f5)] - test: node 8 (#976) (fengmk2 <>) +- [[`1b108a7`](http://github.com/eggjs/egg/commit/1b108a72a96d3d8241b332b8e728a9ec409efbb1)] - docs: remove api that is from egg-rest (#1022) (Haoliang Gao <>) +- [[`057bc47`](http://github.com/eggjs/egg/commit/057bc47e4c5e3ec8faae0de3807f656fa4ef41d4)] - test: add doc test (#989) (Haoliang Gao <>) +- [[`c6eb7b2`](http://github.com/eggjs/egg/commit/c6eb7b2f59f24fe0c6a787829d33cdf0cd4a2e77)] - doc: fix view config doc (#991) (ๅฝ“่ฝฉ <>) +- [[`52865b4`](http://github.com/eggjs/egg/commit/52865b47c4d336833ef1151bae9f30867359ceb6)] - docs: devtool inspect at 8.x (#1018) (TZ | ๅคฉ็Œช <>) +- [[`8a120fd`](http://github.com/eggjs/egg/commit/8a120fde73df60e23f8c5559a3281acaf0a393e0)] - docs: remove max time limit at schdule (#995) (TZ | ๅคฉ็Œช <>) +- [[`9084c24`](http://github.com/eggjs/egg/commit/9084c24dd10fcbcd0d436ada9639b59f36dd2edf)] - docs: add plugin list (#988) (Haoliang Gao <>) +- [[`20a5d91`](http://github.com/eggjs/egg/commit/20a5d9127f7454c899f7701f02b04eefa7c61fce)] - test: disable coverage for schedule (#987) (Haoliang Gao <>) +- [[`3de963f`](http://github.com/eggjs/egg/commit/3de963f3881ef6fb9c5b6fa207730c6695853239)] - docs(basics/structure.md): [translate] (#970) (Weilun Xiong <<330815461@qq.com>>) +- [[`2f232f3`](http://github.com/eggjs/egg/commit/2f232f30b0ba7e14ab07c43e34d363bac3906a43)] - docs: file must appear after other fiels when using getFileStream (#982) (Yiyu He <>) ## 2017-05-28, Version 1.4.0, @dead-horse ### Notable changes -* **feature** - * use lru to aovid oom when httpclient dns cache enabled -* **fix** - * fix port is missed when httpclient dns cache enabled - * fix request url object will be changed when httpclient dns cache enabled - * set maxSockets defautl value to Number.MAX_SAFE_INTEGER -* **document** - * Documents improved. Thanks @DarrenWong, @zousandian, @lslxdx, @Azard, @johnnychen, @coogleyao, @DanielWLam, @m31271n, @Brian175 - -### Commits - -* [[`7370a62`](http://github.com/eggjs/egg/commit/7370a62e190db55dab3fde7f39f621f449301eaa)] - docs: translate tutorials/restful.md (#908) (Darren Wong <>) -* [[`5d8ca65`](http://github.com/eggjs/egg/commit/5d8ca654f311c52fd5faaa939943071c3f69f43f)] - docs: translatebasics/controller.md (#889) (lslxdx <>) -* [[`5b959e0`](http://github.com/eggjs/egg/commit/5b959e0a382491b3111afb66e10b6e866105e0c8)] - docs: translate tutorials/progressive.md to English version (#966) (Darren Wong <>) -* [[`35fa5a9c`](http://github.com/eggjs/egg/commit/35fa5a9c4c2d969f66a5e4df28e1da7f69370709)] - fix: set maxSockets defautl value to Number.MAX_SAFE_INTEGER (#938) (tangyao <<2001-wms@163.com>>) -* [[`5b6fe2b`](http://github.com/eggjs/egg/commit/5b6fe2b187b2c1a4bcee4693b2b1043f2724fe68)] - feat: use lru to aovid oom in dns cache httpclient (#961) (Yiyu He <>) -* [[`3c5c0b8`](http://github.com/eggjs/egg/commit/3c5c0b8d81bb63166f6592390d14277d3baca283)] - docs: Fix objects.md typo (#969) (ไธ‰็‚น <>) -* [[`2bca50b`](http://github.com/eggjs/egg/commit/2bca50b2217424b8cdacd48550dcc39a31e50cff)] - docs(core/unittest.md): update with app.httpRequest() (#943) (Weilun Xiong <<330815461@qq.com>>) -* [[`713e033`](http://github.com/eggjs/egg/commit/713e033f90eb39aad8ac48916985396ca5282815)] - docs: app.controller.foo instead of 'foo' (#942) (Yiyu He <>) -* [[`cfc76ec`](http://github.com/eggjs/egg/commit/cfc76ec721460780d703ead1dfdd315ed484e5c8)] - fix spell error from sign to signed (#932) (johnnychen <>) -* [[`12499d6`](http://github.com/eggjs/egg/commit/12499d636dd471f35e54aad9f09b5f452ea198bf)] - docs: fix yield db.query for en (#930) (Yao Mengfei <>) -* [[`25c7c95`](http://github.com/eggjs/egg/commit/25c7c95bff9eb51baf4f93724444982209872895)] - docs: translate basics/router.md (#896) (lslxdx <>) -* [[`a5c7ac4`](http://github.com/eggjs/egg/commit/a5c7ac462a275c5393f93308a7f31b21cba524a2)] - docs: translate basics/service.md (lslxdx <>) -* [[`7ee5de6`](http://github.com/eggjs/egg/commit/7ee5de6b0ad628332a5c130eb5a405b993a98c60)] - docs: translate basics/extend.md (#884) (DanielLam <>) -* [[`9bf3a65`](http://github.com/eggjs/egg/commit/9bf3a6511469ee85963096836ae8c2421313448d)] - docs: Update env.md (#918) (m31271n <>) -* [[`b3825f3`](http://github.com/eggjs/egg/commit/b3825f33406c01ebc19b16519eccfca9f60e770f)] - docs: fix objects.md (#928) (Yiyu He <>) -* [[`fd04ea2`](http://github.com/eggjs/egg/commit/fd04ea222af962e7fe9b82d108a0bd6f23b32891)] - docs: add document for built-in objects (#914) (Yiyu He <>) -* [[`6180d5d`](http://github.com/eggjs/egg/commit/6180d5db90047a58222ba24d660c1a19b93648f3)] - docs: use names of constants declared (#923) (Yao Mengfei <>) -* [[`02b02e0`](http://github.com/eggjs/egg/commit/02b02e0faf0d423105136723b9d2938a182fd486)] - docs: using a doctools as a external lib (#913) (Haoliang Gao <>) -* [[`5113088`](http://github.com/eggjs/egg/commit/51130889ad8d75baa157c43d9b88e7d08c6067fe)] - fix(docs): yield db.query (#921) (Yao Mengfei <>) -* [[`ddd342c`](http://github.com/eggjs/egg/commit/ddd342c84358319aaffe9ee6eab90c2df1a2e9dc)] - docs: translate basic/config.md (#875) (Brian175 <>) -* [[`ae99e5d`](http://github.com/eggjs/egg/commit/ae99e5d6ee032171d17ce7ce67a8cb3c2f7bd04b)] - fix(docs): basics/structure.md link agent typo (#909) (Weilun Xiong <<330815461@qq.com>>) -* [[`fac3e0c`](http://github.com/eggjs/egg/commit/fac3e0c7306b1143698c29a3685c8116c36b1434)] - refactor: rename private method name to symbol (#904) (Yu Qi <>) -* [[`8115c57`](http://github.com/eggjs/egg/commit/8115c575ea082a92ebda5e4fd08ba4ad37e47bc0)] - docs: translate docs/source/zh-cn/tutorials/mysql.md (#883) (Darren Wong <>) -* [[`e13c515`](http://github.com/eggjs/egg/commit/e13c515226566ae3c87c35b575a8e914e75c6a0b)] - Release 1.3.0 (#885) (fengmk2 <>) +- **feature** + - use lru to aovid oom when httpclient dns cache enabled +- **fix** + - fix port is missed when httpclient dns cache enabled + - fix request url object will be changed when httpclient dns cache enabled + - set maxSockets defautl value to Number.MAX_SAFE_INTEGER +- **document** + - Documents improved. Thanks @DarrenWong, @zousandian, @lslxdx, @Azard, @johnnychen, @coogleyao, @DanielWLam, @m31271n, @Brian175 + +### Commits + +- [[`7370a62`](http://github.com/eggjs/egg/commit/7370a62e190db55dab3fde7f39f621f449301eaa)] - docs: translate tutorials/restful.md (#908) (Darren Wong <>) +- [[`5d8ca65`](http://github.com/eggjs/egg/commit/5d8ca654f311c52fd5faaa939943071c3f69f43f)] - docs: translatebasics/controller.md (#889) (lslxdx <>) +- [[`5b959e0`](http://github.com/eggjs/egg/commit/5b959e0a382491b3111afb66e10b6e866105e0c8)] - docs: translate tutorials/progressive.md to English version (#966) (Darren Wong <>) +- [[`35fa5a9c`](http://github.com/eggjs/egg/commit/35fa5a9c4c2d969f66a5e4df28e1da7f69370709)] - fix: set maxSockets defautl value to Number.MAX_SAFE_INTEGER (#938) (tangyao <<2001-wms@163.com>>) +- [[`5b6fe2b`](http://github.com/eggjs/egg/commit/5b6fe2b187b2c1a4bcee4693b2b1043f2724fe68)] - feat: use lru to aovid oom in dns cache httpclient (#961) (Yiyu He <>) +- [[`3c5c0b8`](http://github.com/eggjs/egg/commit/3c5c0b8d81bb63166f6592390d14277d3baca283)] - docs: Fix objects.md typo (#969) (ไธ‰็‚น <>) +- [[`2bca50b`](http://github.com/eggjs/egg/commit/2bca50b2217424b8cdacd48550dcc39a31e50cff)] - docs(core/unittest.md): update with app.httpRequest() (#943) (Weilun Xiong <<330815461@qq.com>>) +- [[`713e033`](http://github.com/eggjs/egg/commit/713e033f90eb39aad8ac48916985396ca5282815)] - docs: app.controller.foo instead of 'foo' (#942) (Yiyu He <>) +- [[`cfc76ec`](http://github.com/eggjs/egg/commit/cfc76ec721460780d703ead1dfdd315ed484e5c8)] - fix spell error from sign to signed (#932) (johnnychen <>) +- [[`12499d6`](http://github.com/eggjs/egg/commit/12499d636dd471f35e54aad9f09b5f452ea198bf)] - docs: fix yield db.query for en (#930) (Yao Mengfei <>) +- [[`25c7c95`](http://github.com/eggjs/egg/commit/25c7c95bff9eb51baf4f93724444982209872895)] - docs: translate basics/router.md (#896) (lslxdx <>) +- [[`a5c7ac4`](http://github.com/eggjs/egg/commit/a5c7ac462a275c5393f93308a7f31b21cba524a2)] - docs: translate basics/service.md (lslxdx <>) +- [[`7ee5de6`](http://github.com/eggjs/egg/commit/7ee5de6b0ad628332a5c130eb5a405b993a98c60)] - docs: translate basics/extend.md (#884) (DanielLam <>) +- [[`9bf3a65`](http://github.com/eggjs/egg/commit/9bf3a6511469ee85963096836ae8c2421313448d)] - docs: Update env.md (#918) (m31271n <>) +- [[`b3825f3`](http://github.com/eggjs/egg/commit/b3825f33406c01ebc19b16519eccfca9f60e770f)] - docs: fix objects.md (#928) (Yiyu He <>) +- [[`fd04ea2`](http://github.com/eggjs/egg/commit/fd04ea222af962e7fe9b82d108a0bd6f23b32891)] - docs: add document for built-in objects (#914) (Yiyu He <>) +- [[`6180d5d`](http://github.com/eggjs/egg/commit/6180d5db90047a58222ba24d660c1a19b93648f3)] - docs: use names of constants declared (#923) (Yao Mengfei <>) +- [[`02b02e0`](http://github.com/eggjs/egg/commit/02b02e0faf0d423105136723b9d2938a182fd486)] - docs: using a doctools as a external lib (#913) (Haoliang Gao <>) +- [[`5113088`](http://github.com/eggjs/egg/commit/51130889ad8d75baa157c43d9b88e7d08c6067fe)] - fix(docs): yield db.query (#921) (Yao Mengfei <>) +- [[`ddd342c`](http://github.com/eggjs/egg/commit/ddd342c84358319aaffe9ee6eab90c2df1a2e9dc)] - docs: translate basic/config.md (#875) (Brian175 <>) +- [[`ae99e5d`](http://github.com/eggjs/egg/commit/ae99e5d6ee032171d17ce7ce67a8cb3c2f7bd04b)] - fix(docs): basics/structure.md link agent typo (#909) (Weilun Xiong <<330815461@qq.com>>) +- [[`fac3e0c`](http://github.com/eggjs/egg/commit/fac3e0c7306b1143698c29a3685c8116c36b1434)] - refactor: rename private method name to symbol (#904) (Yu Qi <>) +- [[`8115c57`](http://github.com/eggjs/egg/commit/8115c575ea082a92ebda5e4fd08ba4ad37e47bc0)] - docs: translate docs/source/zh-cn/tutorials/mysql.md (#883) (Darren Wong <>) +- [[`e13c515`](http://github.com/eggjs/egg/commit/e13c515226566ae3c87c35b575a8e914e75c6a0b)] - Release 1.3.0 (#885) (fengmk2 <>) ## 2017-05-11, Version 1.3.0, @fengmk2 ### Notable changes - * **document** - * Documents improved. Thanks @Rwing, @lslxdx, @solarhell, @magicdawn - * API document is out https://eggjs.org/api/ - * **refactor** - * Set coreLogger's consoleLevel to WARN in local env +- **document** + - Documents improved. Thanks @Rwing, @lslxdx, @solarhell, @magicdawn + - API document is out https://eggjs.org/api/ +- **refactor** + - Set coreLogger's consoleLevel to WARN in local env ### Commits - * [[`bd6681a`](http://github.com/eggjs/egg/commit/bd6681a509f74af7f39b1505962c0d75958ae0d3)] - chore: typo eggg=>egg (#881) (Rwing <>) - * [[`22c9cd9`](http://github.com/eggjs/egg/commit/22c9cd96df19bb43d1681ce0cffc59bc930c8f0f)] - docs: translated & proofread 'middleware.md' (#784) (lslxdx <>) - * [[`e55a134`](http://github.com/eggjs/egg/commit/e55a13439ec297081d33a7eb2f87ece605581908)] - docs: Add a link to issue template (#853) (Haoliang Gao <>) - * [[`b01d30e`](http://github.com/eggjs/egg/commit/b01d30e33e9b910ee24d69d3b55e2dbe887ff4e3)] - docs: Fix typo. (#869) (jethro <>) - * [[`b3403b5`](http://github.com/eggjs/egg/commit/b3403b56a5635394a4dc9825ef2780850449e573)] - docs: fix view typo (#867) (Tao <>) - * [[`5d6e067`](http://github.com/eggjs/egg/commit/5d6e067fc36697b7c01f290bccac06ce21fb4371)] - chore: add quality badge (#857) (ไป™ๆฃฎ <>) - * [[`8d6755b`](http://github.com/eggjs/egg/commit/8d6755b33c54d6230d1b20141dd6d043ed6c3897)] - deps: upgrade dependencies (#854) (Haoliang Gao <>) - * [[`bd0a827`](http://github.com/eggjs/egg/commit/bd0a827c38f0a2cff42c8a73909081a1f9cd939a)] - refactor: set consoleLevel WARN of coreLogger in local (#850) (Haoliang Gao <>) - * [[`af174ef`](http://github.com/eggjs/egg/commit/af174efb0a0dfe545849d03f8ec1fbee34559dae)] - docs: Add API document to menu (#845) (Haoliang Gao <>) - * [[`edfc07e`](http://github.com/eggjs/egg/commit/edfc07e841b751a4c195544167f50a2ad56971e8)] - chore: generate puml (#842) (Haoliang Gao <>) +- [[`bd6681a`](http://github.com/eggjs/egg/commit/bd6681a509f74af7f39b1505962c0d75958ae0d3)] - chore: typo eggg=>egg (#881) (Rwing <>) +- [[`22c9cd9`](http://github.com/eggjs/egg/commit/22c9cd96df19bb43d1681ce0cffc59bc930c8f0f)] - docs: translated & proofread 'middleware.md' (#784) (lslxdx <>) +- [[`e55a134`](http://github.com/eggjs/egg/commit/e55a13439ec297081d33a7eb2f87ece605581908)] - docs: Add a link to issue template (#853) (Haoliang Gao <>) +- [[`b01d30e`](http://github.com/eggjs/egg/commit/b01d30e33e9b910ee24d69d3b55e2dbe887ff4e3)] - docs: Fix typo. (#869) (jethro <>) +- [[`b3403b5`](http://github.com/eggjs/egg/commit/b3403b56a5635394a4dc9825ef2780850449e573)] - docs: fix view typo (#867) (Tao <>) +- [[`5d6e067`](http://github.com/eggjs/egg/commit/5d6e067fc36697b7c01f290bccac06ce21fb4371)] - chore: add quality badge (#857) (ไป™ๆฃฎ <>) +- [[`8d6755b`](http://github.com/eggjs/egg/commit/8d6755b33c54d6230d1b20141dd6d043ed6c3897)] - deps: upgrade dependencies (#854) (Haoliang Gao <>) +- [[`bd0a827`](http://github.com/eggjs/egg/commit/bd0a827c38f0a2cff42c8a73909081a1f9cd939a)] - refactor: set consoleLevel WARN of coreLogger in local (#850) (Haoliang Gao <>) +- [[`af174ef`](http://github.com/eggjs/egg/commit/af174efb0a0dfe545849d03f8ec1fbee34559dae)] - docs: Add API document to menu (#845) (Haoliang Gao <>) +- [[`edfc07e`](http://github.com/eggjs/egg/commit/edfc07e841b751a4c195544167f50a2ad56971e8)] - chore: generate puml (#842) (Haoliang Gao <>) ## 2017-05-04, Version 1.2.1, @popomore ### Notable changes - * **fix** - * loadPlugin can be extended +- **fix** + - loadPlugin can be extended ### Commits - * [[`13587667`](http://github.com/eggjs/egg/commit/13587667ac019ca516ae11aea728e84966dc57a5)] - fix(loader): loadPlugin can be extended (#836) (Haoliang Gao <>) - * [[`1a027ad7`](http://github.com/eggjs/egg/commit/1a027ad727468d48afe45d1f3ce54de2e4ecfd16)] - test: use assert instead of should (#837) (Haoliang Gao <>) - * [[`89b4df9d`](http://github.com/eggjs/egg/commit/89b4df9d21ddf07efd246145c52141a72e07ad80)] - docs: fix wrong name in chinese router doc (#833) (Tomatoo <<424203705@qq.com>>) +- [[`13587667`](http://github.com/eggjs/egg/commit/13587667ac019ca516ae11aea728e84966dc57a5)] - fix(loader): loadPlugin can be extended (#836) (Haoliang Gao <>) +- [[`1a027ad7`](http://github.com/eggjs/egg/commit/1a027ad727468d48afe45d1f3ce54de2e4ecfd16)] - test: use assert instead of should (#837) (Haoliang Gao <>) +- [[`89b4df9d`](http://github.com/eggjs/egg/commit/89b4df9d21ddf07efd246145c52141a72e07ad80)] - docs: fix wrong name in chinese router doc (#833) (Tomatoo <<424203705@qq.com>>) ## 2017-04-28, Version 1.2.0, @popomore ### Notable changes - * **document** - * Documents improved, Thanks @Rwing, @bingqichen, @okoala, @binsee, @lslxdx - * **feature** - * Move BaseContextClass to egg and add BaseContextLogger [#816](https://github.com/eggjs/egg/pull/816) - * Remove logger config in local environment [#695](https://github.com/eggjs/egg/pull/695) - -### Commits - - * [[`0757655c`](http://github.com/eggjs/egg/commit/0757655cfed451ab3b1ca5a480fb96a3da908708)] - feat: BaseContextClass add logger (#816) (Yiyu He <>) - * [[`9871e450`](http://github.com/eggjs/egg/commit/9871e45098ab4927236382656c4ac774eeffcd11)] - docs: only use inspect at 7.x+ (#813) (TZ | ๅคฉ็Œช <>) - * [[`394bf371`](http://github.com/eggjs/egg/commit/394bf3711312f09d851be728b718e4d0f8fc9c1f)] - docs:Modify some words (#811) (binsee <>) - * [[`1132779c`](http://github.com/eggjs/egg/commit/1132779c4057bf96be1b73a3473b1545c3b5ab7a)] - docs(head.swig):fix the document page anchor position offset. (#790) (binsee <>) - * [[`9ef9d6aa`](http://github.com/eggjs/egg/commit/9ef9d6aa5953106555f11ac5dee6fe544773ceb8)] - fix(package.json & doc.js): fix doc tool error. (#791) (binsee <>) - * [[`90234efb`](http://github.com/eggjs/egg/commit/90234efbae13066ced3d25e8ba7201c0197c3ab1)] - docs(middleware.md): fix grammar (lslxdx <>) - * [[`9200a51d`](http://github.com/eggjs/egg/commit/9200a51d5b5c530a8f5ce8af4dd61f38981dc4c8)] - docs(basic/controller.md): typo 'matchs' -> 'matches' (#802) (lslxdx <>) - * [[`b4eb05b3`](http://github.com/eggjs/egg/commit/b4eb05b301bb1226edfc634ec90d1a5ae53514e2)] - docs(zh-cn docs):fix some link and link text in docs (#789) (binsee <>) - * [[`df1bf345`](http://github.com/eggjs/egg/commit/df1bf3459fd03f948532f7b6d2d436a74c54ed59)] - docs: add inspector protocol vscode debug (#776) (ไป™ๆฃฎ <>) - * [[`a8893f7e`](http://github.com/eggjs/egg/commit/a8893f7e7d9937d675d8be0da7bed0f2c259ae39)] - docs: add vscode debug (#751) (#767) (ไป™ๆฃฎ <>) - * [[`d4c345d3`](http://github.com/eggjs/egg/commit/d4c345d3d29266e0eb248eecee27bc0e492f5e5e)] - docs: typo fix "aync => async" (BingqiChen <>) - * [[`492c97d6`](http://github.com/eggjs/egg/commit/492c97d61c75911ae0e987f65325a5c7493f63b9)] - docs: add vscode plugin link (#756) (TZ | ๅคฉ็Œช <>) - * [[`2bf23fef`](http://github.com/eggjs/egg/commit/2bf23feffb7b9ff1bc07d072a4052eec863d001c)] - docs: link plugins to github search results (#755) (Yiyu He <>) - * [[`5befb0b1`](http://github.com/eggjs/egg/commit/5befb0b1f0f525ba778d54a5dedb72f2e880ab60)] - feat: remove egg logger local config (#695) (TZ | ๅคฉ็Œช <>) - * [[`1ab42e02`](http://github.com/eggjs/egg/commit/1ab42e0243354eab7f602faebd76d7117038e877)] - docs: document for middleware order (#724) (Haoliang Gao <>) - * [[`d6be9499`](http://github.com/eggjs/egg/commit/d6be949973002880a2fe71313c7630f7f94fde97)] - chore: remove chinese commnets (#749) (Yiyu He <>) - * [[`3bdbcae2`](http://github.com/eggjs/egg/commit/3bdbcae2486073447849f6e09831860dc42995d6)] - docs: fix typo, egg-bin => egg-init (#747) (Rwing <>) +- **document** + - Documents improved, Thanks @Rwing, @bingqichen, @okoala, @binsee, @lslxdx +- **feature** + - Move BaseContextClass to egg and add BaseContextLogger [#816](https://github.com/eggjs/egg/pull/816) + - Remove logger config in local environment [#695](https://github.com/eggjs/egg/pull/695) + +### Commits + +- [[`0757655c`](http://github.com/eggjs/egg/commit/0757655cfed451ab3b1ca5a480fb96a3da908708)] - feat: BaseContextClass add logger (#816) (Yiyu He <>) +- [[`9871e450`](http://github.com/eggjs/egg/commit/9871e45098ab4927236382656c4ac774eeffcd11)] - docs: only use inspect at 7.x+ (#813) (TZ | ๅคฉ็Œช <>) +- [[`394bf371`](http://github.com/eggjs/egg/commit/394bf3711312f09d851be728b718e4d0f8fc9c1f)] - docs:Modify some words (#811) (binsee <>) +- [[`1132779c`](http://github.com/eggjs/egg/commit/1132779c4057bf96be1b73a3473b1545c3b5ab7a)] - docs(head.swig):fix the document page anchor position offset. (#790) (binsee <>) +- [[`9ef9d6aa`](http://github.com/eggjs/egg/commit/9ef9d6aa5953106555f11ac5dee6fe544773ceb8)] - fix(package.json & doc.js): fix doc tool error. (#791) (binsee <>) +- [[`90234efb`](http://github.com/eggjs/egg/commit/90234efbae13066ced3d25e8ba7201c0197c3ab1)] - docs(middleware.md): fix grammar (lslxdx <>) +- [[`9200a51d`](http://github.com/eggjs/egg/commit/9200a51d5b5c530a8f5ce8af4dd61f38981dc4c8)] - docs(basic/controller.md): typo 'matchs' -> 'matches' (#802) (lslxdx <>) +- [[`b4eb05b3`](http://github.com/eggjs/egg/commit/b4eb05b301bb1226edfc634ec90d1a5ae53514e2)] - docs(zh-cn docs):fix some link and link text in docs (#789) (binsee <>) +- [[`df1bf345`](http://github.com/eggjs/egg/commit/df1bf3459fd03f948532f7b6d2d436a74c54ed59)] - docs: add inspector protocol vscode debug (#776) (ไป™ๆฃฎ <>) +- [[`a8893f7e`](http://github.com/eggjs/egg/commit/a8893f7e7d9937d675d8be0da7bed0f2c259ae39)] - docs: add vscode debug (#751) (#767) (ไป™ๆฃฎ <>) +- [[`d4c345d3`](http://github.com/eggjs/egg/commit/d4c345d3d29266e0eb248eecee27bc0e492f5e5e)] - docs: typo fix "aync => async" (BingqiChen <>) +- [[`492c97d6`](http://github.com/eggjs/egg/commit/492c97d61c75911ae0e987f65325a5c7493f63b9)] - docs: add vscode plugin link (#756) (TZ | ๅคฉ็Œช <>) +- [[`2bf23fef`](http://github.com/eggjs/egg/commit/2bf23feffb7b9ff1bc07d072a4052eec863d001c)] - docs: link plugins to github search results (#755) (Yiyu He <>) +- [[`5befb0b1`](http://github.com/eggjs/egg/commit/5befb0b1f0f525ba778d54a5dedb72f2e880ab60)] - feat: remove egg logger local config (#695) (TZ | ๅคฉ็Œช <>) +- [[`1ab42e02`](http://github.com/eggjs/egg/commit/1ab42e0243354eab7f602faebd76d7117038e877)] - docs: document for middleware order (#724) (Haoliang Gao <>) +- [[`d6be9499`](http://github.com/eggjs/egg/commit/d6be949973002880a2fe71313c7630f7f94fde97)] - chore: remove chinese commnets (#749) (Yiyu He <>) +- [[`3bdbcae2`](http://github.com/eggjs/egg/commit/3bdbcae2486073447849f6e09831860dc42995d6)] - docs: fix typo, egg-bin => egg-init (#747) (Rwing <>) ## 2017-04-11, Version 1.1.0, @fengmk2 ### Notable changes - * **document** - * Lots of documents improve and typo fixes. Thanks @lslxdx, @zhennann, @dotnil, @no7dw, @cuyl, @Andiedie, @kylezhang, - @SF-Zhou, @yandongxu, @jemmyzheng, @Carrotzpc, @zbinlin, @OneNewLife, @monkindey, @simman, - @demohi, @xwang1024 and @davidnotes - * **feature** - * warn if some confused configurations exist in config [#637](https://github.com/eggjs/egg/pull/637) - * use extend2 instead of extend to support `Array` config value [#674](https://github.com/eggjs/egg/pull/674) - * expose context base classes on Application instance, make app or framework override context extend more easily [#737](https://github.com/eggjs/egg/pull/737) - * expose egg.Controller and egg.Service [#741](https://github.com/eggjs/egg/pull/741) - * **fix** - * remove unused `jsonp` context delegate to response, please use [jsonp middleware instead](https://eggjs.org/zh-cn/basics/controller.html#jsonp) [#739](https://github.com/eggjs/egg/pull/739) - -### Commits - - * [[`241b4e8`](http://github.com/eggjs/egg/commit/241b4e83c05e7086493564e536f5ce69d17dde0c)] - feat: expose egg.Controller and egg.Service (#741) (Yiyu He <>) - * [[`26efa42`](http://github.com/eggjs/egg/commit/26efa427cf34e0ef0482d69fc10a77280e5fea5e)] - fix: remove unused jsonp delegate (#739) (Yiyu He <>) - * [[`c33523d`](http://github.com/eggjs/egg/commit/c33523db3e086eafd1f7bc7486c6d1b2b68335e3)] - feat: export context base classes on Application (#737) (fengmk2 <>) - * [[`ee127ad`](http://github.com/eggjs/egg/commit/ee127ad46b33a19d43c84a04649569a404a7f6af)] - docs: add sub directory support for controller (#734) (Yiyu He <>) - * [[`88a1669`](http://github.com/eggjs/egg/commit/88a166933478373c4fd5cdd349d3b63e00cbaf7e)] - docs: typo at controller.md (#720) (lslxdx <>) - * [[`4c298c2`](http://github.com/eggjs/egg/commit/4c298c2c70017d12688e2801bfe6e66886ba24bd)] - docs: async-function typo, change generator to async (#712) (zhennann <>) - * [[`a9d27d0`](http://github.com/eggjs/egg/commit/a9d27d0ab3f3dea89487fc1e8c084b9ddc7e854d)] - docs: add schedule max interval (#711) (Yiyu He <>) - * [[`9e94b7b`](http://github.com/eggjs/egg/commit/9e94b7b31106ce578a67dd15984d847587527299)] - docs: little grammar issues (#707) (Chen Yangjian <>) - * [[`a4d12ec`](http://github.com/eggjs/egg/commit/a4d12ecc6c468ebf37ff6acba06e65b15cfde4f4)] - chore: remove unused config (#694) (Yiyu He <>) - * [[`88449f9`](http://github.com/eggjs/egg/commit/88449f9b292d69bd2f936f0ecb037efecbed2e8e)] - docs: add webstorm debug (#689) (TZ | ๅคฉ็Œช <>) - * [[`8517625`](http://github.com/eggjs/egg/commit/8517625b44f36909169032f8fff3ced3e1910a47)] - docs: correct spelling mistake (#682) (Wade Deng <>) - * [[`92ef92b`](http://github.com/eggjs/egg/commit/92ef92b7cec015d2843c9d7cb113694ad7ca34ec)] - docs: faq add where are my logs (#680) (Yiyu He <>) - * [[`b8fc4e4`](http://github.com/eggjs/egg/commit/b8fc4e460e2dcffe60364a71dec2d07bd354d2cf)] - deps: use extend2 instead of extend (#674) (Yiyu He <>) - * [[`0ccbcf9`](http://github.com/eggjs/egg/commit/0ccbcf98be8946891b520321743d3b5a95899955)] - docs: fix example code syntax error & typos (#672) (cuyl <<463060544@qq.com>>) - * [[`1486705`](http://github.com/eggjs/egg/commit/14867059b5070b274cbee26df3accf5463eb4fe8)] - docs: security match and ignore (#668) (Yiyu He <>) - * [[`7ab3791`](http://github.com/eggjs/egg/commit/7ab37915afc4a197cc58bc477e5b96cb1a73ced1)] - test: test for closing logger (#667) (Haoliang Gao <>) - * [[`5f5cf91`](http://github.com/eggjs/egg/commit/5f5cf91a6af118ebc558252e07bcfa0f094045e3)] - docs(quickstart): tip for controller and config style (#666) (TZ | ๅคฉ็Œช <>) - * [[`e47c24b`](http://github.com/eggjs/egg/commit/e47c24b3f1fd27b0f545f107913d6c6e1cae53ac)] - docs: fix example code typos (#629) (SF-Zhou <>) - * [[`7900576`](http://github.com/eggjs/egg/commit/7900576e690d038e4d75891890c467c743f03605)] - docs: fix egg-session-redis code (#642) (ๅ‘จ้•ฟๅฎ‰ <>) - * [[`8c77e59`](http://github.com/eggjs/egg/commit/8c77e5907834cb110a99a4ace0356868107c88e6)] - feat: warn if some confused configurations exist in config (#637) (Yiyu He <>) - * [[`cd8c659`](http://github.com/eggjs/egg/commit/cd8c65965dc62fe7d45598450d6ef31ab344b878)] - docs: fix some typo (#638) (kyle <>) - * [[`7d830b7`](http://github.com/eggjs/egg/commit/7d830b7c92f81a9d133b7f1e6fe71b3d8a8d5a31)] - docs: fix reference framework path (#634) (kyle <>) - * [[`a471e93`](http://github.com/eggjs/egg/commit/a471e93977e67c98280af8517100bfe48495bbb2)] - docs: fix example code in basics/middleware (#624) (SF-Zhou <>) - * [[`e87c170`](http://github.com/eggjs/egg/commit/e87c170770c117d275fd84c02a9fb1e699fa94cf)] - docs: fix code syntax (#628) (dongxu <>) - * [[`531dadd`](http://github.com/eggjs/egg/commit/531dadd7c3f8bd813c365d705ce7293a719e98f3)] - docs(security): Cookie of token, the key must be csrfToken (#625) (jemmy zheng <>) - * [[`8d73b02`](http://github.com/eggjs/egg/commit/8d73b02dcb856e3d8075aa34bc47a2f6dbb3af2b)] - docs: move cnzz to layout (#622) (Haoliang Gao <>) - * [[`077bebe`](http://github.com/eggjs/egg/commit/077bebe17889d8a0cff2a1dbfebd72b4b8147ab3)] - docs: fix table render error in en env.md (#621) (SF-Zhou <>) - * [[`990d45e`](http://github.com/eggjs/egg/commit/990d45e75f2d73b9bb4cddbf76e67452740e3178)] - docs: fixed table render error in env.md (#619) (SF-Zhou <>) - * [[`e9428ba`](http://github.com/eggjs/egg/commit/e9428ba95fcd07ba255359a968dd027932ce2f77)] - docs: improve left padding when window between 1005 and 1130 (#617) (Haoliang Gao <>) - * [[`c22e005`](http://github.com/eggjs/egg/commit/c22e0055ca8df35c1aa9d7d6ed7e31c21dd4b547)] - docs: turn off safe write in Jetbrains softwares (#614) (Shawn <>) - * [[`2296b7b`](http://github.com/eggjs/egg/commit/2296b7b22cc3e240bb676444d4fd2f953338cea5)] - docs: fix document deploy (#609) (Haoliang Gao <>) +- **document** + - Lots of documents improve and typo fixes. Thanks @lslxdx, @zhennann, @dotnil, @no7dw, @cuyl, @Andiedie, @kylezhang, + @SF-Zhou, @yandongxu, @jemmyzheng, @Carrotzpc, @zbinlin, @OneNewLife, @monkindey, @simman, + @demohi, @xwang1024 and @davidnotes +- **feature** + - warn if some confused configurations exist in config [#637](https://github.com/eggjs/egg/pull/637) + - use extend2 instead of extend to support `Array` config value [#674](https://github.com/eggjs/egg/pull/674) + - expose context base classes on Application instance, make app or framework override context extend more easily [#737](https://github.com/eggjs/egg/pull/737) + - expose egg.Controller and egg.Service [#741](https://github.com/eggjs/egg/pull/741) +- **fix** + - remove unused `jsonp` context delegate to response, please use [jsonp middleware instead](https://eggjs.org/zh-cn/basics/controller.html#jsonp) [#739](https://github.com/eggjs/egg/pull/739) + +### Commits + +- [[`241b4e8`](http://github.com/eggjs/egg/commit/241b4e83c05e7086493564e536f5ce69d17dde0c)] - feat: expose egg.Controller and egg.Service (#741) (Yiyu He <>) +- [[`26efa42`](http://github.com/eggjs/egg/commit/26efa427cf34e0ef0482d69fc10a77280e5fea5e)] - fix: remove unused jsonp delegate (#739) (Yiyu He <>) +- [[`c33523d`](http://github.com/eggjs/egg/commit/c33523db3e086eafd1f7bc7486c6d1b2b68335e3)] - feat: export context base classes on Application (#737) (fengmk2 <>) +- [[`ee127ad`](http://github.com/eggjs/egg/commit/ee127ad46b33a19d43c84a04649569a404a7f6af)] - docs: add sub directory support for controller (#734) (Yiyu He <>) +- [[`88a1669`](http://github.com/eggjs/egg/commit/88a166933478373c4fd5cdd349d3b63e00cbaf7e)] - docs: typo at controller.md (#720) (lslxdx <>) +- [[`4c298c2`](http://github.com/eggjs/egg/commit/4c298c2c70017d12688e2801bfe6e66886ba24bd)] - docs: async-function typo, change generator to async (#712) (zhennann <>) +- [[`a9d27d0`](http://github.com/eggjs/egg/commit/a9d27d0ab3f3dea89487fc1e8c084b9ddc7e854d)] - docs: add schedule max interval (#711) (Yiyu He <>) +- [[`9e94b7b`](http://github.com/eggjs/egg/commit/9e94b7b31106ce578a67dd15984d847587527299)] - docs: little grammar issues (#707) (Chen Yangjian <>) +- [[`a4d12ec`](http://github.com/eggjs/egg/commit/a4d12ecc6c468ebf37ff6acba06e65b15cfde4f4)] - chore: remove unused config (#694) (Yiyu He <>) +- [[`88449f9`](http://github.com/eggjs/egg/commit/88449f9b292d69bd2f936f0ecb037efecbed2e8e)] - docs: add webstorm debug (#689) (TZ | ๅคฉ็Œช <>) +- [[`8517625`](http://github.com/eggjs/egg/commit/8517625b44f36909169032f8fff3ced3e1910a47)] - docs: correct spelling mistake (#682) (Wade Deng <>) +- [[`92ef92b`](http://github.com/eggjs/egg/commit/92ef92b7cec015d2843c9d7cb113694ad7ca34ec)] - docs: faq add where are my logs (#680) (Yiyu He <>) +- [[`b8fc4e4`](http://github.com/eggjs/egg/commit/b8fc4e460e2dcffe60364a71dec2d07bd354d2cf)] - deps: use extend2 instead of extend (#674) (Yiyu He <>) +- [[`0ccbcf9`](http://github.com/eggjs/egg/commit/0ccbcf98be8946891b520321743d3b5a95899955)] - docs: fix example code syntax error & typos (#672) (cuyl <<463060544@qq.com>>) +- [[`1486705`](http://github.com/eggjs/egg/commit/14867059b5070b274cbee26df3accf5463eb4fe8)] - docs: security match and ignore (#668) (Yiyu He <>) +- [[`7ab3791`](http://github.com/eggjs/egg/commit/7ab37915afc4a197cc58bc477e5b96cb1a73ced1)] - test: test for closing logger (#667) (Haoliang Gao <>) +- [[`5f5cf91`](http://github.com/eggjs/egg/commit/5f5cf91a6af118ebc558252e07bcfa0f094045e3)] - docs(quickstart): tip for controller and config style (#666) (TZ | ๅคฉ็Œช <>) +- [[`e47c24b`](http://github.com/eggjs/egg/commit/e47c24b3f1fd27b0f545f107913d6c6e1cae53ac)] - docs: fix example code typos (#629) (SF-Zhou <>) +- [[`7900576`](http://github.com/eggjs/egg/commit/7900576e690d038e4d75891890c467c743f03605)] - docs: fix egg-session-redis code (#642) (ๅ‘จ้•ฟๅฎ‰ <>) +- [[`8c77e59`](http://github.com/eggjs/egg/commit/8c77e5907834cb110a99a4ace0356868107c88e6)] - feat: warn if some confused configurations exist in config (#637) (Yiyu He <>) +- [[`cd8c659`](http://github.com/eggjs/egg/commit/cd8c65965dc62fe7d45598450d6ef31ab344b878)] - docs: fix some typo (#638) (kyle <>) +- [[`7d830b7`](http://github.com/eggjs/egg/commit/7d830b7c92f81a9d133b7f1e6fe71b3d8a8d5a31)] - docs: fix reference framework path (#634) (kyle <>) +- [[`a471e93`](http://github.com/eggjs/egg/commit/a471e93977e67c98280af8517100bfe48495bbb2)] - docs: fix example code in basics/middleware (#624) (SF-Zhou <>) +- [[`e87c170`](http://github.com/eggjs/egg/commit/e87c170770c117d275fd84c02a9fb1e699fa94cf)] - docs: fix code syntax (#628) (dongxu <>) +- [[`531dadd`](http://github.com/eggjs/egg/commit/531dadd7c3f8bd813c365d705ce7293a719e98f3)] - docs(security): Cookie of token, the key must be csrfToken (#625) (jemmy zheng <>) +- [[`8d73b02`](http://github.com/eggjs/egg/commit/8d73b02dcb856e3d8075aa34bc47a2f6dbb3af2b)] - docs: move cnzz to layout (#622) (Haoliang Gao <>) +- [[`077bebe`](http://github.com/eggjs/egg/commit/077bebe17889d8a0cff2a1dbfebd72b4b8147ab3)] - docs: fix table render error in en env.md (#621) (SF-Zhou <>) +- [[`990d45e`](http://github.com/eggjs/egg/commit/990d45e75f2d73b9bb4cddbf76e67452740e3178)] - docs: fixed table render error in env.md (#619) (SF-Zhou <>) +- [[`e9428ba`](http://github.com/eggjs/egg/commit/e9428ba95fcd07ba255359a968dd027932ce2f77)] - docs: improve left padding when window between 1005 and 1130 (#617) (Haoliang Gao <>) +- [[`c22e005`](http://github.com/eggjs/egg/commit/c22e0055ca8df35c1aa9d7d6ed7e31c21dd4b547)] - docs: turn off safe write in Jetbrains softwares (#614) (Shawn <>) +- [[`2296b7b`](http://github.com/eggjs/egg/commit/2296b7b22cc3e240bb676444d4fd2f953338cea5)] - docs: fix document deploy (#609) (Haoliang Gao <>) ## 2017-03-21, Version 1.0.0, @popomore @@ -2084,352 +2054,328 @@ Release the first stable version :egg: :clap::clap::clap: ### Commits - * [[`a3ad38d`](http://github.com/eggjs/egg/commit/a3ad38d649ff8eb0cd6dfcbe338466f1c59afef3)] - docs: fix HttpClient link in docs (#599) (Luobo Zhang <>) - * [[`242a4a1`](http://github.com/eggjs/egg/commit/242a4a1fbecfc4efa37cca58d1861040dd5838bd)] - docs: fix session's maxage (#598) (Yiyu He <>) - * [[`ee77e5c`](http://github.com/eggjs/egg/commit/ee77e5cdcb444f86bf9f50bfd89a63dd9321449f)] - docs: fix some typo (#597) (kyle <>) - * [[`984d732`](http://github.com/eggjs/egg/commit/984d7320881adf9420e5c7e49d62d5530ad887dd)] - refactor: app.cluster auto bind this (#570) (zลng yว” <>) - * [[`4687f0f`](http://github.com/eggjs/egg/commit/4687f0f47566373938f9f928ac1dc4fa62590f4d)] - docs: fix session link (#595) (TZ | ๅคฉ็Œช <>) - * [[`3849c1c`](http://github.com/eggjs/egg/commit/3849c1c4b8f0354b12fd17bb884c33ef9e115e3c)] - docs: fix typo of httpclient & unittest (#591) (kyle <>) - * [[`871aa82`](http://github.com/eggjs/egg/commit/871aa82d28eeb026de6633cafbe168cca8ad3182)] - docs: add gitter & more controller ctx style (#585) (TZ | ๅคฉ็Œช <>) - * [[`a172960`](http://github.com/eggjs/egg/commit/a1729604959af84878dddb2776d621ee01c2d447)] - docs: typo (kyle <>) - * [[`54c10bc`](http://github.com/eggjs/egg/commit/54c10bc085b380f4f003d2f7987c205264dde1ad)] - docs: change controller showcase style to ctx (#568) (TZ | ๅคฉ็Œช <>) - * [[`d131f23`](http://github.com/eggjs/egg/commit/d131f236111981d7fb7021998bed200a46a4603d)] - docs: fix typo in docs (#563) (Jason Lee <>) - * [[`497b9a9`](http://github.com/eggjs/egg/commit/497b9a9e7c5cdcb0b769691ea40a74a4d284cfff)] - docs(faq): fix cluster link (#557) (Mars Wong <>) - * [[`0d37e42`](http://github.com/eggjs/egg/commit/0d37e42259647ce9cb43deeba7a887817c7ef408)] - docs: update the style for search (#558) (TZ | ๅคฉ็Œช <>) - * [[`24ef44f`](http://github.com/eggjs/egg/commit/24ef44fa662392c7b80dbba8da0c4d5a7c9b83dd)] - docs: fix typo (#565) (Colin Cheng <>) - * [[`9eecf7b`](http://github.com/eggjs/egg/commit/9eecf7b0f928fc33d47e93782c79289ca2a13289)] - docs: rule for transforming filepath to properties (#547) (Haoliang Gao <>) - * [[`d088283`](http://github.com/eggjs/egg/commit/d0882837c34a8b950a11e4f8fe4f47f29d8823f7)] - feat: show warning message with call stack (#549) (fengmk2 <>) - * [[`4a89c3b`](http://github.com/eggjs/egg/commit/4a89c3b563ef79f5ad557ef741c16f283c11e835)] - docs: replace customEgg to framework (#545) (fengmk2 <>) - * [[`c1464fb`](http://github.com/eggjs/egg/commit/c1464fbecb27caa0dc6766147d3b13d790466386)] - docs: more detail for mysql dynamic create (#540) (TZ | ๅคฉ็Œช <>) - -1.0.0-rc.3 / 2017-03-10 -======================= - - * docs: fix doc scroll bug (#532) - * test: fix development test (#546) - * doc: add Algolia docsearch (#542) - * feat: [BREAKING_CHANGE] override array when load config (#522) - * docs: fix cookie example (#533) - * feat: ignore types when dump (#518) - * docs: rotate csrf token (#520) - * refactor: [BREAKING CHANGE] remove userservice and userrole (#527) - * refactor: [BREAKING_CHANGE] remove default validate plugin (#526) - * docs: fix doc build (#524) - * docs: fix middleware typo (#519) - * docs(quickstart): fix keys again (#515) - * docs(quickstart): fix keys (#511) - * docs: add cookie and session (#510) - * docs: fix html closing tag in quickstart (#512) - * docs: quickstart tip (#502) - * docs: add English version of `egg and koa` (#490) - * feat: remove default customEgg (#487) - * doc: add the view config for the egg-view-nunjucks (#496) - * test: add qs security test cases (#491) - * docs: remove meaningless word (#488) - -1.0.0-rc.2 / 2017-03-01 -======================= - - * deps: upgrade egg-session@2 to support external session store (#480) - * docs: fix view plugin config at quickstart (#482) - * docs: update document for view that using egg-view (#475) - * docs: add config merge to faq (#478) - * docs(doc): add english version of "what is egg" (#462) - * docs: fix deployment link (#473) - * docs: add document for deployment (#448) - * test: travis test on node 8 using nightly building (#464) - * docs: seperate cluster-and-ipc and cluster-client (#441) - * docs: fixed typos 'BS' (#461) - * docs: fixed spelling mistake (#460) - * test: disable error log to stderr (#453) - * docs: fix async-function demo link (#457) - * feat: throw if config.keys not exists when access app.keys (#443) - * docs: add year to licence && mysql docs (#447) - * feat: extend runInBackground on application (#442) - -1.0.0-rc.1 / 2017-02-23 -======================= - - * feat: [BREAKING_CHANGE] reimplement view, use egg-view plugin (#402) - * fix: listen CookieLimitExceed in app (#429) - * fix: close gracefully (#419) - * docs: correct spelling mistake (#424) - * feat: log error when cookie value's length exceed the limit (#418) - * docs: Update mysql.md (#422) - * docs: add more complete example code for quickstart (#412) - * fix: deprecate warning when inspect & toJSON (#408) - * docs: should listen egg-ready using messenger (#406) - * docs: correct english description at README (#400) - * docs: fix character type error and link reference error (#396) - * docs: add csrf to faq (#393) - * fix: keep unhandledRejectionError err object stack (#390) - * docs: use compress replace bodyparser for example (#391) - * docs: add directory structure (#383) - * docs: add api-doc (#369) - * docs: how to use koa's middleware (#386) - * feat: dump config both after loaded and ready (#377) - * docs: fix filename in config.md (#376) - * docs: add plugin dep name description (#374) - * docs: update version automatically (#367) - * doc: add pm2 faq (#370) - * docs: fix jsonp config in controller.md (#372) - * feat: [BREAKING_CHANGE] remove notfound.enableRedirect (#368) - * docs: add resource page (#364) - * docs: add config result description (#365) - * deps: upgrade egg-mock (#362) - * docs: english wip description & remove unuse file (#361) - * docs: add tutorials index & fix async (#359) - -0.12.0 / 2017-02-12 -=================== - - * docs: fix async link (#357) - * docs: add async await (#349) - * docs: typo Github > GitHub (#356) - * docs: update site style (#340) - * deps: upgrade egg-core (#350) - * docs: add description to config/env file (#348) - * docs: add APIClient concept to cluster doc (#344) - * test: add async test case (#339) - * feat: view base promise to support async function (#343) - * feat: curl return promise (#342) - * test: add class style controller tests (#336) - * docs: add cnzz (#335) - * test: improve coverage to 100% (#333) - * docs: update egg-and-koa with async function (#334) - * fix: remove tair and hsf (#332) - * docs: quickstart - use controller class (#329) - -0.11.0 / 2017-02-07 -=================== - - * feat: remove overrideMethod middleware (#324) - * feat: remove worker client, use app.cluster (#282) - * chore(scripts): Add PATH to find hexo (#327) - * docs: fix quickstart example code (#326) - * chore(scripts): deploy document by travis (#325) - * docs: add httpclient tracer demo and docs (#313) - * feat: close cluster clients before app close (#310) - * test: mv benchmark to eggjs/benchmark (#320) - * docs: document for plugin.{env}.js and the reason of plugin name (#321) - * docs: add sigleton in plugin.md (#316) - * docs: plugin and framework list use github tags (#318) - * docs: remove outdated docs (#319) - * docs: controller support class and refactor jsonp (#314) - * docs: add more details about csrf (#315) - -0.10.0 / 2017-02-03 -=================== - - * feat: remove tracer (#311) - * refactor: use app.beforeClose (#306) - * feat: move ctx.runtime to egg-instrument (#302) - * feat: merge the api of application/agent from extend to instance (#294) - * docs: add egg-security config to router docs (#303) - * style: fix code style for app and config (#300) - * refactor: remove ctx.jsonp and add egg-jsonp plugin (#299) - * docs: fix typo $app to app (#297) - * docs: remove inner links (#298) - -0.9.0 / 2017-01-22 -================== - - * feat: remove isAjax (#295) - * test: fix cookie test cases (#296) - * docs: adjust some words (#291) - * feat: move clusterPort to egg-cluster (#281) - * feat: move app.Service egg-core (#279) - * docs: change egg-bin to egg-init (#284) - * docs: improve framework doc based on eggjs/examples#9 (#267) - * feat: remove instrument (#283) - * docs: add progressive link && adjust en docs directory (#275) - * docs: add progressive usage (#268) - -0.8.0 / 2017-01-18 -================== - - * test: dep -> dependencies (#270) - * docs: translate zh-cn/basics/app-start.md into english (#222) - * docs: fix quickstart typo (#266) - * docs: add http client debug docs (#265) - * docs: modify and fix 3 points (#264) - * docs(intro): improve decription (#263) - * docs: fix docs site version (#262) - * docs: Fix typo. (#261) - * docs: review 1st version docs (#257) - * fix: typo conext -> context (#259) - * docs: contributing && readme && deps (#253) - * docs: fix quickstart link in index.html (#256) - * docs: set the default locale zh-cn (#255) - * refactor: ctx.realStatus delegate ctx.response.realStatus (#252) - * docs: Add intro/index.md (#246) - * feat: adjust default plugins (#251) - * docs: add RESTful documents (#247) - * feat: delegate ctx.jsonp to ctx.response.jsonp (#248) - * chore: remove examples (#245) - * docs: improve mysql doc - * docs: add mysql doc - * docs: view (#228) - * docs: improve doc theme (#230) - * docs: add core/unittest.md (#199) - * docs: add advanced/framework.md (#225) - -0.7.0 / 2017-01-12 -================== - - * docs: add service doc (#221) - * docs: serverEnv => env (#239) - * feat: delegate configurations in app (#233) - * refactor: remove ctx.getCookie, ctx.setCookie and ctx.deleteCookie (#240) - * docs: remove mon-printable character (#242) - * feat: support app.config.proxy to identify app is behind a proxy (#231) - * doc: add plugin doc (#224) - * docs: add Quick Start in English (#223) - * docs: add basics/controller.md (#209) - * docs: add core/development.md (#214) - * docs: remove init.js from document, use app.beforeStart (#229) - * docs: quickstart (#217) - * docs: add security plugin doc (#196) - * docs: mv cluster.md to zh-cn (#216) - * feat: add cluster-client (#191) - * docs: add basics/router.md (#203) - * docs: add advanced/loader.md (#198) - * docs: fix i18n doc (#210) - * docs: add core/i18n.md (#208) - * docs: add core/httpclient document (#197) - * docs: typo (#207) - * docs: add core/logger.md (#204) - * docs: add one more reason why not use koa 2 (#206) - * docs: add error handling (#205) - * docs: add schedule (#202) - * docs: add english translation of basics/env.md - * docs: basics/middleware (#194) - * docs: add basics/config.md (#188) - * doc: app start (#193) - * docs: rename koa.md to egg-and-koa.md (#190) - * docs: egg and koa (#179) - * doc: add basics/env.md (#178) - * doc: rename guide/basics/extend.md to basics/extend.md (#189) - * doc: guide/basics/extend doc (#187) - -0.6.3 / 2016-12-30 -================== - - * refactor: use logger.close, .end is deprecated (#171) - -0.6.2 / 2016-12-22 -================== - - * refactor(config): set keepAliveTimeout 4000ms by default (#165) - -0.6.1 / 2016-12-21 -================== - - * refactor: use sendToApp/sendToAgent in worker client - * fix: protocolHeaders can split with whitespace (#164) - * deps: update version (#157) - -0.6.0 / 2016-12-03 -================== - - * deps: egg-cookies@2 (#155) - * fix: already supported in egg-core (#154) - * feat: body parser support disable, ignore and match (#150) - * feat: use appInfo.root in config (#147) - * test: refactor workclient test cases (#145) - * feat: add a dns cache httpclient (#146) - -0.5.0 / 2016-11-04 -================== - - * deps: upgrade dependencies (#144) - * feat: warn when agent send message before started (#143) - * feat: [BREAKING_CHANGE] refactor Messenger (#141) - * feat: print error to console on unittest env (#139) - * feat: add ip setter on request (#138) - * feat: add getLogger to app and ctx (#136) - * test: remove co-sleep deps - * test: add local server for curl test cases - * test: use fs read instead of curl test on runInBackground - -0.4.0 / 2016-10-29 -================== - - * deps: update version (#135) - * feat: support background task on ctx (#119) - * chore: add middleware example (#121) - -0.3.0 / 2016-10-28 -================== - - * test: fix unstable test (#133) - * feat: close return promise (#128) - * deps: update deps version (#113) - * fix: AppWorkerClient subscribe same data failed issue (#110) - -0.2.1 / 2016-09-16 -================== - - * feat(application): emit startTimeout event (#107) - * perf: get header using lower case (#106) - * chore: remove --fix for error check but not fix (#101) - * doc: Add Installation (#95) - * doc: add title (#94) - -0.2.0 / 2016-09-03 -================== - - * docs: improve documents - * test: update benchmark scripts (#79) - * test: add router for bench cases (#78) - * fix: set header use lowercase (#76) - * test: add toa benchmark (#75) - * test: add benchmark results (#74) - * test: fix security tests (#73) - * test: egg-view-nunjucks change views -> view (#72) - -0.1.3 / 2016-08-31 -================== - - * fix: utils.assign support undefined (#71) - * refactor: change accept to getter (#68) - -0.1.2 / 2016-08-31 -================== - - * deps: egg-security@1 (#67) - * Revert raw header (#65) - * feat: [BREAKING_CHANGE] remove poweredBy && config.core (#63) - -0.1.1 / 2016-08-29 -================== - - * refactor: use ctx.setRawHeader (#61) - * chore: add benchmarks (#62) - * fix(meta): remove server-id (#56) - * feat(response): add res.setRawHeader (#60) - * refator: use utils.assign instead of Object.assign (#59) - * feat: docs structure (#55) - * docs: web.md and web.zh_CN.md (#54) +- [[`a3ad38d`](http://github.com/eggjs/egg/commit/a3ad38d649ff8eb0cd6dfcbe338466f1c59afef3)] - docs: fix HttpClient link in docs (#599) (Luobo Zhang <>) +- [[`242a4a1`](http://github.com/eggjs/egg/commit/242a4a1fbecfc4efa37cca58d1861040dd5838bd)] - docs: fix session's maxage (#598) (Yiyu He <>) +- [[`ee77e5c`](http://github.com/eggjs/egg/commit/ee77e5cdcb444f86bf9f50bfd89a63dd9321449f)] - docs: fix some typo (#597) (kyle <>) +- [[`984d732`](http://github.com/eggjs/egg/commit/984d7320881adf9420e5c7e49d62d5530ad887dd)] - refactor: app.cluster auto bind this (#570) (zลng yว” <>) +- [[`4687f0f`](http://github.com/eggjs/egg/commit/4687f0f47566373938f9f928ac1dc4fa62590f4d)] - docs: fix session link (#595) (TZ | ๅคฉ็Œช <>) +- [[`3849c1c`](http://github.com/eggjs/egg/commit/3849c1c4b8f0354b12fd17bb884c33ef9e115e3c)] - docs: fix typo of httpclient & unittest (#591) (kyle <>) +- [[`871aa82`](http://github.com/eggjs/egg/commit/871aa82d28eeb026de6633cafbe168cca8ad3182)] - docs: add gitter & more controller ctx style (#585) (TZ | ๅคฉ็Œช <>) +- [[`a172960`](http://github.com/eggjs/egg/commit/a1729604959af84878dddb2776d621ee01c2d447)] - docs: typo (kyle <>) +- [[`54c10bc`](http://github.com/eggjs/egg/commit/54c10bc085b380f4f003d2f7987c205264dde1ad)] - docs: change controller showcase style to ctx (#568) (TZ | ๅคฉ็Œช <>) +- [[`d131f23`](http://github.com/eggjs/egg/commit/d131f236111981d7fb7021998bed200a46a4603d)] - docs: fix typo in docs (#563) (Jason Lee <>) +- [[`497b9a9`](http://github.com/eggjs/egg/commit/497b9a9e7c5cdcb0b769691ea40a74a4d284cfff)] - docs(faq): fix cluster link (#557) (Mars Wong <>) +- [[`0d37e42`](http://github.com/eggjs/egg/commit/0d37e42259647ce9cb43deeba7a887817c7ef408)] - docs: update the style for search (#558) (TZ | ๅคฉ็Œช <>) +- [[`24ef44f`](http://github.com/eggjs/egg/commit/24ef44fa662392c7b80dbba8da0c4d5a7c9b83dd)] - docs: fix typo (#565) (Colin Cheng <>) +- [[`9eecf7b`](http://github.com/eggjs/egg/commit/9eecf7b0f928fc33d47e93782c79289ca2a13289)] - docs: rule for transforming filepath to properties (#547) (Haoliang Gao <>) +- [[`d088283`](http://github.com/eggjs/egg/commit/d0882837c34a8b950a11e4f8fe4f47f29d8823f7)] - feat: show warning message with call stack (#549) (fengmk2 <>) +- [[`4a89c3b`](http://github.com/eggjs/egg/commit/4a89c3b563ef79f5ad557ef741c16f283c11e835)] - docs: replace customEgg to framework (#545) (fengmk2 <>) +- [[`c1464fb`](http://github.com/eggjs/egg/commit/c1464fbecb27caa0dc6766147d3b13d790466386)] - docs: more detail for mysql dynamic create (#540) (TZ | ๅคฉ็Œช <>) + +# 1.0.0-rc.3 / 2017-03-10 + +- docs: fix doc scroll bug (#532) +- test: fix development test (#546) +- doc: add Algolia docsearch (#542) +- feat: [BREAKING_CHANGE] override array when load config (#522) +- docs: fix cookie example (#533) +- feat: ignore types when dump (#518) +- docs: rotate csrf token (#520) +- refactor: [BREAKING CHANGE] remove userservice and userrole (#527) +- refactor: [BREAKING_CHANGE] remove default validate plugin (#526) +- docs: fix doc build (#524) +- docs: fix middleware typo (#519) +- docs(quickstart): fix keys again (#515) +- docs(quickstart): fix keys (#511) +- docs: add cookie and session (#510) +- docs: fix html closing tag in quickstart (#512) +- docs: quickstart tip (#502) +- docs: add English version of `egg and koa` (#490) +- feat: remove default customEgg (#487) +- doc: add the view config for the egg-view-nunjucks (#496) +- test: add qs security test cases (#491) +- docs: remove meaningless word (#488) + +# 1.0.0-rc.2 / 2017-03-01 + +- deps: upgrade egg-session@2 to support external session store (#480) +- docs: fix view plugin config at quickstart (#482) +- docs: update document for view that using egg-view (#475) +- docs: add config merge to faq (#478) +- docs(doc): add english version of "what is egg" (#462) +- docs: fix deployment link (#473) +- docs: add document for deployment (#448) +- test: travis test on node 8 using nightly building (#464) +- docs: seperate cluster-and-ipc and cluster-client (#441) +- docs: fixed typos 'BS' (#461) +- docs: fixed spelling mistake (#460) +- test: disable error log to stderr (#453) +- docs: fix async-function demo link (#457) +- feat: throw if config.keys not exists when access app.keys (#443) +- docs: add year to licence && mysql docs (#447) +- feat: extend runInBackground on application (#442) + +# 1.0.0-rc.1 / 2017-02-23 + +- feat: [BREAKING_CHANGE] reimplement view, use egg-view plugin (#402) +- fix: listen CookieLimitExceed in app (#429) +- fix: close gracefully (#419) +- docs: correct spelling mistake (#424) +- feat: log error when cookie value's length exceed the limit (#418) +- docs: Update mysql.md (#422) +- docs: add more complete example code for quickstart (#412) +- fix: deprecate warning when inspect & toJSON (#408) +- docs: should listen egg-ready using messenger (#406) +- docs: correct english description at README (#400) +- docs: fix character type error and link reference error (#396) +- docs: add csrf to faq (#393) +- fix: keep unhandledRejectionError err object stack (#390) +- docs: use compress replace bodyparser for example (#391) +- docs: add directory structure (#383) +- docs: add api-doc (#369) +- docs: how to use koa's middleware (#386) +- feat: dump config both after loaded and ready (#377) +- docs: fix filename in config.md (#376) +- docs: add plugin dep name description (#374) +- docs: update version automatically (#367) +- doc: add pm2 faq (#370) +- docs: fix jsonp config in controller.md (#372) +- feat: [BREAKING_CHANGE] remove notfound.enableRedirect (#368) +- docs: add resource page (#364) +- docs: add config result description (#365) +- deps: upgrade egg-mock (#362) +- docs: english wip description & remove unuse file (#361) +- docs: add tutorials index & fix async (#359) + +# 0.12.0 / 2017-02-12 + +- docs: fix async link (#357) +- docs: add async await (#349) +- docs: typo Github > GitHub (#356) +- docs: update site style (#340) +- deps: upgrade egg-core (#350) +- docs: add description to config/env file (#348) +- docs: add APIClient concept to cluster doc (#344) +- test: add async test case (#339) +- feat: view base promise to support async function (#343) +- feat: curl return promise (#342) +- test: add class style controller tests (#336) +- docs: add cnzz (#335) +- test: improve coverage to 100% (#333) +- docs: update egg-and-koa with async function (#334) +- fix: remove tair and hsf (#332) +- docs: quickstart - use controller class (#329) + +# 0.11.0 / 2017-02-07 + +- feat: remove overrideMethod middleware (#324) +- feat: remove worker client, use app.cluster (#282) +- chore(scripts): Add PATH to find hexo (#327) +- docs: fix quickstart example code (#326) +- chore(scripts): deploy document by travis (#325) +- docs: add httpclient tracer demo and docs (#313) +- feat: close cluster clients before app close (#310) +- test: mv benchmark to eggjs/benchmark (#320) +- docs: document for plugin.{env}.js and the reason of plugin name (#321) +- docs: add sigleton in plugin.md (#316) +- docs: plugin and framework list use github tags (#318) +- docs: remove outdated docs (#319) +- docs: controller support class and refactor jsonp (#314) +- docs: add more details about csrf (#315) + +# 0.10.0 / 2017-02-03 + +- feat: remove tracer (#311) +- refactor: use app.beforeClose (#306) +- feat: move ctx.runtime to egg-instrument (#302) +- feat: merge the api of application/agent from extend to instance (#294) +- docs: add egg-security config to router docs (#303) +- style: fix code style for app and config (#300) +- refactor: remove ctx.jsonp and add egg-jsonp plugin (#299) +- docs: fix typo $app to app (#297) +- docs: remove inner links (#298) + +# 0.9.0 / 2017-01-22 + +- feat: remove isAjax (#295) +- test: fix cookie test cases (#296) +- docs: adjust some words (#291) +- feat: move clusterPort to egg-cluster (#281) +- feat: move app.Service egg-core (#279) +- docs: change egg-bin to egg-init (#284) +- docs: improve framework doc based on eggjs/examples#9 (#267) +- feat: remove instrument (#283) +- docs: add progressive link && adjust en docs directory (#275) +- docs: add progressive usage (#268) + +# 0.8.0 / 2017-01-18 + +- test: dep -> dependencies (#270) +- docs: translate zh-cn/basics/app-start.md into english (#222) +- docs: fix quickstart typo (#266) +- docs: add http client debug docs (#265) +- docs: modify and fix 3 points (#264) +- docs(intro): improve decription (#263) +- docs: fix docs site version (#262) +- docs: Fix typo. (#261) +- docs: review 1st version docs (#257) +- fix: typo conext -> context (#259) +- docs: contributing && readme && deps (#253) +- docs: fix quickstart link in index.html (#256) +- docs: set the default locale zh-cn (#255) +- refactor: ctx.realStatus delegate ctx.response.realStatus (#252) +- docs: Add intro/index.md (#246) +- feat: adjust default plugins (#251) +- docs: add RESTful documents (#247) +- feat: delegate ctx.jsonp to ctx.response.jsonp (#248) +- chore: remove examples (#245) +- docs: improve mysql doc +- docs: add mysql doc +- docs: view (#228) +- docs: improve doc theme (#230) +- docs: add core/unittest.md (#199) +- docs: add advanced/framework.md (#225) + +# 0.7.0 / 2017-01-12 + +- docs: add service doc (#221) +- docs: serverEnv => env (#239) +- feat: delegate configurations in app (#233) +- refactor: remove ctx.getCookie, ctx.setCookie and ctx.deleteCookie (#240) +- docs: remove mon-printable character (#242) +- feat: support app.config.proxy to identify app is behind a proxy (#231) +- doc: add plugin doc (#224) +- docs: add Quick Start in English (#223) +- docs: add basics/controller.md (#209) +- docs: add core/development.md (#214) +- docs: remove init.js from document, use app.beforeStart (#229) +- docs: quickstart (#217) +- docs: add security plugin doc (#196) +- docs: mv cluster.md to zh-cn (#216) +- feat: add cluster-client (#191) +- docs: add basics/router.md (#203) +- docs: add advanced/loader.md (#198) +- docs: fix i18n doc (#210) +- docs: add core/i18n.md (#208) +- docs: add core/httpclient document (#197) +- docs: typo (#207) +- docs: add core/logger.md (#204) +- docs: add one more reason why not use koa 2 (#206) +- docs: add error handling (#205) +- docs: add schedule (#202) +- docs: add english translation of basics/env.md +- docs: basics/middleware (#194) +- docs: add basics/config.md (#188) +- doc: app start (#193) +- docs: rename koa.md to egg-and-koa.md (#190) +- docs: egg and koa (#179) +- doc: add basics/env.md (#178) +- doc: rename guide/basics/extend.md to basics/extend.md (#189) +- doc: guide/basics/extend doc (#187) + +# 0.6.3 / 2016-12-30 + +- refactor: use logger.close, .end is deprecated (#171) + +# 0.6.2 / 2016-12-22 + +- refactor(config): set keepAliveTimeout 4000ms by default (#165) + +# 0.6.1 / 2016-12-21 + +- refactor: use sendToApp/sendToAgent in worker client +- fix: protocolHeaders can split with whitespace (#164) +- deps: update version (#157) + +# 0.6.0 / 2016-12-03 + +- deps: egg-cookies@2 (#155) +- fix: already supported in egg-core (#154) +- feat: body parser support disable, ignore and match (#150) +- feat: use appInfo.root in config (#147) +- test: refactor workclient test cases (#145) +- feat: add a dns cache httpclient (#146) + +# 0.5.0 / 2016-11-04 + +- deps: upgrade dependencies (#144) +- feat: warn when agent send message before started (#143) +- feat: [BREAKING_CHANGE] refactor Messenger (#141) +- feat: print error to console on unittest env (#139) +- feat: add ip setter on request (#138) +- feat: add getLogger to app and ctx (#136) +- test: remove co-sleep deps +- test: add local server for curl test cases +- test: use fs read instead of curl test on runInBackground + +# 0.4.0 / 2016-10-29 + +- deps: update version (#135) +- feat: support background task on ctx (#119) +- chore: add middleware example (#121) + +# 0.3.0 / 2016-10-28 + +- test: fix unstable test (#133) +- feat: close return promise (#128) +- deps: update deps version (#113) +- fix: AppWorkerClient subscribe same data failed issue (#110) + +# 0.2.1 / 2016-09-16 + +- feat(application): emit startTimeout event (#107) +- perf: get header using lower case (#106) +- chore: remove --fix for error check but not fix (#101) +- doc: Add Installation (#95) +- doc: add title (#94) + +# 0.2.0 / 2016-09-03 + +- docs: improve documents +- test: update benchmark scripts (#79) +- test: add router for bench cases (#78) +- fix: set header use lowercase (#76) +- test: add toa benchmark (#75) +- test: add benchmark results (#74) +- test: fix security tests (#73) +- test: egg-view-nunjucks change views -> view (#72) + +# 0.1.3 / 2016-08-31 + +- fix: utils.assign support undefined (#71) +- refactor: change accept to getter (#68) + +# 0.1.2 / 2016-08-31 + +- deps: egg-security@1 (#67) +- Revert raw header (#65) +- feat: [BREAKING_CHANGE] remove poweredBy && config.core (#63) + +# 0.1.1 / 2016-08-29 + +- refactor: use ctx.setRawHeader (#61) +- chore: add benchmarks (#62) +- fix(meta): remove server-id (#56) +- feat(response): add res.setRawHeader (#60) +- refator: use utils.assign instead of Object.assign (#59) +- feat: docs structure (#55) +- docs: web.md and web.zh_CN.md (#54) + +# 0.1.0 / 2016-08-18 + +- feat: [BREAKING_CHANGE] use egg-core (#44) +- doc: translate to EN (#25) +- fix: Error of no such file or directory, scandir '/restful_api/app/api' (#42) +- test: fix default plugins test (#37) +- feat: add inner plugins (#24) +- docs: add schedule example (#30) + +# 0.0.5 / 2016-07-20 + +- refactor(core): let ctx.cookies become a getter (#22) +- fix(messenger): init when create app and agent (#21) +- test: add test codes (#20) -0.1.0 / 2016-08-18 -================== +# 0.0.1 / 2016-07-13 - * feat: [BREAKING_CHANGE] use egg-core (#44) - * doc: translate to EN (#25) - * fix: Error of no such file or directory, scandir '/restful_api/app/api' (#42) - * test: fix default plugins test (#37) - * feat: add inner plugins (#24) - * docs: add schedule example (#30) - -0.0.5 / 2016-07-20 -================== - - * refactor(core): let ctx.cookies become a getter (#22) - * fix(messenger): init when create app and agent (#21) - * test: add test codes (#20) - -0.0.1 / 2016-07-13 -================== - - * init version +- init version diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..dc61294815 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,79 @@ + + + +# Using Vite+, the Unified Toolchain for the Web + +This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`. + +## Vite+ Workflow + +`vp` is a global binary that handles the full development lifecycle. Run `vp help` to print a list of commands and `vp --help` for information about a specific command. + +### Start + +- create - Create a new project from a template +- migrate - Migrate an existing project to Vite+ +- config - Configure hooks and agent integration +- staged - Run linters on staged files +- install (`i`) - Install dependencies +- env - Manage Node.js versions + +### Develop + +- dev - Run the development server +- check - Run format, lint, and TypeScript type checks +- lint - Lint code +- fmt - Format code +- test - Run tests + +### Execute + +- run - Run monorepo tasks +- exec - Execute a command from local `node_modules/.bin` +- dlx - Execute a package binary without installing it as a dependency +- cache - Manage the task cache + +### Build + +- build - Build for production +- pack - Build libraries +- preview - Preview production build + +### Manage Dependencies + +Vite+ automatically detects and wraps the underlying package manager such as pnpm, npm, or Yarn through the `packageManager` field in `package.json` or package manager-specific lockfiles. + +- add - Add packages to dependencies +- remove (`rm`, `un`, `uninstall`) - Remove packages from dependencies +- update (`up`) - Update packages to latest versions +- dedupe - Deduplicate dependencies +- outdated - Check for outdated packages +- list (`ls`) - List installed packages +- why (`explain`) - Show why a package is installed +- info (`view`, `show`) - View package information from the registry +- link (`ln`) / unlink - Manage local package links +- pm - Forward a command to the package manager + +### Maintain + +- upgrade - Update `vp` itself to the latest version + +These commands map to their corresponding tools. For example, `vp dev --port 3000` runs Vite's dev server and works the same as Vite. `vp test` runs JavaScript tests through the bundled Vitest. The version of all tools can be checked using `vp --version`. This is useful when researching documentation, features, and bugs. + +## Common Pitfalls + +- **Using the package manager directly:** Do not use pnpm, npm, or Yarn directly. Vite+ can handle all package manager operations. +- **Always use Vite commands to run tools:** Don't attempt to run `vp vitest` or `vp oxlint`. They do not exist. Use `vp test` and `vp lint` instead. +- **Running scripts:** Vite+ commands take precedence over `package.json` scripts. If there is a `test` script defined in `scripts` that conflicts with the built-in `vp test` command, run it using `vp run test`. +- **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly:** Vite+ wraps these tools. They must not be installed directly. You cannot upgrade these tools by installing their latest versions. Always use Vite+ commands. +- **Use Vite+ wrappers for one-off binaries:** Use `vp dlx` instead of package-manager-specific `dlx`/`npx` commands. +- **Import JavaScript modules from `vite-plus`:** Instead of importing from `vite` or `vitest`, all modules should be imported from the project's `vite-plus` dependency. For example, `import { defineConfig } from 'vite-plus';` or `import { expect, test, vi } from 'vite-plus/test';`. You must not install `vitest` to import test utilities. +- **Type-Aware Linting:** There is no need to install `oxlint-tsgolint`, `vp lint --type-aware` works out of the box. + +## Review Checklist for Agents + +- [ ] Run `vp install` after pulling remote changes and before getting started. +- [ ] Run `vp check` and `vp test` to validate changes. + + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 60c879bfa4..dc6ae7c440 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,7 @@ All features must be submitted along with documentations. The documentations sho - Documentations must clarify one or more aspects of the feature, depending on the nature of feature: what it is, why it happens and how it works. - It's better to include a series of procedues to explain how to fix the problem. You are also encourgaed to provide **simple, but self-explanatory** demo. -All demos should be compiled at [eggjs/examples](https://github.com/eggjs/examples) repository. + All demos should be compiled at [eggjs/examples](https://github.com/eggjs/examples) repository. - Please provide essential urls, such as application process, terminology explainations and references. ## Pulling and Submitting Code @@ -217,9 +217,9 @@ In the release of every stable version, there will be a PM who has the following - Confirm that performance test is passed and all issues in current Milestone are either closed or can be delayed to later versions. - Open a new [Release Proposal MR], and write `History` as [node CHANGELOG]. Don't forget to correct content in documentation which is related to the releasing version. Commits can be generated automatically. - ```bash - $ npm run commits - ``` + ```bash + $ npm run commits + ``` - Nominate PM for next stable version. diff --git a/CONTRIBUTING.zh-CN.md b/CONTRIBUTING.zh-CN.md index 7f13de5d60..be3fa8d518 100644 --- a/CONTRIBUTING.zh-CN.md +++ b/CONTRIBUTING.zh-CN.md @@ -25,7 +25,7 @@ - ๆญคๆ—ถ issue ไผš่ขซ้žๅธธ้ซ˜็š„ไผ˜ๅ…ˆ็บง่ฟ›่กŒๅค„็†ใ€‚ - ๅฆ‚ๆžœๆญค bug ๆ˜ฏๆญฃๅœจๅฝฑๅ“็บฟไธŠๅบ”็”จๆญฃๅธธ่ฟ่กŒ๏ผŒไผšๅ†ๆ‰“ไธŠ `critical`๏ผŒไปฃ่กจๆ˜ฏๆœ€้ซ˜ไผ˜ๅ…ˆ็บง๏ผŒ้œ€่ฆ้ฉฌไธŠ็ซ‹ๅˆปๅค„็†๏ผ - bug ไผšๅœจๆœ€ไฝŽ้œ€่ฆไฟฎๅค็š„็‰ˆๆœฌ่ฟ›่กŒไฟฎๅค๏ผŒๅฆ‚ๆ˜ฏๅœจ `0.9.x` ่ฆไฟฎๅค็š„๏ผŒ่€Œๅฝ“ๅ‰ๆœ€ๆ–ฐ็‰ˆๆœฌๆ˜ฏ `1.1.x`๏ผŒ - ้‚ฃไนˆๆญค issue ่ฟ˜ไผš่ขซๆ‰“ไธŠ `0.9`๏ผŒ`0.10`๏ผŒ`1.0`๏ผŒ`1.1`๏ผŒไปฃ่กจ้œ€่ฆไฟฎๅคๅˆฐ่ฟ™ไบ›็‰ˆๆœฌใ€‚ + ้‚ฃไนˆๆญค issue ่ฟ˜ไผš่ขซๆ‰“ไธŠ `0.9`๏ผŒ`0.10`๏ผŒ`1.0`๏ผŒ`1.1`๏ผŒไปฃ่กจ้œ€่ฆไฟฎๅคๅˆฐ่ฟ™ไบ›็‰ˆๆœฌใ€‚ - `core: xx`: ไปฃ่กจ issue ่ทŸ core ๅ†…ๆ ธ็›ธๅ…ณ๏ผŒๅฆ‚ `core: antx` ไปฃ่กจ่ทŸ `antx` ้…็ฝฎ็›ธๅ…ณใ€‚ - `plugin: xx`: ไปฃ่กจ issue ่ทŸๆ’ไปถ็›ธๅ…ณ๏ผŒๅฆ‚ `deps: session` ไปฃ่กจ่ทŸ `session` ๆ’ไปถ็›ธๅ…ณใ€‚ - `deps: xx`: ไปฃ่กจ issue ่ทŸ `dependencies` ๆจกๅ—็›ธๅ…ณ๏ผŒๅฆ‚ `deps: egg-cors` ไปฃ่กจ่ทŸ `egg-cors` ๆจกๅ—็›ธๅ…ณใ€‚ @@ -38,7 +38,7 @@ - ๅฟ…้กป่ฏดๆธ…ๆฅš้—ฎ้ข˜็š„ๅ‡ ไธชๆ–น้ข๏ผšwhat๏ผˆๆ˜ฏไป€ไนˆ๏ผ‰๏ผŒwhy๏ผˆไธบไป€ไนˆ๏ผ‰๏ผŒhow๏ผˆๆ€Žไนˆๅš๏ผ‰๏ผŒๅฏๆ นๆฎ้—ฎ้ข˜็š„็‰นๆ€งๆœ‰ๆ‰€ไพง้‡ใ€‚ - how ้ƒจๅˆ†ๅฟ…้กปๅŒ…ๅซ่ฏฆๅฐฝๅฎŒๆ•ด็š„ๆ“ไฝœๆญฅ้ชค๏ผŒๅฟ…่ฆๆ—ถ้™„ไธŠ **่ถณๅคŸ็ฎ€ๅ•๏ผŒๅฏ่ฟ่กŒ** ็š„่Œƒไพ‹ไปฃ็ ๏ผŒ -ๆ‰€ๆœ‰่Œƒไพ‹ไปฃ็ ๆ”พๅœจ [eggjs/examples](https://github.com/eggjs/examples) ๅบ“ไธญใ€‚ + ๆ‰€ๆœ‰่Œƒไพ‹ไปฃ็ ๆ”พๅœจ [eggjs/examples](https://github.com/eggjs/examples) ๅบ“ไธญใ€‚ - ๆไพ›ๅฟ…่ฆ็š„้“พๆŽฅ๏ผŒๅฆ‚็”ณ่ฏทๆต็จ‹๏ผŒๆœฏ่ฏญ่งฃ้‡Šๅ’Œๅ‚่€ƒๆ–‡ๆกฃ็ญ‰ใ€‚ - ๅŒๆญฅไฟฎๆ”นไธญ่‹ฑๆ–‡ๆ–‡ๆกฃ๏ผŒๆˆ–่€…ๅœจ PR ้‡Œ้ข่ฏดๆ˜Žใ€‚ @@ -163,7 +163,7 @@ BREAKING CHANGE: ่‹ฑ่ฏญๆญฃๆ–‡ๆŒ‰็…งไธ€่ˆฌ่‹ฑ่ฏญ่ฏญๆณ•่ง„ๅพ‹ไนฆๅ†™ๅณๅฏ๏ผŒไฝ†ๆ ‡้ข˜ๆฏ”่พƒ็‰นๆฎŠ๏ผŒๅบ”่ฏฅๆŒ‰็…งไปฅไธ‹่ง„่Œƒ่ฟ›่กŒไนฆๅ†™๏ผš -- ๅ่ฏใ€ๅŠจ่ฏใ€ไปฃ่ฏใ€ๅฝขๅฎน่ฏใ€ๅ‰ฏ่ฏ็ญ‰้ฆ–ๅญ—ๆฏๅคงๅ†™๏ผŒไป‹่ฏใ€ๅ† ่ฏใ€่ฟž่ฏใ€ๆ„Ÿๅน่ฏๅ’ŒๅŠฉ่ฏ้ฆ–ๅญ—ๆฏๅฐๅ†™๏ผŒ*ๆ ‡้ข˜็ฌฌไธ€ไธชๅ•่ฏใ€ๆœ€ๅŽไธ€ไธชๅ•่ฏๆ— ่ฎบ่ฏๆ€ง้ฆ–ๅญ—ๆฏๅบ”่ฏฅๅคงๅ†™*ใ€‚ +- ๅ่ฏใ€ๅŠจ่ฏใ€ไปฃ่ฏใ€ๅฝขๅฎน่ฏใ€ๅ‰ฏ่ฏ็ญ‰้ฆ–ๅญ—ๆฏๅคงๅ†™๏ผŒไป‹่ฏใ€ๅ† ่ฏใ€่ฟž่ฏใ€ๆ„Ÿๅน่ฏๅ’ŒๅŠฉ่ฏ้ฆ–ๅญ—ๆฏๅฐๅ†™๏ผŒ_ๆ ‡้ข˜็ฌฌไธ€ไธชๅ•่ฏใ€ๆœ€ๅŽไธ€ไธชๅ•่ฏๆ— ่ฎบ่ฏๆ€ง้ฆ–ๅญ—ๆฏๅบ”่ฏฅๅคงๅ†™_ใ€‚ - ไธ“ๆœ‰ๅ่ฏ๏ผˆๅฆ‚็›ดๆŽฅๅผ•็”จๆŸไธชๅ˜้‡๏ผŒๆˆ–่€…ๆŸไธชๆ’ไปถๅ็งฐ็ญ‰๏ผ‰๏ผŒๅฟ…้กปไฝฟ็”จๅๅ•ๅผ•ๅท๏ผˆ้”ฎ็›˜ไธŠ Esc ๆญฃไธ‹ๆ–น๏ผ‰่ฟ›่กŒๅผ•็”จ๏ผŒๅนถไฟๆŒๅŽŸๆฅๅคงๅฐๅ†™ใ€‚ - ่ถ…่ฟ‡5ไธชๅญ—ๆฏ็š„ไป‹่ฏ้ฆ–ๅญ—ๆฏๅบ”่ฏฅๅคงๅ†™๏ผŒๅฆๅˆ™ไธ€ๅพ‹ๅฐๅ†™ใ€‚ - ๅฆ‚ๆžœๆ˜ฏ้‡่ฆๆ็คบๆ€งๆ ‡้ข˜๏ผŒๆˆ–่€…ๆ˜ฏไธ“ๆœ‰ๅ็งฐๆ ‡้ข˜๏ผˆไพ‹ๅฆ‚ Http ่ฏทๆฑ‚ๆ–นๆณ•๏ผšGET๏ผŒPOST๏ผŒPUT๏ผŒDELETE๏ผ‰๏ผŒๅฏไปฅๅ…จ้ƒจๅญ—ๆฏ้ƒฝ็”จๅคงๅ†™๏ผˆๆ…Ž้‡่€ƒ่™‘๏ผ‰ใ€‚ @@ -219,9 +219,9 @@ egg ๅŸบไบŽ [semver] ่ฏญไน‰ๅŒ–็‰ˆๆœฌๅท่ฟ›่กŒๅ‘ๅธƒใ€‚ - ็กฎ่ฎคๅฝ“ๅ‰ๅ‘ๅธƒ้‡Œ็จ‹็ข‘ๆ‰€ๆœ‰็š„ๅทฒ็Ÿฅ้—ฎ้ข˜้ƒฝๅทฒๅ…ณ้—ญๆˆ–ๅฏๅปถๆœŸ๏ผŒๅฎŒๆˆๆ€ง่ƒฝๆต‹่ฏ•ใ€‚ - ๅ‘่ตทไธ€ไธชๆ–ฐ็š„ [ๅ‘ๅธƒๅˆๅนถ่ฏทๆฑ‚]๏ผŒๆŒ‰็…ง [node ๅ˜ๆ›ดๆ—ฅๅฟ—] ่ฟ›่กŒ `History` ็š„็ผ–ๅ†™๏ผŒไฟฎๆญฃๆ–‡ๆกฃไธญไธŽ็‰ˆๆœฌ็›ธๅ…ณ็š„ๅ†…ๅฎน๏ผŒcommits ๅฏไปฅ่‡ชๅŠจ็”Ÿๆˆ๏ผš - ```bash - $ npm run commits - ``` + ```bash + $ npm run commits + ``` - ๆŒ‡ๅฎšไธ‹ไธ€ไธชๅคง็‰ˆๆœฌ็š„ PMใ€‚ diff --git a/History.md b/History.md index 861881bbf9..22b30053fd 100644 --- a/History.md +++ b/History.md @@ -1,52 +1,53 @@ - -3.29.0 / 2024-11-30 -================== +# 3.29.0 / 2024-11-30 **features** - * [[`e4f706990`](http://github.com/eggjs/egg/commit/e4f7069904b99c842e65692f2531a72543719207)] - feat: use urllib@4.5.0 (#5371) (fengmk2 <>) -3.28.0 / 2024-09-16 -================== +- [[`e4f706990`](http://github.com/eggjs/egg/commit/e4f7069904b99c842e65692f2531a72543719207)] - feat: use urllib@4.5.0 (#5371) (fengmk2 <>) + +# 3.28.0 / 2024-09-16 **features** - * [[`46d3fb222`](http://github.com/eggjs/egg/commit/46d3fb222bcf455d2aee9a99005d18c271f29b16)] - feat: support allowH2 on urllib@4 (#5357) (fengmk2 <>) -3.27.1 / 2024-07-12 -================== +- [[`46d3fb222`](http://github.com/eggjs/egg/commit/46d3fb222bcf455d2aee9a99005d18c271f29b16)] - feat: support allowH2 on urllib@4 (#5357) (fengmk2 <>) + +# 3.27.1 / 2024-07-12 **fixes** - * [[`f3d8df1b`](http://github.com/eggjs/egg/commit/f3d8df1b7c2aef88cca3beec8c753656f8cc629c)] - fix: add httpclient.safeCurl typing (#5341) (killa <>) -3.27.0 / 2024-07-12 -================== +- [[`f3d8df1b`](http://github.com/eggjs/egg/commit/f3d8df1b7c2aef88cca3beec8c753656f8cc629c)] - fix: add httpclient.safeCurl typing (#5341) (killa <>) + +# 3.27.0 / 2024-07-12 **features** - * [[`68cbd241`](http://github.com/eggjs/egg/commit/68cbd241e2172b8018328d77ea087dd5974a580f)] - feat: impl httpclient.safeCurl (#5339) (killa <>) -3.26.1 / 2024-07-04 -================== +- [[`68cbd241`](http://github.com/eggjs/egg/commit/68cbd241e2172b8018328d77ea087dd5974a580f)] - feat: impl httpclient.safeCurl (#5339) (killa <>) + +# 3.26.1 / 2024-07-04 **fixes** - * [[`872273cb`](http://github.com/eggjs/egg/commit/872273cb23cd6f5d76b3f33528916effade31011)] - fix: xframe value type (#5336) (hongzzz <>) + +- [[`872273cb`](http://github.com/eggjs/egg/commit/872273cb23cd6f5d76b3f33528916effade31011)] - fix: xframe value type (#5336) (hongzzz <>) **others** - * [[`8ae76d09`](http://github.com/eggjs/egg/commit/8ae76d09db8cf020cbdacfc64fee0750b9612136)] - docs: fix typo (#5330) (Fu Yuchen <<78291982+fyc09@users.noreply.github.com>>) -3.26.0 / 2024-07-01 -================== +- [[`8ae76d09`](http://github.com/eggjs/egg/commit/8ae76d09db8cf020cbdacfc64fee0750b9612136)] - docs: fix typo (#5330) (Fu Yuchen <<78291982+fyc09@users.noreply.github.com>>) + +# 3.26.0 / 2024-07-01 **features** - * [[`b0292a8b`](http://github.com/eggjs/egg/commit/b0292a8b7e76d5dbf7441b7164c39441dbae51ec)] - feat: allow to create httpClient from app (#5334) (fengmk2 <>) -3.25.0 / 2024-06-27 -================== +- [[`b0292a8b`](http://github.com/eggjs/egg/commit/b0292a8b7e76d5dbf7441b7164c39441dbae51ec)] - feat: allow to create httpClient from app (#5334) (fengmk2 <>) + +# 3.25.0 / 2024-06-27 **features** - * [[`ceded0b1`](http://github.com/eggjs/egg/commit/ceded0b1c9217503c5ed9226f96c493d6bd00547)] - feat: allow to httpClient use HTTP2 first (#5332) (fengmk2 <>) + +- [[`ceded0b1`](http://github.com/eggjs/egg/commit/ceded0b1c9217503c5ed9226f96c493d6bd00547)] - feat: allow to httpClient use HTTP2 first (#5332) (fengmk2 <>) **others** - * [[`8553c3f2`](http://github.com/eggjs/egg/commit/8553c3f23e423e9f60144b11a484b703fe7c9229)] - chore: remove auto release (fengmk2 <>) - * [[`b4f01a1c`](http://github.com/eggjs/egg/commit/b4f01a1c6bf006c943c85fce334b81d61f55b7d0)] - chore: fix release branches name (fengmk2 <>) - * [[`a8073b04`](http://github.com/eggjs/egg/commit/a8073b04fc3821bb23326c6c8b4fd0ccaeb5c200)] - chore: add release config (fengmk2 <>) - * [[`8ce2ff90`](http://github.com/eggjs/egg/commit/8ce2ff90bfbb9e4580a23ea49a15fdb1c185fbb5)] - chore: add npm publish tag (fengmk2 <>) - * [[`44950ed8`](http://github.com/eggjs/egg/commit/44950ed82a3ce4d5d4b9028aee98d6650298a552)] - chore: start 3.x LTS (fengmk2 <>) + +- [[`8553c3f2`](http://github.com/eggjs/egg/commit/8553c3f23e423e9f60144b11a484b703fe7c9229)] - chore: remove auto release (fengmk2 <>) +- [[`b4f01a1c`](http://github.com/eggjs/egg/commit/b4f01a1c6bf006c943c85fce334b81d61f55b7d0)] - chore: fix release branches name (fengmk2 <>) +- [[`a8073b04`](http://github.com/eggjs/egg/commit/a8073b04fc3821bb23326c6c8b4fd0ccaeb5c200)] - chore: add release config (fengmk2 <>) +- [[`8ce2ff90`](http://github.com/eggjs/egg/commit/8ce2ff90bfbb9e4580a23ea49a15fdb1c185fbb5)] - chore: add npm publish tag (fengmk2 <>) +- [[`44950ed8`](http://github.com/eggjs/egg/commit/44950ed82a3ce4d5d4b9028aee98d6650298a552)] - chore: start 3.x LTS (fengmk2 <>) diff --git a/agent.js b/agent.js index 17fbdc32eb..068dfb0f45 100644 --- a/agent.js +++ b/agent.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -const BaseHookClass = require('./lib/core/base_hook_class'); +const BaseHookClass = require("./lib/core/base_hook_class"); class EggAgentHook extends BaseHookClass { configDidLoad() { diff --git a/app/extend/context.js b/app/extend/context.js index 83bef2499b..1b40167261 100644 --- a/app/extend/context.js +++ b/app/extend/context.js @@ -1,20 +1,19 @@ -'use strict'; +"use strict"; -const { performance } = require('node:perf_hooks'); -const delegate = require('delegates'); -const { assign } = require('utility'); -const eggUtils = require('egg-core').utils; +const { performance } = require("node:perf_hooks"); +const delegate = require("delegates"); +const { assign } = require("utility"); +const eggUtils = require("egg-core").utils; -const HELPER = Symbol('Context#helper'); -const LOCALS = Symbol('Context#locals'); -const LOCALS_LIST = Symbol('Context#localsList'); -const COOKIES = Symbol('Context#cookies'); -const CONTEXT_LOGGERS = Symbol('Context#logger'); -const CONTEXT_HTTPCLIENT = Symbol('Context#httpclient'); -const CONTEXT_ROUTER = Symbol('Context#router'); - -const proto = module.exports = { +const HELPER = Symbol("Context#helper"); +const LOCALS = Symbol("Context#locals"); +const LOCALS_LIST = Symbol("Context#localsList"); +const COOKIES = Symbol("Context#cookies"); +const CONTEXT_LOGGERS = Symbol("Context#logger"); +const CONTEXT_HTTPCLIENT = Symbol("Context#httpclient"); +const CONTEXT_ROUTER = Symbol("Context#router"); +const proto = (module.exports = { /** * Get the current visitor's cookies. */ @@ -127,7 +126,7 @@ const proto = module.exports = { * ``` */ get logger() { - return this.getLogger('logger'); + return this.getLogger("logger"); }, /** @@ -138,7 +137,7 @@ const proto = module.exports = { * @since 1.0.0 */ get coreLogger() { - return this.getLogger('coreLogger'); + return this.getLogger("coreLogger"); }, /** @@ -216,7 +215,7 @@ const proto = module.exports = { /* istanbul ignore next */ const taskName = scope._name || scope.name || eggUtils.getCalleeFromStack(true); scope._name = taskName; - this._runInBackground(scope); + void this._runInBackground(scope); }, // let plugins or frameworks to reuse _runInBackground in some cases. @@ -227,59 +226,67 @@ const proto = module.exports = { /* istanbul ignore next */ const taskName = scope._name || scope.name || eggUtils.getCalleeFromStack(true); // use setImmediate to ensure all sync logic will run async - return new Promise(resolve => setImmediate(resolve)) - // use app.toAsyncFunction to support both generator function and async function - .then(() => ctx.app.toAsyncFunction(scope)(ctx)) - .then(() => { - ctx.coreLogger.info('[egg:background] task:%s success (%dms)', - taskName, Math.floor((performance.now() - start) * 1000) / 1000); - }) - .catch(err => { - // background task process log - ctx.coreLogger.info('[egg:background] task:%s fail (%dms)', - taskName, Math.floor((performance.now() - start) * 1000) / 1000); + return ( + new Promise((resolve) => setImmediate(resolve)) + // use app.toAsyncFunction to support both generator function and async function + .then(() => ctx.app.toAsyncFunction(scope)(ctx)) + .then(() => { + ctx.coreLogger.info( + "[egg:background] task:%s success (%dms)", + taskName, + Math.floor((performance.now() - start) * 1000) / 1000, + ); + }) + .catch((err) => { + // background task process log + ctx.coreLogger.info( + "[egg:background] task:%s fail (%dms)", + taskName, + Math.floor((performance.now() - start) * 1000) / 1000, + ); - // emit error when promise catch, and set err.runInBackground flag - err.runInBackground = true; - ctx.app.emit('error', err, ctx); - }); + // emit error when promise catch, and set err.runInBackground flag + err.runInBackground = true; + ctx.app.emit("error", err, ctx); + }) + ); }, -}; +}); /** * Context delegation. */ -delegate(proto, 'request') +delegate(proto, "request") /** * @member {Boolean} Context#acceptJSON * @see Request#acceptJSON * @since 1.0.0 */ - .getter('acceptJSON') + .getter("acceptJSON") /** * @member {Array} Context#queries * @see Request#queries * @since 1.0.0 */ - .getter('queries') + .getter("queries") /** * @member {Boolean} Context#accept * @see Request#accept * @since 1.0.0 */ - .getter('accept') + .getter("accept") /** * @member {string} Context#ip * @see Request#ip * @since 1.0.0 */ - .access('ip'); + .access("ip"); -delegate(proto, 'response') +delegate(proto, "response") /** * @member {Number} Context#realStatus * @see Response#realStatus * @since 1.0.0 */ - .access('realStatus'); + .access("realStatus"); diff --git a/app/extend/helper.js b/app/extend/helper.js index 5b86eaef89..7f25d2ce97 100644 --- a/app/extend/helper.js +++ b/app/extend/helper.js @@ -1,10 +1,8 @@ -'use strict'; - -const url = require('node:url'); +"use strict"; +const url = require("node:url"); module.exports = { - /** * Generate URL path(without host) for route. Takes the route name and a map of named params. * @function Helper#pathFor @@ -37,7 +35,11 @@ module.exports = { * @return {String} full url(with host) */ urlFor(name, params) { - return this.ctx.protocol + '://' + this.ctx.host + url.resolve('/', this.app.router.url(name, params)); + return ( + this.ctx.protocol + + "://" + + this.ctx.host + + url.resolve("/", this.app.router.url(name, params)) + ); }, - }; diff --git a/app/extend/request.js b/app/extend/request.js index c496351beb..5239d658d6 100644 --- a/app/extend/request.js +++ b/app/extend/request.js @@ -1,15 +1,15 @@ -'use strict'; +"use strict"; -const querystring = require('node:querystring'); -const accepts = require('accepts'); +const querystring = require("node:querystring"); +const accepts = require("accepts"); -const _querycache = Symbol('_querycache'); -const _queriesCache = Symbol('_queriesCache'); -const PROTOCOL = Symbol('PROTOCOL'); -const HOST = Symbol('HOST'); -const ACCEPTS = Symbol('ACCEPTS'); -const IPS = Symbol('IPS'); -const RE_ARRAY_KEY = /[^\[\]]+\[\]$/; +const _querycache = Symbol("_querycache"); +const _queriesCache = Symbol("_queriesCache"); +const PROTOCOL = Symbol("PROTOCOL"); +const HOST = Symbol("HOST"); +const ACCEPTS = Symbol("ACCEPTS"); +const IPS = Symbol("IPS"); +const RE_ARRAY_KEY = /[^[\]]+\[\]$/; module.exports = { /** @@ -36,7 +36,7 @@ module.exports = { if (this.app.config.proxy) { host = getFromHeaders(this, this.app.config.hostHeaders); } - host = host || this.get('host') || ''; + host = host || this.get("host") || ""; this[HOST] = host.split(/\s*,\s*/)[0]; return this[HOST]; }, @@ -53,7 +53,7 @@ module.exports = { if (this[PROTOCOL]) return this[PROTOCOL]; // detect encrypted socket if (this.socket && this.socket.encrypted) { - this[PROTOCOL] = 'https'; + this[PROTOCOL] = "https"; return this[PROTOCOL]; } // get from headers specified in `app.config.protocolHeaders` @@ -65,7 +65,7 @@ module.exports = { } } // use protocol specified in `app.conig.protocol` - this[PROTOCOL] = this.app.config.protocol || 'http'; + this[PROTOCOL] = this.app.config.protocol || "http"; return this[PROTOCOL]; }, @@ -89,12 +89,14 @@ module.exports = { return this[IPS]; } - const val = getFromHeaders(this, this.app.config.ipHeaders) || ''; + const val = getFromHeaders(this, this.app.config.ipHeaders) || ""; this[IPS] = val ? val.split(/\s*,\s*/) : []; let maxIpsCount = this.app.config.maxIpsCount; // Compatible with maxProxyCount logic (previous logic is wrong, only for compatibility with legacy logic) - if (!maxIpsCount && this.app.config.maxProxyCount) maxIpsCount = this.app.config.maxProxyCount + 1; + if (!maxIpsCount && this.app.config.maxProxyCount) { + maxIpsCount = this.app.config.maxProxyCount + 1; + } if (maxIpsCount > 0) { // if maxIpsCount present, only keep `maxIpsCount` ips @@ -122,7 +124,7 @@ module.exports = { const ip = this.ips[0] || this.socket.remoteAddress; // will be '::ffff:x.x.x.x', should convert to standard IPv4 format // https://zh.wikipedia.org/wiki/IPv6 - this._ip = ip && ip.indexOf('::ffff:') > -1 ? ip.substring(7) : ip; + this._ip = ip && ip.indexOf("::ffff:") > -1 ? ip.substring(7) : ip; return this._ip; }, @@ -151,16 +153,16 @@ module.exports = { * @since 1.0.0 */ get acceptJSON() { - if (this.path.endsWith('.json')) return true; - if (this.response.type && this.response.type.indexOf('json') >= 0) return true; - if (this.accepts('html', 'text', 'json') === 'json') return true; + if (this.path.endsWith(".json")) return true; + if (this.response.type && this.response.type.indexOf("json") >= 0) return true; + if (this.accepts("html", "text", "json") === "json") return true; return false; }, // How to read query safely // https://github.com/koajs/qs/issues/5 _customQuery(cacheName, filter) { - const str = this.querystring || ''; + const str = this.querystring || ""; let c = this[cacheName]; if (!c) { c = this[cacheName] = {}; @@ -256,7 +258,6 @@ module.exports = { }, }; - function firstValue(value) { if (Array.isArray(value)) { value = value[0]; @@ -266,17 +267,17 @@ function firstValue(value) { function arrayValue(value) { if (!Array.isArray(value)) { - value = [ value ]; + value = [value]; } return value; } function getFromHeaders(ctx, names) { - if (!names) return ''; + if (!names) return ""; names = names.split(/\s*,\s*/); for (const name of names) { const value = ctx.get(name); if (value) return value; } - return ''; + return ""; } diff --git a/app/extend/response.js b/app/extend/response.js index 643d53f610..dc4f9704dd 100644 --- a/app/extend/response.js +++ b/app/extend/response.js @@ -1,12 +1,11 @@ -'use strict'; +"use strict"; -const getType = require('cache-content-type'); -const isJSON = require('koa-is-json'); +const getType = require("cache-content-type"); +const isJSON = require("koa-is-json"); -const REAL_STATUS = Symbol('Context#realStatus'); +const REAL_STATUS = Symbol("Context#realStatus"); module.exports = { - /** * Get or set the length of content. * @@ -19,17 +18,17 @@ module.exports = { set length(len) { // copy from koa // change header name to lower case - this.set('content-length', len); + this.set("content-length", len); }, get length() { // copy from koa - const len = this.header['content-length']; + const len = this.header["content-length"]; const body = this.body; if (len == null) { if (!body) return; - if (typeof body === 'string') return Buffer.byteLength(body); + if (typeof body === "string") return Buffer.byteLength(body); if (Buffer.isBuffer(body)) return body.length; if (isJSON(body)) return Buffer.byteLength(JSON.stringify(body)); return; @@ -55,17 +54,17 @@ module.exports = { // - change header name to lower case type = getType(type); if (type) { - this.set('content-type', type); + this.set("content-type", type); } else { - this.remove('content-type'); + this.remove("content-type"); } }, get type() { // copy from koa - const type = this.get('content-type'); - if (!type) return ''; - return type.split(';')[0]; + const type = this.get("content-type"); + if (!type) return ""; + return type.split(";")[0]; }, /** diff --git a/app/middleware/body_parser.js b/app/middleware/body_parser.js index 70f473a33d..1d3cde2782 100644 --- a/app/middleware/body_parser.js +++ b/app/middleware/body_parser.js @@ -1,3 +1,3 @@ -'use strict'; +"use strict"; -module.exports = require('koa-bodyparser'); +module.exports = require("koa-bodyparser"); diff --git a/app/middleware/meta.js b/app/middleware/meta.js index 5ef169092d..bbc5ccdc3e 100644 --- a/app/middleware/meta.js +++ b/app/middleware/meta.js @@ -2,19 +2,26 @@ * meta middleware, should be the first middleware */ -const { performance } = require('node:perf_hooks'); +const { performance } = require("node:perf_hooks"); -module.exports = options => { +module.exports = (options) => { return async function meta(ctx, next) { if (options.logging) { - ctx.coreLogger.info('[meta] request started, host: %s, user-agent: %s', ctx.host, ctx.header['user-agent']); + ctx.coreLogger.info( + "[meta] request started, host: %s, user-agent: %s", + ctx.host, + ctx.header["user-agent"], + ); } await next(); // total response time header if (ctx.performanceStarttime) { - ctx.set('x-readtime', Math.floor((performance.now() - ctx.performanceStarttime) * 1000) / 1000); + ctx.set( + "x-readtime", + Math.floor((performance.now() - ctx.performanceStarttime) * 1000) / 1000, + ); } else { - ctx.set('x-readtime', Date.now() - ctx.starttime); + ctx.set("x-readtime", Date.now() - ctx.starttime); } }; }; diff --git a/app/middleware/notfound.js b/app/middleware/notfound.js index 4ec4288f8e..bf7506fdc8 100644 --- a/app/middleware/notfound.js +++ b/app/middleware/notfound.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -module.exports = options => { +module.exports = (options) => { return async function notfound(ctx, next) { await next(); @@ -13,12 +13,12 @@ module.exports = options => { if (ctx.acceptJSON) { ctx.body = { - message: 'Not Found', + message: "Not Found", }; return; } - const notFoundHtml = '

404 Not Found

'; + const notFoundHtml = "

404 Not Found

"; // notfound handler is unimplemented if (options.pageUrl && ctx.path === options.pageUrl) { diff --git a/app/middleware/override_method.js b/app/middleware/override_method.js index bf5f7ef0f4..daa0504a7d 100644 --- a/app/middleware/override_method.js +++ b/app/middleware/override_method.js @@ -1,3 +1,3 @@ -'use strict'; +"use strict"; -module.exports = require('koa-override'); +module.exports = require("koa-override"); diff --git a/app/middleware/site_file.js b/app/middleware/site_file.js index cb403d9a97..9d93afe00b 100644 --- a/app/middleware/site_file.js +++ b/app/middleware/site_file.js @@ -1,26 +1,26 @@ -'use strict'; +"use strict"; -const path = require('node:path'); +const path = require("node:path"); -module.exports = options => { +module.exports = (options) => { return async function siteFile(ctx, next) { - if (ctx.method !== 'HEAD' && ctx.method !== 'GET') return next(); + if (ctx.method !== "HEAD" && ctx.method !== "GET") return next(); /* istanbul ignore if */ - if (ctx.path[0] !== '/') return next(); + if (ctx.path[0] !== "/") return next(); let content = options[ctx.path]; if (!content) return next(); // '/favicon.ico': 'https://eggjs.org/favicon.ico' or '/favicon.ico': async (ctx) => 'https://eggjs.org/favicon.ico' // content is function - if (typeof content === 'function') content = await content(ctx); + if (typeof content === "function") content = await content(ctx); // content is url - if (typeof content === 'string') return ctx.redirect(content); + if (typeof content === "string") return ctx.redirect(content); // '/robots.txt': Buffer { - +module.exports = (appInfo) => { const config = { - /** * The environment of egg * @member {String} Config#env @@ -36,7 +35,7 @@ module.exports = appInfo => { * @default * @since 1.0.0 */ - keys: '', + keys: "", /** * default cookie options @@ -86,7 +85,7 @@ module.exports = appInfo => { * @default * @since 1.0.0 */ - protocolHeaders: 'x-forwarded-proto', + protocolHeaders: "x-forwarded-proto", /** * Detect request' ip from specified headers, not case-sensitive. @@ -95,7 +94,7 @@ module.exports = appInfo => { * @default * @since 1.0.0 */ - ipHeaders: 'x-forwarded-for', + ipHeaders: "x-forwarded-for", /** * Detect request' host from specified headers, not case-sensitive. @@ -104,7 +103,7 @@ module.exports = appInfo => { * @default * @since 1.0.0 */ - hostHeaders: '', + hostHeaders: "", /** * package.json @@ -136,7 +135,7 @@ module.exports = appInfo => { * @default * @since 1.0.0 */ - rundir: path.join(appInfo.baseDir, 'run'), + rundir: path.join(appInfo.baseDir, "run"), /** * dump config @@ -148,7 +147,14 @@ module.exports = appInfo => { */ dump: { ignore: new Set([ - 'pass', 'pwd', 'passd', 'passwd', 'password', 'keys', 'masterKey', 'accessKey', + "pass", + "pwd", + "passd", + "passwd", + "password", + "keys", + "masterKey", + "accessKey", // ignore any key contains "secret" keyword /secret/i, ]), @@ -167,11 +173,11 @@ module.exports = appInfo => { * @type {Object} */ confusedConfigurations: { - bodyparser: 'bodyParser', - notFound: 'notfound', - sitefile: 'siteFile', - middlewares: 'middleware', - httpClient: 'httpclient', + bodyparser: "bodyParser", + notFound: "notfound", + sitefile: "siteFile", + middlewares: "middleware", + httpClient: "httpclient", }, }; @@ -185,7 +191,7 @@ module.exports = appInfo => { * @property {String} pageUrl - the 404 page url */ config.notfound = { - pageUrl: '', + pageUrl: "", }; /** @@ -202,9 +208,9 @@ module.exports = appInfo => { * }; */ config.siteFile = { - '/favicon.ico': fs.readFileSync(path.join(__dirname, 'favicon.png')), + "/favicon.ico": fs.readFileSync(path.join(__dirname, "favicon.png")), // default cache in 30 days - cacheControl: 'public, max-age=2592000', + cacheControl: "public, max-age=2592000", }; /** @@ -225,10 +231,10 @@ module.exports = appInfo => { */ config.bodyParser = { enable: true, - encoding: 'utf8', - formLimit: '1mb', - jsonLimit: '1mb', - textLimit: '1mb', + encoding: "utf8", + formLimit: "1mb", + jsonLimit: "1mb", + textLimit: "1mb", strict: true, // @see https://github.com/hapijs/qs/blob/master/lib/parse.js#L8 for more options queryString: { @@ -237,7 +243,7 @@ module.exports = appInfo => { parameterLimit: 1000, }, onerror(err, ctx) { - err.message += ', check bodyParser config'; + err.message += ", check bodyParser config"; if (ctx.status === 404) { // set default status to 400, meaning client bad request ctx.status = 400; @@ -268,18 +274,18 @@ module.exports = appInfo => { * @property {Boolean} enableFastContextLogger - using the app logger instead of EggContextLogger, defaults to false */ config.logger = { - dir: path.join(appInfo.root, 'logs', appInfo.name), - encoding: 'utf8', + dir: path.join(appInfo.root, "logs", appInfo.name), + encoding: "utf8", env: appInfo.env, - level: 'INFO', - consoleLevel: 'INFO', - disableConsoleAfterReady: appInfo.env !== 'local' && appInfo.env !== 'unittest', + level: "INFO", + consoleLevel: "INFO", + disableConsoleAfterReady: appInfo.env !== "local" && appInfo.env !== "unittest", outputJSON: false, buffer: true, appLogName: `${appInfo.name}-web.log`, - coreLogName: 'egg-web.log', - agentLogName: 'egg-agent.log', - errorLogName: 'common-error.log', + coreLogName: "egg-web.log", + agentLogName: "egg-agent.log", + errorLogName: "common-error.log", coreLogger: {}, allowDebugAtProd: false, enablePerformanceTimer: false, @@ -346,13 +352,7 @@ module.exports = appInfo => { * core enable middlewares * @member {Array} Config#middleware */ - config.coreMiddleware = [ - 'meta', - 'siteFile', - 'notfound', - 'bodyParser', - 'overrideMethod', - ]; + config.coreMiddleware = ["meta", "siteFile", "notfound", "bodyParser", "overrideMethod"]; /** * emit `startTimeout` if worker don't ready after `workerStartTimeout` ms @@ -380,9 +380,9 @@ module.exports = appInfo => { */ config.cluster = { listen: { - path: '', + path: "", port: 7001, - hostname: '', + hostname: "", }, }; @@ -403,9 +403,9 @@ module.exports = appInfo => { * The response to be returned should include properties below: * * @member {Function} Config#onClientError - * @property [body] {String|Buffer} - the response body - * @property [status] {Number} - the response status code - * @property [headers] {Object} - the response header key-value pairs + * @property {String|Buffer} [body] - the response body + * @property {Number} [status] - the response status code + * @property {Object} [headers] - the response header key-value pairs * * @example * exports.onClientError = async (err, socket, app) => { diff --git a/config/config.local.js b/config/config.local.js index 2924388133..b1e7a16121 100644 --- a/config/config.local.js +++ b/config/config.local.js @@ -1,7 +1,7 @@ -'use strict'; +"use strict"; exports.logger = { coreLogger: { - consoleLevel: 'WARN', + consoleLevel: "WARN", }, }; diff --git a/config/config.unittest.js b/config/config.unittest.js index 7c5c5e4c6d..e576f0d814 100644 --- a/config/config.unittest.js +++ b/config/config.unittest.js @@ -1,8 +1,8 @@ -'use strict'; +"use strict"; module.exports = { logger: { - consoleLevel: 'WARN', + consoleLevel: "WARN", buffer: false, }, }; diff --git a/config/plugin.js b/config/plugin.js index da864347eb..bc9125a503 100644 --- a/config/plugin.js +++ b/config/plugin.js @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; module.exports = { // enable plugins @@ -10,7 +10,7 @@ module.exports = { */ onerror: { enable: true, - package: 'egg-onerror', + package: "egg-onerror", }, /** @@ -21,7 +21,7 @@ module.exports = { */ session: { enable: true, - package: 'egg-session', + package: "egg-session", }, /** @@ -32,7 +32,7 @@ module.exports = { */ i18n: { enable: true, - package: 'egg-i18n', + package: "egg-i18n", }, /** @@ -43,7 +43,7 @@ module.exports = { */ watcher: { enable: true, - package: 'egg-watcher', + package: "egg-watcher", }, /** @@ -54,7 +54,7 @@ module.exports = { */ multipart: { enable: true, - package: 'egg-multipart', + package: "egg-multipart", }, /** @@ -65,7 +65,7 @@ module.exports = { */ security: { enable: true, - package: 'egg-security', + package: "egg-security", }, /** @@ -76,7 +76,7 @@ module.exports = { */ development: { enable: true, - package: 'egg-development', + package: "egg-development", }, /** @@ -87,7 +87,7 @@ module.exports = { */ logrotator: { enable: true, - package: 'egg-logrotator', + package: "egg-logrotator", }, /** @@ -98,7 +98,7 @@ module.exports = { */ schedule: { enable: true, - package: 'egg-schedule', + package: "egg-schedule", }, /** @@ -109,7 +109,7 @@ module.exports = { */ static: { enable: true, - package: 'egg-static', + package: "egg-static", }, /** @@ -120,7 +120,7 @@ module.exports = { */ jsonp: { enable: true, - package: 'egg-jsonp', + package: "egg-jsonp", }, /** @@ -131,6 +131,6 @@ module.exports = { */ view: { enable: true, - package: 'egg-view', + package: "egg-view", }, }; diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 2ef684b895..0000000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,25 +0,0 @@ -import { fixupConfigRules } from '@eslint/compat'; -import { FlatCompat } from '@eslint/eslintrc'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); - -export default [ - { - ignores: [ - 'test/fixtures/**', - 'examples/**/app/public/**', - 'logs/**', - 'run/**', - 'docs/node_modules/**', - 'site/**', - ], - }, - ...fixupConfigRules(compat.extends('eslint-config-egg')), -]; diff --git a/index.d.ts b/index.d.ts index 28ed159299..85c36fbd0b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,11 +1,11 @@ -import accepts = require('accepts'); -import { AsyncLocalStorage } from 'async_hooks'; -import { EventEmitter } from 'events' -import { Readable } from 'stream'; -import { Socket, LookupFunction } from 'net'; -import { IncomingMessage, ServerResponse } from 'http'; -import KoaApplication = require('koa'); -import KoaRouter = require('koa-router'); +import accepts = require("accepts"); +import { AsyncLocalStorage } from "node:async_hooks"; +import { EventEmitter } from "node:events"; +import { Readable } from "node:stream"; +import { Socket, LookupFunction } from "node:net"; +import { IncomingMessage, ServerResponse } from "node:http"; +import KoaApplication = require("koa"); +import KoaRouter = require("koa-router"); import { EggLogger as Logger, EggLoggers, @@ -13,20 +13,17 @@ import { EggLoggersOptions, EggLoggerOptions, EggContextLogger, -} from 'egg-logger'; +} from "egg-logger"; import { RequestOptions2 as RequestOptionsOld, HttpClientResponse as HttpClientResponseOld, -} from 'urllib'; +} from "urllib"; import { RequestURL, RequestOptions, HttpClientResponse as HttpClientResponseNext, -} from 'urllib-next'; -import { - FetchFactory, - fetch, -} from 'urllib4'; +} from "urllib-next"; +import { FetchFactory, fetch } from "urllib4"; import { EggCoreBase, FileLoaderOption, @@ -34,22 +31,22 @@ import { EggCoreOptions as CoreOptions, EggLoaderOptions as CoreLoaderOptions, BaseContextClass as CoreBaseContextClass, -} from 'egg-core'; -import EggCookies = require('egg-cookies'); -import 'egg-onerror'; -import 'egg-session'; -import 'egg-i18n'; -import 'egg-watcher'; -import 'egg-multipart'; -import 'egg-security'; -import 'egg-development'; -import 'egg-logrotator'; -import 'egg-schedule'; -import 'egg-static'; -import 'egg-jsonp'; -import 'egg-view'; - -declare module 'egg' { +} from "egg-core"; +import EggCookies = require("egg-cookies"); +import "egg-onerror"; +import "egg-session"; +import "egg-i18n"; +import "egg-watcher"; +import "egg-multipart"; +import "egg-security"; +import "egg-development"; +import "egg-logrotator"; +import "egg-schedule"; +import "egg-static"; +import "egg-jsonp"; +import "egg-view"; + +declare module "egg" { export type EggLogger = Logger; // plain object type PlainObject = { [key: string]: T }; @@ -69,24 +66,36 @@ declare module 'egg' { export type HttpClientResponse = HttpClientResponseNext; // Compatible with both urllib@2 and urllib@3 RequestOptions to request export interface EggHttpClient extends EventEmitter { - request(url: HttpClientRequestURL): Promise | HttpClientResponse>; - request(url: HttpClientRequestURL, options: RequestOptionsOld | HttpClientRequestOptions): - Promise | HttpClientResponse>; - curl(url: HttpClientRequestURL): Promise | HttpClientResponse>; - curl(url: HttpClientRequestURL, options: RequestOptionsOld | HttpClientRequestOptions): - Promise | HttpClientResponse>; - safeCurl(url: HttpClientRequestURL): Promise | HttpClientResponse>; - safeCurl(url: HttpClientRequestURL, options: RequestOptionsOld | HttpClientRequestOptions): - Promise | HttpClientResponse>; + request( + url: HttpClientRequestURL, + ): Promise | HttpClientResponse>; + request( + url: HttpClientRequestURL, + options: RequestOptionsOld | HttpClientRequestOptions, + ): Promise | HttpClientResponse>; + curl( + url: HttpClientRequestURL, + ): Promise | HttpClientResponse>; + curl( + url: HttpClientRequestURL, + options: RequestOptionsOld | HttpClientRequestOptions, + ): Promise | HttpClientResponse>; + safeCurl( + url: HttpClientRequestURL, + ): Promise | HttpClientResponse>; + safeCurl( + url: HttpClientRequestURL, + options: RequestOptionsOld | HttpClientRequestOptions, + ): Promise | HttpClientResponse>; } interface EggHttpConstructor { - new(app: Application): EggHttpClient; + new (app: Application): EggHttpClient; } - export interface EggContextHttpClient extends EggHttpClient { } + export interface EggContextHttpClient extends EggHttpClient {} interface EggContextHttpClientConstructor { - new(ctx: Context): EggContextHttpClient; + new (ctx: Context): EggContextHttpClient; } /** @@ -94,7 +103,13 @@ declare module 'egg' { * it's instantiated in context level, * {@link Helper}, {@link Service} is extending it. */ - export class BaseContextClass extends CoreBaseContextClass { // tslint:disable-line + export class BaseContextClass extends CoreBaseContextClass< + Context, + Application, + EggAppConfig, + IService + > { + // tslint:disable-line /** * logger */ @@ -129,7 +144,8 @@ declare module 'egg' { export type RequestArrayBody = any[]; export type RequestObjectBody = PlainObject; - export interface Request extends KoaApplication.Request { // tslint:disable-line + export interface Request extends KoaApplication.Request { + // tslint:disable-line /** * detect if response should be json * 1. url path ends with `.json` @@ -211,7 +227,8 @@ declare module 'egg' { body: any; } - export interface Response extends KoaApplication.Response { // tslint:disable-line + export interface Response extends KoaApplication.Response { + // tslint:disable-line /** * read response real status code. * @@ -227,7 +244,6 @@ declare module 'egg' { export type LoggerLevel = EggLoggerLevel; - /** * egg app info * @example @@ -255,7 +271,7 @@ declare module 'egg' { type IgnoreOrMatch = IgnoreItem | IgnoreItem[]; /** logger config of egg */ - export interface EggLoggerConfig extends RemoveSpecProp { + export interface EggLoggerConfig extends RemoveSpecProp { /** custom config of coreLogger */ coreLogger?: Partial; /** allow debug log at prod, defaults to `false` */ @@ -269,11 +285,14 @@ declare module 'egg' { } /** Custom Loader Configuration */ - export interface CustomLoaderConfig extends RemoveSpecProp { + export interface CustomLoaderConfig extends RemoveSpecProp< + FileLoaderOption, + "inject" | "target" + > { /** * an object you wanner load to, value can only be 'ctx' or 'app'. default to app */ - inject?: 'ctx' | 'app'; + inject?: "ctx" | "app"; /** * whether need to load files in plugins or framework, default to false */ @@ -295,9 +314,7 @@ declare module 'egg' { maxFreeSockets?: number; } - type Dispatcher = FetchFactory['getDispatcher'] extends () => infer R - ? R - : never; + type Dispatcher = FetchFactory["getDispatcher"] extends () => infer R ? R : never; /** HttpClient config */ export interface HttpClientConfig extends HttpClientBaseConfig { @@ -323,7 +340,7 @@ declare module 'egg' { allowH2?: boolean; /** Custom lookup function for DNS resolution */ lookup?: LookupFunction; - interceptors?: Parameters; + interceptors?: Parameters; } export interface EggAppConfig { workerStartTimeout: number; @@ -370,7 +387,7 @@ declare module 'egg' { text: string[]; }; /** Default is `'error'`, it will return `400` response when `Prototype-Poisoning` happen. */ - onProtoPoisoning: 'error' | 'remove' | 'ignore'; + onProtoPoisoning: "error" | "remove" | "ignore"; }; /** @@ -533,11 +550,11 @@ declare module 'egg' { }; xframe: { enable: boolean; - value: 'SAMEORIGIN' | 'DENY' | string; + value: "SAMEORIGIN" | "DENY" | string; }; hsts: any; methodnoallow: { enable: boolean }; - noopen: { enable: boolean; } + noopen: { enable: boolean }; xssProtection: any; csp: any; }; @@ -546,7 +563,11 @@ declare module 'egg' { watcher: PlainObject; - onClientError(err: Error, socket: Socket, app: EggApplication): ClientErrorResponse | Promise; + onClientError( + err: Error, + socket: Socket, + app: EggApplication, + ): ClientErrorResponse | Promise; /** * server timeout in milliseconds, default to 0 (no timeout). @@ -566,7 +587,7 @@ declare module 'egg' { headers: { [key: string]: string }; } - export interface Router extends Omit, 'url'> { + export interface Router extends Omit, "url"> { /** * restful router api */ @@ -593,7 +614,10 @@ declare module 'egg' { methods: string[]; } - export interface EggApplication extends Omit, 'ctxStorage' | 'currentContext'> { + export interface EggApplication extends Omit< + EggCoreBase, + "ctxStorage" | "currentContext" + > { /** * HttpClient instance */ @@ -603,7 +627,7 @@ declare module 'egg' { * node fetch */ FetchFactory: FetchFactory; - fetch: typeof fetch, + fetch: typeof fetch; /** * Logger for Application, wrapping app.coreLogger with context infomation @@ -650,7 +674,7 @@ declare module 'egg' { * Keep the same api with httpclient.request(url, args). * See https://github.com/node-modules/urllib#api-doc for more details. */ - curl: EggHttpClient['request']; + curl: EggHttpClient["request"]; /** * Get logger by name, it's equal to app.loggers['name'], but you can extend it with your own logical @@ -761,20 +785,21 @@ declare module 'egg' { /** * Get current execute ctx async local storage - * @returns {AsyncLocalStorage} localStorage - store current execute Context + * @return {AsyncLocalStorage} localStorage - store current execute Context */ get ctxStorage(): AsyncLocalStorage; /** * Get current execute ctx, maybe undefined - * @returns {Context} ctx - current execute Context + * @return {Context} ctx - current execute Context */ get currentContext(): Context; } - export interface IApplicationLocals extends PlainObject { } + export interface IApplicationLocals extends PlainObject {} - export interface FileStream extends Readable { // tslint:disable-line + export interface FileStream extends Readable { + // tslint:disable-line fields: any; filename: string; @@ -809,23 +834,23 @@ declare module 'egg' { file: any, filename: string, encoding: string, - mimetype: string + mimetype: string, ): void | Error; } /** - * KoaApplication's Context will carry the default 'cookie' property in - * the egg's Context interface, which is wrong here because we have our own - * special properties (e.g: encrypted). So we must remove this property and - * create our own with the same name. - * @see https://github.com/eggjs/egg/pull/2958 - * - * However, the latest version of Koa has "[key: string]: any" on the - * context, and there'll be a type error for "keyof koa.Context". - * So we have to directly inherit from "KoaApplication.BaseContext" and - * rewrite all the properties to be compatible with types in Koa. - * @see https://github.com/eggjs/egg/pull/3329 - */ + * KoaApplication's Context will carry the default 'cookie' property in + * the egg's Context interface, which is wrong here because we have our own + * special properties (e.g: encrypted). So we must remove this property and + * create our own with the same name. + * @see https://github.com/eggjs/egg/pull/2958 + * + * However, the latest version of Koa has "[key: string]: any" on the + * context, and there'll be a type error for "keyof koa.Context". + * So we have to directly inherit from "KoaApplication.BaseContext" and + * rewrite all the properties to be compatible with types in Koa. + * @see https://github.com/eggjs/egg/pull/3329 + */ export interface Context extends KoaApplication.BaseContext { [key: string]: any; body: ResponseBodyT; @@ -1026,7 +1051,7 @@ declare module 'egg' { * Keep the same api with httpclient.request(url, args). * See https://github.com/node-modules/urllib#api-doc for more details. */ - curl: EggHttpClient['request']; + curl: EggHttpClient["request"]; __(key: string, ...values: string[]): string; gettext(key: string, ...values: string[]): string; @@ -1054,13 +1079,13 @@ declare module 'egg' { httpclient: EggContextHttpClient; } - export interface IContextLocals extends PlainObject { } + export interface IContextLocals extends PlainObject {} - export class Controller extends BaseContextClass { } + export class Controller extends BaseContextClass {} - export class Service extends BaseContextClass { } + export class Service extends BaseContextClass {} - export class Subscription extends BaseContextClass { } + export class Subscription extends BaseContextClass {} /** * The empty interface `IService` is a placeholder, for egg @@ -1081,11 +1106,11 @@ declare module 'egg' { * * Now I can get ctx.service.foo at controller and other service file. */ - export interface IService extends PlainObject { } // tslint:disable-line + export interface IService extends PlainObject {} // tslint:disable-line - export interface IController extends PlainObject { } // tslint:disable-line + export interface IController extends PlainObject {} // tslint:disable-line - export interface IMiddleware extends PlainObject { } // tslint:disable-line + export interface IMiddleware extends PlainObject {} // tslint:disable-line export interface IHelper extends PlainObject, BaseContextClass { /** @@ -1121,7 +1146,7 @@ declare module 'egg' { } // egg env type - export type EggEnvType = 'local' | 'unittest' | 'prod' | string; + export type EggEnvType = "local" | "unittest" | "prod" | string; /** * plugin config item interface @@ -1157,8 +1182,7 @@ declare module 'egg' { /** * Singleton instance in Agent Worker, extend {@link EggApplication} */ - export class Agent extends EggApplication { - } + export class Agent extends EggApplication {} export interface ClusterOptions { /** specify framework that can be absolute path or npm package */ @@ -1191,7 +1215,7 @@ declare module 'egg' { ignoreWarning?: boolean; } - export function start(options?: StartOptions): Promise + export function start(options?: StartOptions): Promise; /** * Powerful Partial, Support adding ? modifier to a mapped property in deep level @@ -1202,9 +1226,7 @@ declare module 'egg' { * type EggConfig = PowerPartial */ export type PowerPartial = { - [U in keyof T]?: T[U] extends object - ? PowerPartial - : T[U] + [U in keyof T]?: T[U] extends object ? PowerPartial : T[U]; }; // send data can be number|string|boolean|object but not Set|Map @@ -1239,8 +1261,8 @@ declare module 'egg' { } // compatible - export interface EggLoaderOptions extends CoreLoaderOptions { } - export interface EggLoader extends CoreLoader { } + export interface EggLoaderOptions extends CoreLoaderOptions {} + export interface EggLoader extends CoreLoader {} /** * App worker process Loader, will load plugins @@ -1303,4 +1325,4 @@ declare module 'egg' { export interface Singleton { get(id: string): T; } -} \ No newline at end of file +} diff --git a/index.js b/index.js index 7e3269eda3..c9e92192da 100644 --- a/index.js +++ b/index.js @@ -6,63 +6,63 @@ * Start egg application with cluster mode * @since 1.0.0 */ -exports.startCluster = require('egg-cluster').startCluster; +exports.startCluster = require("egg-cluster").startCluster; /** * Start egg application with single process mode * @since 1.0.0 */ -exports.start = require('./lib/start'); +exports.start = require("./lib/start"); /** * @member {Application} Egg#Application * @since 1.0.0 */ -exports.Application = require('./lib/application'); +exports.Application = require("./lib/application"); /** * @member {Agent} Egg#Agent * @since 1.0.0 */ -exports.Agent = require('./lib/agent'); +exports.Agent = require("./lib/agent"); /** * @member {AppWorkerLoader} Egg#AppWorkerLoader * @since 1.0.0 */ -exports.AppWorkerLoader = require('./lib/loader').AppWorkerLoader; +exports.AppWorkerLoader = require("./lib/loader").AppWorkerLoader; /** * @member {AgentWorkerLoader} Egg#AgentWorkerLoader * @since 1.0.0 */ -exports.AgentWorkerLoader = require('./lib/loader').AgentWorkerLoader; +exports.AgentWorkerLoader = require("./lib/loader").AgentWorkerLoader; /** * @member {Controller} Egg#Controller * @since 1.1.0 */ -exports.Controller = require('./lib/core/base_context_class'); +exports.Controller = require("./lib/core/base_context_class"); /** * @member {Service} Egg#Service * @since 1.1.0 */ -exports.Service = require('./lib/core/base_context_class'); +exports.Service = require("./lib/core/base_context_class"); /** * @member {Subscription} Egg#Subscription * @since 1.10.0 */ -exports.Subscription = require('./lib/core/base_context_class'); +exports.Subscription = require("./lib/core/base_context_class"); /** * @member {BaseContextClass} Egg#BaseContextClass * @since 1.2.0 */ -exports.BaseContextClass = require('./lib/core/base_context_class'); +exports.BaseContextClass = require("./lib/core/base_context_class"); /** * @member {Boot} Egg#Boot */ -exports.Boot = require('./lib/core/base_hook_class'); +exports.Boot = require("./lib/core/base_hook_class"); diff --git a/index.test-d.ts b/index.test-d.ts index 8f7bcd336e..d90889f394 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1 +1 @@ -import '.'; +import "."; diff --git a/lib/agent.js b/lib/agent.js index 0e3013db8d..1163537279 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -1,12 +1,12 @@ -'use strict'; +"use strict"; -const path = require('node:path'); -const ms = require('ms'); -const EggApplication = require('./egg'); -const AgentWorkerLoader = require('./loader').AgentWorkerLoader; +const path = require("node:path"); +const ms = require("ms"); +const EggApplication = require("./egg"); +const AgentWorkerLoader = require("./loader").AgentWorkerLoader; -const EGG_LOADER = Symbol.for('egg#loader'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const EGG_LOADER = Symbol.for("egg#loader"); +const EGG_PATH = Symbol.for("egg#eggPath"); /** * Singleton instance in Agent Worker, extend {@link EggApplication} @@ -18,7 +18,7 @@ class Agent extends EggApplication { * @param {Object} options - see {@link EggApplication} */ constructor(options = {}) { - options.type = 'agent'; + options.type = "agent"; super(options); this.loader.load(); @@ -26,16 +26,13 @@ class Agent extends EggApplication { // dump config after loaded, ensure all the dynamic modifications will be recorded const dumpStartTime = Date.now(); this.dumpConfig(); - this.coreLogger.info( - '[egg:core] dump config after load, %s', - ms(Date.now() - dumpStartTime) - ); + this.coreLogger.info("[egg:core] dump config after load, %s", ms(Date.now() - dumpStartTime)); // keep agent alive even it doesn't have any io tasks this.agentAliveHandler = setInterval(() => {}, 24 * 60 * 60 * 1000); this._uncaughtExceptionHandler = this._uncaughtExceptionHandler.bind(this); - process.on('uncaughtException', this._uncaughtExceptionHandler); + process.on("uncaughtException", this._uncaughtExceptionHandler); } _uncaughtExceptionHandler(err) { @@ -43,8 +40,8 @@ class Agent extends EggApplication { err = new Error(String(err)); } /* istanbul ignore else */ - if (err.name === 'Error') { - err.name = 'unhandledExceptionError'; + if (err.name === "Error") { + err.name = "unhandledExceptionError"; } this.coreLogger.error(err); } @@ -54,39 +51,29 @@ class Agent extends EggApplication { } get [EGG_PATH]() { - return path.join(__dirname, '..'); + return path.join(__dirname, ".."); } _wrapMessenger() { - for (const methodName of [ - 'broadcast', - 'sendTo', - 'sendToApp', - 'sendToAgent', - 'sendRandom', - ]) { + for (const methodName of ["broadcast", "sendTo", "sendToApp", "sendToAgent", "sendRandom"]) { wrapMethod(methodName, this.messenger, this.coreLogger); } function wrapMethod(methodName, messenger, logger) { const originMethod = messenger[methodName]; - messenger[methodName] = function() { - const stack = new Error().stack.split('\n').slice(1).join('\n'); - logger.warn( - "agent can't call %s before server started\n%s", - methodName, - stack - ); + messenger[methodName] = function () { + const stack = new Error().stack.split("\n").slice(1).join("\n"); + logger.warn("agent can't call %s before server started\n%s", methodName, stack); originMethod.apply(this, arguments); }; - messenger.prependOnceListener('egg-ready', () => { + messenger.prependOnceListener("egg-ready", () => { messenger[methodName] = originMethod; }); } } close() { - process.removeListener('uncaughtException', this._uncaughtExceptionHandler); + process.removeListener("uncaughtException", this._uncaughtExceptionHandler); clearInterval(this.agentAliveHandler); return super.close(); } diff --git a/lib/application.js b/lib/application.js index c13dfa8854..31290fecf3 100644 --- a/lib/application.js +++ b/lib/application.js @@ -1,27 +1,27 @@ -'use strict'; - -const path = require('node:path'); -const fs = require('node:fs'); -const ms = require('ms'); -const is = require('is-type-of'); -const graceful = require('graceful'); -const http = require('node:http'); -const cluster = require('cluster-client'); -const onFinished = require('on-finished'); -const { assign } = require('utility'); -const eggUtils = require('egg-core').utils; -const EggApplication = require('./egg'); -const AppWorkerLoader = require('./loader').AppWorkerLoader; - -const KEYS = Symbol('Application#keys'); -const HELPER = Symbol('Application#Helper'); -const LOCALS = Symbol('Application#locals'); -const BIND_EVENTS = Symbol('Application#bindEvents'); -const WARN_CONFUSED_CONFIG = Symbol('Application#warnConfusedConfig'); -const EGG_LOADER = Symbol.for('egg#loader'); -const EGG_PATH = Symbol.for('egg#eggPath'); -const CLUSTER_CLIENTS = Symbol.for('egg#clusterClients'); -const RESPONSE_RAW = Symbol('Application#responseRaw'); +"use strict"; + +const path = require("node:path"); +const fs = require("node:fs"); +const ms = require("ms"); +const is = require("is-type-of"); +const graceful = require("graceful"); +const http = require("node:http"); +const cluster = require("cluster-client"); +const onFinished = require("on-finished"); +const { assign } = require("utility"); +const eggUtils = require("egg-core").utils; +const EggApplication = require("./egg"); +const AppWorkerLoader = require("./loader").AppWorkerLoader; + +const KEYS = Symbol("Application#keys"); +const HELPER = Symbol("Application#Helper"); +const LOCALS = Symbol("Application#locals"); +const BIND_EVENTS = Symbol("Application#bindEvents"); +const WARN_CONFUSED_CONFIG = Symbol("Application#warnConfusedConfig"); +const EGG_LOADER = Symbol.for("egg#loader"); +const EGG_PATH = Symbol.for("egg#eggPath"); +const CLUSTER_CLIENTS = Symbol.for("egg#clusterClients"); +const RESPONSE_RAW = Symbol("Application#responseRaw"); // client error => 400 Bad Request // Refs: https://nodejs.org/dist/latest-v8.x/docs/api/http.html#http_event_clienterror @@ -41,7 +41,7 @@ const DEFAULT_BAD_REQUEST_RESPONSE = function escapeHeaderValue(value) { // Protect against response splitting. The regex test is there to // minimize the performance impact in the common case. - return /[\r\n]/.test(value) ? value.replace(/[\r\n]+[ \t]*/g, '') : value; + return /[\r\n]/.test(value) ? value.replace(/[\r\n]+[ \t]*/g, "") : value; } // Refs: https://github.com/nodejs/node/blob/b38c81/lib/_http_outgoing.js#L706-L710 @@ -50,13 +50,12 @@ function escapeHeaderValue(value) { * @augments EggApplication */ class Application extends EggApplication { - /** * @class * @param {Object} options - see {@link EggApplication} */ constructor(options = {}) { - options.type = 'application'; + options.type = "application"; super(options); // will auto set after 'server' event emit @@ -73,7 +72,7 @@ class Application extends EggApplication { // dump config after loaded, ensure all the dynamic modifications will be recorded const dumpStartTime = Date.now(); this.dumpConfig(); - this.coreLogger.info('[egg:core] dump config after load, %s', ms(Date.now() - dumpStartTime)); + this.coreLogger.info("[egg:core] dump config after load, %s", ms(Date.now() - dumpStartTime)); this[WARN_CONFUSED_CONFIG](); this[BIND_EVENTS](); @@ -84,7 +83,7 @@ class Application extends EggApplication { } get [EGG_PATH]() { - return path.join(__dirname, '..'); + return path.join(__dirname, ".."); } [RESPONSE_RAW](socket, raw) { @@ -92,17 +91,17 @@ class Application extends EggApplication { if (!socket.writable) return; if (!raw) return socket.end(DEFAULT_BAD_REQUEST_RESPONSE); - const body = (raw.body == null) ? DEFAULT_BAD_REQUEST_HTML : raw.body; + const body = raw.body == null ? DEFAULT_BAD_REQUEST_HTML : raw.body; const headers = raw.headers || {}; const status = raw.status || 400; - let responseHeaderLines = ''; - const firstLine = `HTTP/1.1 ${status} ${http.STATUS_CODES[status] || 'Unknown'}`; + let responseHeaderLines = ""; + const firstLine = `HTTP/1.1 ${status} ${http.STATUS_CODES[status] || "Unknown"}`; // Not that safe because no validation for header keys. // Refs: https://github.com/nodejs/node/blob/b38c81/lib/_http_outgoing.js#L451 for (const key of Object.keys(headers)) { - if (key.toLowerCase() === 'content-length') { + if (key.toLowerCase() === "content-length") { delete headers[key]; continue; } @@ -117,15 +116,17 @@ class Application extends EggApplication { onClientError(err, socket) { // ignore when there is no http body, it almost like an ECONNRESET if (err.rawPacket) { - this.logger.warn('A client (%s:%d) error [%s] occurred: %s', + this.logger.warn( + "A client (%s:%d) error [%s] occurred: %s", socket.remoteAddress, socket.remotePort, err.code, - err.message); + err.message, + ); } - if (typeof this.config.onClientError === 'function') { - const p = eggUtils.callFn(this.config.onClientError, [ err, socket, this ]); + if (typeof this.config.onClientError === "function") { + const p = eggUtils.callFn(this.config.onClientError, [err, socket, this]); // the returned object should be something like: // @@ -142,9 +143,9 @@ class Application extends EggApplication { // + body: '' // + headers: {} // + status: 400 - p.then(ret => { + p.then((ret) => { this[RESPONSE_RAW](socket, ret || {}); - }).catch(err => { + }).catch((err) => { this.logger.error(err); this[RESPONSE_RAW](socket); }); @@ -163,15 +164,22 @@ class Application extends EggApplication { /* istanbul ignore next */ graceful({ - server: [ server ], + server: [server], error: (err, throwErrorCount) => { const originMessage = err.message; if (originMessage) { // shouldjs will override error property but only getter // https://github.com/shouldjs/should.js/blob/889e22ebf19a06bc2747d24cf34b25cc00b37464/lib/assertion-error.js#L26 - Object.defineProperty(err, 'message', { + Object.defineProperty(err, "message", { get() { - return originMessage + ' (uncaughtException throw ' + throwErrorCount + ' times on pid:' + process.pid + ')'; + return ( + originMessage + + " (uncaughtException throw " + + throwErrorCount + + " times on pid:" + + process.pid + + ")" + ); }, configurable: true, enumerable: false, @@ -182,7 +190,7 @@ class Application extends EggApplication { ignoreCode: serverGracefulIgnoreCode, }); - server.on('clientError', (err, socket) => this.onClientError(err, socket)); + server.on("clientError", (err, socket) => this.onClientError(err, socket)); // server timeout if (is.number(this.config.serverTimeout)) server.setTimeout(this.config.serverTimeout); @@ -209,8 +217,8 @@ class Application extends EggApplication { } handleRequest(ctx, fnMiddleware) { - this.emit('request', ctx); - onFinished(ctx.res, () => this.emit('response', ctx)); + this.emit("request", ctx); + onFinished(ctx.res, () => this.emit("response", ctx)); return super.handleRequest(ctx, fnMiddleware); } @@ -225,7 +233,7 @@ class Application extends EggApplication { const rundir = this.config.rundir; const FULLPATH = this.loader.FileLoader.FULLPATH; try { - const dumpRouterFile = path.join(rundir, 'router.json'); + const dumpRouterFile = path.join(rundir, "router.json"); const routers = []; for (const layer of this.router.stack) { routers.push({ @@ -234,7 +242,9 @@ class Application extends EggApplication { paramNames: layer.paramNames, path: layer.path, regexp: layer.regexp.toString(), - stack: layer.stack.map(stack => stack[FULLPATH] || stack._name || stack.name || 'anonymous'), + stack: layer.stack.map( + (stack) => stack[FULLPATH] || stack._name || stack.name || "anonymous", + ), }); } fs.writeFileSync(dumpRouterFile, JSON.stringify(routers, null, 2)); @@ -277,15 +287,15 @@ class Application extends EggApplication { get keys() { if (!this[KEYS]) { if (!this.config.keys) { - if (this.config.env === 'local' || this.config.env === 'unittest') { - const configPath = path.join(this.config.baseDir, 'config/config.default.js'); - console.error('Cookie need secret key to sign and encrypt.'); - console.error('Please add `config.keys` in %s', configPath); + if (this.config.env === "local" || this.config.env === "unittest") { + const configPath = path.join(this.config.baseDir, "config/config.default.js"); + console.error("Cookie need secret key to sign and encrypt."); + console.error("Please add `config.keys` in %s", configPath); } - throw new Error('Please set config.keys first'); + throw new Error("Please set config.keys first"); } - this[KEYS] = this.config.keys.split(',').map(s => s.trim()); + this[KEYS] = this.config.keys.split(",").map((s) => s.trim()); } return this[KEYS]; } @@ -318,15 +328,15 @@ class Application extends EggApplication { */ [BIND_EVENTS]() { // Browser Cookie Limits: http://browsercookielimits.squawky.net/ - this.on('cookieLimitExceed', ({ name, value, ctx }) => { + this.on("cookieLimitExceed", ({ name, value, ctx }) => { const err = new Error(`cookie ${name}'s length(${value.length}) exceed the limit(4093)`); - err.name = 'CookieLimitExceedError'; + err.name = "CookieLimitExceedError"; err.key = name; err.cookie = value; ctx.coreLogger.error(err); }); // expose server to support websocket - this.once('server', server => this.onServer(server)); + this.once("server", (server) => this.onServer(server)); } /** @@ -336,10 +346,13 @@ class Application extends EggApplication { */ [WARN_CONFUSED_CONFIG]() { const confusedConfigurations = this.config.confusedConfigurations; - Object.keys(confusedConfigurations).forEach(key => { + Object.keys(confusedConfigurations).forEach((key) => { if (this.config[key] !== undefined) { - this.logger.warn('Unexpected config key `%s` exists, Please use `%s` instead.', - key, confusedConfigurations[key]); + this.logger.warn( + "Unexpected config key `%s` exists, Please use `%s` instead.", + key, + confusedConfigurations[key], + ); } }); } diff --git a/lib/core/base_context_class.js b/lib/core/base_context_class.js index 1016d60440..86a7ea72ac 100644 --- a/lib/core/base_context_class.js +++ b/lib/core/base_context_class.js @@ -1,9 +1,9 @@ -'use strict'; +"use strict"; -const EggCoreBaseContextClass = require('egg-core').BaseContextClass; -const BaseContextLogger = require('./base_context_logger'); +const EggCoreBaseContextClass = require("egg-core").BaseContextClass; +const BaseContextLogger = require("./base_context_logger"); -const LOGGER = Symbol('BaseContextClass#logger'); +const LOGGER = Symbol("BaseContextClass#logger"); /** * BaseContextClass is a base class that can be extended, diff --git a/lib/core/base_context_logger.js b/lib/core/base_context_logger.js index 6c1dc2c8df..5909059b32 100644 --- a/lib/core/base_context_logger.js +++ b/lib/core/base_context_logger.js @@ -1,4 +1,4 @@ -const CALL = Symbol('BaseContextLogger#call'); +const CALL = Symbol("BaseContextLogger#call"); class BaseContextLogger { /** @@ -18,7 +18,7 @@ class BaseContextLogger { [CALL](method, args) { // add `[${pathName}]` in log - if (this.pathName && typeof args[0] === 'string') { + if (this.pathName && typeof args[0] === "string") { args[0] = `[${this.pathName}] ${args[0]}`; } this.ctx.app.logger[method](...args); @@ -30,7 +30,7 @@ class BaseContextLogger { * @since 1.2.0 */ debug(...args) { - this[CALL]('debug', args); + this[CALL]("debug", args); } /** @@ -39,7 +39,7 @@ class BaseContextLogger { * @since 1.2.0 */ info(...args) { - this[CALL]('info', args); + this[CALL]("info", args); } /** @@ -48,7 +48,7 @@ class BaseContextLogger { * @since 1.2.0 */ warn(...args) { - this[CALL]('warn', args); + this[CALL]("warn", args); } /** @@ -57,7 +57,7 @@ class BaseContextLogger { * @since 1.2.0 */ error(...args) { - this[CALL]('error', args); + this[CALL]("error", args); } } diff --git a/lib/core/base_hook_class.js b/lib/core/base_hook_class.js index b0e65ce77d..d4a3b49bcc 100644 --- a/lib/core/base_hook_class.js +++ b/lib/core/base_hook_class.js @@ -1,10 +1,9 @@ -'use strict'; +"use strict"; -const assert = require('node:assert'); -const INSTANCE = Symbol('BaseHookClass#instance'); +const assert = require("node:assert"); +const INSTANCE = Symbol("BaseHookClass#instance"); class BaseHookClass { - constructor(instance) { this[INSTANCE] = instance; } @@ -18,12 +17,12 @@ class BaseHookClass { } get app() { - assert(this[INSTANCE].type === 'application', 'agent boot should not use app instance'); + assert(this[INSTANCE].type === "application", "agent boot should not use app instance"); return this[INSTANCE]; } get agent() { - assert(this[INSTANCE].type === 'agent', 'app boot should not use agent instance'); + assert(this[INSTANCE].type === "agent", "app boot should not use agent instance"); return this[INSTANCE]; } } diff --git a/lib/core/context_httpclient.js b/lib/core/context_httpclient.js index a1db7d26a5..440e558589 100644 --- a/lib/core/context_httpclient.js +++ b/lib/core/context_httpclient.js @@ -18,8 +18,8 @@ class ContextHttpClient { return await this.app.curl(url, options); } - async request(url, options) { - return await this.curl(url, options); + request(url, options) { + return this.curl(url, options); } } diff --git a/lib/core/dnscache_httpclient.js b/lib/core/dnscache_httpclient.js index ba5e4bcb45..17731b36f1 100644 --- a/lib/core/dnscache_httpclient.js +++ b/lib/core/dnscache_httpclient.js @@ -1,12 +1,12 @@ -const dns = require('node:dns').promises; -const LRU = require('ylru'); -const { assign } = require('utility'); -const HttpClient = require('./httpclient'); -const utils = require('./utils'); +const dns = require("node:dns").promises; +const LRU = require("ylru"); +const { assign } = require("utility"); +const HttpClient = require("./httpclient"); +const utils = require("./utils"); const IP_REGEX = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; -const DNSLOOKUP = Symbol('DNSCacheHttpClient#dnslookup'); -const UPDATE_DNS = Symbol('DNSCacheHttpClient#updateDNS'); +const DNSLOOKUP = Symbol("DNSCacheHttpClient#dnslookup"); +const UPDATE_DNS = Symbol("DNSCacheHttpClient#updateDNS"); class DNSCacheHttpClient extends HttpClient { constructor(app) { @@ -26,7 +26,7 @@ class DNSCacheHttpClient extends HttpClient { async [DNSLOOKUP](url, args) { let parsed; - if (typeof url === 'string') { + if (typeof url === "string") { parsed = utils.safeParseURL(url); // invalid url or relative url if (!parsed) return { url, args }; @@ -55,7 +55,7 @@ class DNSCacheHttpClient extends HttpClient { if (now - record.timestamp >= this.dnsCacheLookupInterval) { // make sure the next request doesn't refresh dns query record.timestamp = now; - this[UPDATE_DNS](hostname, args).catch(err => this.app.emit('error', err)); + this[UPDATE_DNS](hostname, args).catch((err) => this.app.emit("error", err)); } return { url: formatDnsLookupUrl(hostname, url, record.ip), args }; @@ -69,8 +69,7 @@ class DNSCacheHttpClient extends HttpClient { const logger = args.ctx ? args.ctx.coreLogger : this.app.coreLogger; try { const { address } = await dns.lookup(hostname, { family: 4 }); - logger.info('[dnscache_httpclient] dns lookup success: %s => %s', - hostname, address); + logger.info("[dnscache_httpclient] dns lookup success: %s => %s", hostname, address); this.dnsCache.set(hostname, { timestamp: Date.now(), ip: address }); return address; } catch (err) { @@ -83,7 +82,7 @@ class DNSCacheHttpClient extends HttpClient { module.exports = DNSCacheHttpClient; function formatDnsLookupUrl(host, url, address) { - if (typeof url === 'string') return url.replace(host, address); + if (typeof url === "string") return url.replace(host, address); const urlObj = assign({}, url); urlObj.hostname = urlObj.hostname.replace(host, address); if (urlObj.host) { diff --git a/lib/core/fetch_factory.js b/lib/core/fetch_factory.js index 0b67e9e5c7..d5d23501af 100644 --- a/lib/core/fetch_factory.js +++ b/lib/core/fetch_factory.js @@ -1,6 +1,6 @@ -const debug = require('node:util').debuglog('egg:lib:core:fetch_factory'); +const debug = require("node:util").debuglog("egg:lib:core:fetch_factory"); -const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]); +const mainNodejsVersion = parseInt(process.versions.node.split(".")[0]); let FetchFactory; let fetch; // Track initialization per app instance by storing a WeakMap @@ -11,11 +11,11 @@ let ssrfFetchFactory; if (mainNodejsVersion >= 20) { // urllib@4 only works on Node.js >= 20 try { - const urllib4 = require('urllib4'); + const urllib4 = require("urllib4"); FetchFactory = urllib4.FetchFactory; - debug('urllib4 enable'); + debug("urllib4 enable"); - fetch = function(url, init) { + fetch = function (url, init) { if (!fetchInitializedMap.get(this)) { const clientOptions = {}; if (this.config.httpclient?.lookup) { @@ -44,7 +44,7 @@ if (mainNodejsVersion >= 20) { if (ssrfConfig?.checkAddress) { clientOptions.checkAddress = ssrfConfig.checkAddress; } else { - this.logger.warn('[egg-security] please configure `config.security.ssrf` first'); + this.logger.warn("[egg-security] please configure `config.security.ssrf` first"); } if (this.config.httpclient?.lookup) { clientOptions.lookup = this.config.httpclient.lookup; @@ -61,7 +61,7 @@ if (mainNodejsVersion >= 20) { return ssrfFetchFactory.fetch(url, init); }; } catch (err) { - debug('require urllib4 error: %s', err); + debug("require urllib4 error: %s", err); } } diff --git a/lib/core/httpclient.js b/lib/core/httpclient.js index f3828e800b..537ab70f24 100644 --- a/lib/core/httpclient.js +++ b/lib/core/httpclient.js @@ -1,12 +1,12 @@ -const Agent = require('agentkeepalive'); -const HttpsAgent = require('agentkeepalive').HttpsAgent; -const urllib = require('urllib'); -const ms = require('humanize-ms'); -const { FrameworkBaseError } = require('egg-errors'); +const Agent = require("agentkeepalive"); +const HttpsAgent = require("agentkeepalive").HttpsAgent; +const urllib = require("urllib"); +const ms = require("humanize-ms"); +const { FrameworkBaseError } = require("egg-errors"); class HttpClientError extends FrameworkBaseError { get module() { - return 'httpclient'; + return "httpclient"; } } @@ -35,7 +35,7 @@ class HttpClient extends urllib.HttpClient2 { try { return await super.request(url, args); } catch (err) { - if (err.code === 'ENETUNREACH') { + if (err.code === "ENETUNREACH") { throw HttpClientError.create(err.message, err.code); } throw err; @@ -51,7 +51,7 @@ class HttpClient extends urllib.HttpClient2 { if (ssrfConfig?.checkAddress) { options.checkAddress = ssrfConfig.checkAddress; } else { - this.app.logger.warn('[egg-security] please configure `config.security.ssrf` first'); + this.app.logger.warn("[egg-security] please configure `config.security.ssrf` first"); } return await this.curl(url, options); @@ -62,7 +62,7 @@ function normalizeConfig(app) { const config = app.config.httpclient; // compatibility - if (typeof config.keepAlive === 'boolean') { + if (typeof config.keepAlive === "boolean") { config.httpAgent.keepAlive = config.keepAlive; config.httpsAgent.keepAlive = config.keepAlive; } @@ -92,27 +92,31 @@ function normalizeConfig(app) { } } - if (typeof config.maxSockets === 'number') { + if (typeof config.maxSockets === "number") { config.httpAgent.maxSockets = config.maxSockets; config.httpsAgent.maxSockets = config.maxSockets; } - if (typeof config.maxFreeSockets === 'number') { + if (typeof config.maxFreeSockets === "number") { config.httpAgent.maxFreeSockets = config.maxFreeSockets; config.httpsAgent.maxFreeSockets = config.maxFreeSockets; } if (config.httpAgent.timeout < 30000) { - app.coreLogger.warn('[egg:httpclient] config.httpclient.httpAgent.timeout(%s) can\'t below 30000, auto reset to 30000', - config.httpAgent.timeout); + app.coreLogger.warn( + "[egg:httpclient] config.httpclient.httpAgent.timeout(%s) can't below 30000, auto reset to 30000", + config.httpAgent.timeout, + ); config.httpAgent.timeout = 30000; } if (config.httpsAgent.timeout < 30000) { - app.coreLogger.warn('[egg:httpclient] config.httpclient.httpsAgent.timeout(%s) can\'t below 30000, auto reset to 30000', - config.httpsAgent.timeout); + app.coreLogger.warn( + "[egg:httpclient] config.httpclient.httpsAgent.timeout(%s) can't below 30000, auto reset to 30000", + config.httpsAgent.timeout, + ); config.httpsAgent.timeout = 30000; } - if (typeof config.request.timeout === 'string') { + if (typeof config.request.timeout === "string") { config.request.timeout = ms(config.request.timeout); } } diff --git a/lib/core/httpclient_next.js b/lib/core/httpclient_next.js index 7c80b78277..66531d7a50 100644 --- a/lib/core/httpclient_next.js +++ b/lib/core/httpclient_next.js @@ -1,23 +1,23 @@ -const debug = require('node:util').debuglog('egg:lib:core:httpclient_next'); -const ms = require('humanize-ms'); +const debug = require("node:util").debuglog("egg:lib:core:httpclient_next"); +const ms = require("humanize-ms"); -const SSRF_HTTPCLIENT = Symbol('SSRF_HTTPCLIENT'); +const SSRF_HTTPCLIENT = Symbol("SSRF_HTTPCLIENT"); -const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]); +const mainNodejsVersion = parseInt(process.versions.node.split(".")[0]); let HttpClient; if (mainNodejsVersion >= 20) { // urllib@4 only works on Node.js >= 20 try { - HttpClient = require('urllib4').HttpClient; - debug('urllib4 enable'); + HttpClient = require("urllib4").HttpClient; + debug("urllib4 enable"); } catch (err) { - debug('require urllib4 error: %s', err); + debug("require urllib4 error: %s", err); } } if (!HttpClient) { // fallback to urllib@3 - HttpClient = require('urllib-next').HttpClient; - debug('urllib3 enable'); + HttpClient = require("urllib-next").HttpClient; + debug("urllib3 enable"); } class HttpClientNext extends HttpClient { @@ -61,7 +61,7 @@ class HttpClientNext extends HttpClient { if (ssrfConfig?.checkAddress) { options.checkAddress = ssrfConfig.checkAddress; } else { - this.app.logger.warn('[egg-security] please configure `config.security.ssrf` first'); + this.app.logger.warn("[egg-security] please configure `config.security.ssrf` first"); } if (!options.lookup && this.app.config.httpclient.lookup) { options.lookup = this.app.config.httpclient.lookup; @@ -77,7 +77,7 @@ class HttpClientNext extends HttpClient { function normalizeConfig(app) { const config = app.config.httpclient; - if (typeof config.request.timeout === 'string') { + if (typeof config.request.timeout === "string") { config.request.timeout = ms(config.request.timeout); } } diff --git a/lib/core/logger.js b/lib/core/logger.js index a38dbddcf5..c085449bdf 100644 --- a/lib/core/logger.js +++ b/lib/core/logger.js @@ -1,13 +1,17 @@ -const { EggLoggers } = require('egg-logger'); -const { setCustomLogger } = require('onelogger'); +const { EggLoggers } = require("egg-logger"); +const { setCustomLogger } = require("onelogger"); module.exports = function createLoggers(app) { const loggerConfig = app.config.logger; loggerConfig.type = app.type; loggerConfig.localStorage = app.ctxStorage; - if (app.config.env === 'prod' && loggerConfig.level === 'DEBUG' && !loggerConfig.allowDebugAtProd) { - loggerConfig.level = 'INFO'; + if ( + app.config.env === "prod" && + loggerConfig.level === "DEBUG" && + !loggerConfig.allowDebugAtProd + ) { + loggerConfig.level = "INFO"; } const loggers = new EggLoggers(app.config); @@ -29,7 +33,7 @@ module.exports = function createLoggers(app) { setCustomLogger(loggerName, undefined); } }); - loggers.coreLogger.info('[egg:logger] init all loggers with options: %j', loggerConfig); + loggers.coreLogger.info("[egg:logger] init all loggers with options: %j", loggerConfig); return loggers; }; diff --git a/lib/core/messenger/index.js b/lib/core/messenger/index.js index f819cfa917..1e3ed383ee 100644 --- a/lib/core/messenger/index.js +++ b/lib/core/messenger/index.js @@ -1,14 +1,16 @@ -'use strict'; +"use strict"; -const LocalMessenger = require('./local'); -const IPCMessenger = require('./ipc'); +const LocalMessenger = require("./local"); +const IPCMessenger = require("./ipc"); /** * @class Messenger */ -exports.create = egg => { - return egg.options.mode === 'single' - ? new LocalMessenger(egg) - : new IPCMessenger(egg); +/** + * @param {Object} egg - egg application instance + * @return {Messenger} messenger instance + */ +exports.create = (egg) => { + return egg.options.mode === "single" ? new LocalMessenger(egg) : new IPCMessenger(egg); }; diff --git a/lib/core/messenger/ipc.js b/lib/core/messenger/ipc.js index 155c8fe9df..7ea5835b94 100644 --- a/lib/core/messenger/ipc.js +++ b/lib/core/messenger/ipc.js @@ -1,16 +1,15 @@ -'use strict'; +"use strict"; -const debug = require('node:util').debuglog('egg:util:messenger:ipc'); -const is = require('is-type-of'); -const workerThreads = require('node:worker_threads'); -const sendmessage = require('sendmessage'); -const EventEmitter = require('node:events'); +const debug = require("node:util").debuglog("egg:util:messenger:ipc"); +const is = require("is-type-of"); +const workerThreads = require("node:worker_threads"); +const sendmessage = require("sendmessage"); +const EventEmitter = require("node:events"); /** * Communication between app worker and agent worker by IPC channel */ class Messenger extends EventEmitter { - constructor() { super(); this.pid = String(process.pid); @@ -18,13 +17,13 @@ class Messenger extends EventEmitter { // - retrieve app worker pids when it's an agent worker // - retrieve agent worker pids when it's an app worker this.opids = []; - this.on('egg-pids', pids => { + this.on("egg-pids", (pids) => { this.opids = pids; }); this._onMessage = this._onMessage.bind(this); - process.on('message', this._onMessage); + process.on("message", this._onMessage); if (!workerThreads.isMainThread) { - workerThreads.parentPort.on('message', this._onMessage); + workerThreads.parentPort.on("message", this._onMessage); } } @@ -35,9 +34,9 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ broadcast(action, data) { - debug('[%s] broadcast %s with %j', this.pid, action, data); - this.send(action, data, 'app'); - this.send(action, data, 'agent'); + debug("[%s] broadcast %s with %j", this.pid, action, data); + this.send(action, data, "app"); + this.send(action, data, "agent"); return this; } @@ -49,7 +48,7 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendTo(pid, action, data) { - debug('[%s] send %s with %j to %s', this.pid, action, data, pid); + debug("[%s] send %s with %j to %s", this.pid, action, data, pid); sendmessage(process, { action, data, @@ -81,8 +80,8 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendToApp(action, data) { - debug('[%s] send %s with %j to all app', this.pid, action, data); - this.send(action, data, 'app'); + debug("[%s] send %s with %j to all app", this.pid, action, data); + this.send(action, data, "app"); return this; } @@ -93,8 +92,8 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendToAgent(action, data) { - debug('[%s] send %s with %j to all agent', this.pid, action, data); - this.send(action, data, 'agent'); + debug("[%s] send %s with %j to all agent", this.pid, action, data); + this.send(action, data, "agent"); return this; } @@ -115,14 +114,19 @@ class Messenger extends EventEmitter { _onMessage(message) { if (message && is.string(message.action)) { - debug('[%s] got message %s with %j, receiverPid: %s', - this.pid, message.action, message.data, message.receiverPid); + debug( + "[%s] got message %s with %j, receiverPid: %s", + this.pid, + message.action, + message.data, + message.receiverPid, + ); this.emit(message.action, message.data); } } close() { - process.removeListener('message', this._onMessage); + process.removeListener("message", this._onMessage); this.removeAllListeners(); } diff --git a/lib/core/messenger/local.js b/lib/core/messenger/local.js index 65a9688424..e1bee56e2c 100644 --- a/lib/core/messenger/local.js +++ b/lib/core/messenger/local.js @@ -1,14 +1,13 @@ -'use strict'; +"use strict"; -const debug = require('node:util').debuglog('egg:util:messenger:local'); -const is = require('is-type-of'); -const EventEmitter = require('node:events'); +const debug = require("node:util").debuglog("egg:util:messenger:local"); +const is = require("is-type-of"); +const EventEmitter = require("node:events"); /** * Communication between app worker and agent worker with EventEmitter */ class Messenger extends EventEmitter { - constructor(egg) { super(); this.egg = egg; @@ -21,8 +20,8 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ broadcast(action, data) { - debug('[%s] broadcast %s with %j', this.pid, action, data); - this.send(action, data, 'both'); + debug("[%s] broadcast %s with %j", this.pid, action, data); + this.send(action, data, "both"); return this; } @@ -36,9 +35,9 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendTo(pid, action, data) { - debug('[%s] send %s with %j to %s', this.pid, action, data, pid); + debug("[%s] send %s with %j to %s", this.pid, action, data, pid); if (pid !== process.pid) return this; - this.send(action, data, 'both'); + this.send(action, data, "both"); return this; } @@ -52,8 +51,8 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendRandom(action, data) { - debug('[%s] send %s with %j to opposite', this.pid, action, data); - this.send(action, data, 'opposite'); + debug("[%s] send %s with %j to opposite", this.pid, action, data); + this.send(action, data, "opposite"); return this; } @@ -64,8 +63,8 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendToApp(action, data) { - debug('[%s] send %s with %j to all app', this.pid, action, data); - this.send(action, data, 'application'); + debug("[%s] send %s with %j to all app", this.pid, action, data); + this.send(action, data, "application"); return this; } @@ -76,8 +75,8 @@ class Messenger extends EventEmitter { * @return {Messenger} this */ sendToAgent(action, data) { - debug('[%s] send %s with %j to all agent', this.pid, action, data); - this.send(action, data, 'agent'); + debug("[%s] send %s with %j to all agent", this.pid, action, data); + this.send(action, data, "agent"); return this; } @@ -95,7 +94,7 @@ class Messenger extends EventEmitter { let agent; let opposite; - if (egg.type === 'application') { + if (egg.type === "application") { application = egg; agent = egg.agent; opposite = agent; @@ -104,15 +103,15 @@ class Messenger extends EventEmitter { application = egg.application; opposite = application; } - if (!to) to = egg.type === 'application' ? 'agent' : 'application'; + if (!to) to = egg.type === "application" ? "agent" : "application"; - if (application && application.messenger && (to === 'application' || to === 'both')) { + if (application && application.messenger && (to === "application" || to === "both")) { application.messenger._onMessage({ action, data }); } - if (agent && agent.messenger && (to === 'agent' || to === 'both')) { + if (agent && agent.messenger && (to === "agent" || to === "both")) { agent.messenger._onMessage({ action, data }); } - if (opposite && opposite.messenger && to === 'opposite') { + if (opposite && opposite.messenger && to === "opposite") { opposite.messenger._onMessage({ action, data }); } }); @@ -122,7 +121,7 @@ class Messenger extends EventEmitter { _onMessage(message) { if (message && is.string(message.action)) { - debug('[%s] got message %s with %j', this.pid, message.action, message.data); + debug("[%s] got message %s with %j", this.pid, message.action, message.data); this.emit(message.action, message.data); } } diff --git a/lib/core/singleton.js b/lib/core/singleton.js index 7931557e73..b70166ec4e 100644 --- a/lib/core/singleton.js +++ b/lib/core/singleton.js @@ -1,13 +1,13 @@ -'use strict'; +"use strict"; -const assert = require('node:assert'); -const is = require('is-type-of'); +const assert = require("node:assert"); +const is = require("is-type-of"); class Singleton { constructor(options = {}) { - assert(options.name, '[egg:singleton] Singleton#constructor options.name is required'); - assert(options.app, '[egg:singleton] Singleton#constructor options.app is required'); - assert(options.create, '[egg:singleton] Singleton#constructor options.create is required'); + assert(options.name, "[egg:singleton] Singleton#constructor options.name is required"); + assert(options.app, "[egg:singleton] Singleton#constructor options.app is required"); + assert(options.create, "[egg:singleton] Singleton#constructor options.create is required"); assert(!options.app[options.name], `${options.name} is already exists in app`); this.clients = new Map(); this.app = options.app; @@ -23,8 +23,10 @@ class Singleton { initSync() { const options = this.options; - assert(!(options.client && options.clients), - `egg:singleton ${this.name} can not set options.client and options.clients both`); + assert( + !(options.client && options.clients), + `egg:singleton ${this.name} can not set options.client and options.clients both`, + ); // alias app[name] as client, but still support createInstance method if (options.client) { @@ -36,7 +38,7 @@ class Singleton { // multi client, use app[name].getInstance(id) if (options.clients) { - Object.keys(options.clients).forEach(id => { + Object.keys(options.clients).forEach((id) => { const client = this.createInstance(options.clients[id], id); this.clients.set(id, client); }); @@ -50,8 +52,10 @@ class Singleton { async initAsync() { const options = this.options; - assert(!(options.client && options.clients), - `egg:singleton ${this.name} can not set options.client and options.clients both`); + assert( + !(options.client && options.clients), + `egg:singleton ${this.name} can not set options.client and options.clients both`, + ); // alias app[name] as client, but still support createInstance method if (options.client) { @@ -63,10 +67,13 @@ class Singleton { // multi client, use app[name].getInstance(id) if (options.clients) { - await Promise.all(Object.keys(options.clients).map(id => { - return this.createInstanceAsync(options.clients[id], id) - .then(client => this.clients.set(id, client)); - })); + await Promise.all( + Object.keys(options.clients).map((id) => { + return this.createInstanceAsync(options.clients[id], id).then((client) => + this.clients.set(id, client), + ); + }), + ); this.app[this.name] = this; return; } @@ -86,8 +93,10 @@ class Singleton { createInstance(config, clientName) { // async creator only support createInstanceAsync - assert(!is.asyncFunction(this.create), - `egg:singleton ${this.name} only support create asynchronous, please use createInstanceAsync`); + assert( + !is.asyncFunction(this.create), + `egg:singleton ${this.name} only support create asynchronous, please use createInstanceAsync`, + ); // options.default will be merge in to options.clients[id] config = Object.assign({}, this.options.default, config); return this.create(config, this.app, clientName); @@ -100,20 +109,26 @@ class Singleton { } _extendDynamicMethods(client) { - assert(!client.createInstance, 'singleton instance should not have createInstance method'); - assert(!client.createInstanceAsync, 'singleton instance should not have createInstanceAsync method'); + assert(!client.createInstance, "singleton instance should not have createInstance method"); + assert( + !client.createInstanceAsync, + "singleton instance should not have createInstanceAsync method", + ); try { let extendable = client; // Object.preventExtensions() or Object.freeze() if (!Object.isExtensible(client) || Object.isFrozen(client)) { - // eslint-disable-next-line no-proto + // oxlint-disable-next-line no-proto extendable = client.__proto__ || client; } extendable.createInstance = this.createInstance.bind(this); extendable.createInstanceAsync = this.createInstanceAsync.bind(this); } catch { - this.app.logger.warn('egg:singleton %s dynamic create is disabled because of client is unextensible', this.name); + this.app.logger.warn( + "egg:singleton %s dynamic create is disabled because of client is unextensible", + this.name, + ); } } } diff --git a/lib/core/utils.js b/lib/core/utils.js index 657d3952f2..e747261bf0 100644 --- a/lib/core/utils.js +++ b/lib/core/utils.js @@ -1,8 +1,8 @@ -'use strict'; +"use strict"; -const util = require('node:util'); -const is = require('is-type-of'); -const URL = require('node:url').URL; +const util = require("node:util"); +const is = require("is-type-of"); +const URL = require("node:url").URL; module.exports = { convertObject, @@ -12,17 +12,23 @@ module.exports = { function convertObject(obj, ignore, ignoreKeyPaths) { if (!is.array(ignore)) { - ignore = [ ignore ]; + ignore = [ignore]; } if (!is.array(ignoreKeyPaths)) { - ignoreKeyPaths = ignoreKeyPaths ? [ ignoreKeyPaths ] : []; + ignoreKeyPaths = ignoreKeyPaths ? [ignoreKeyPaths] : []; } - _convertObject(obj, ignore, ignoreKeyPaths, ''); + _convertObject(obj, ignore, ignoreKeyPaths, ""); } function _convertObject(obj, ignore, ignoreKeyPaths, keyPath) { for (const key of Object.keys(obj)) { - obj[key] = convertValue(key, obj[key], ignore, ignoreKeyPaths, keyPath ? `${keyPath}.${key}` : key); + obj[key] = convertValue( + key, + obj[key], + ignore, + ignoreKeyPaths, + keyPath ? `${keyPath}.${key}` : key, + ); } return obj; } @@ -56,13 +62,13 @@ function convertValue(key, value, ignore, ignoreKeyPaths, keyPath) { // o = {} if (Object.getPrototypeOf(value) === Object.prototype) { if (hitKeyPath) { - return ''; + return ""; } return _convertObject(value, ignore, ignoreKeyPaths, keyPath); } // support class - const name = value.name || 'anonymous'; + const name = value.name || "anonymous"; if (is.class(value)) { return ``; } @@ -100,14 +106,14 @@ function safeParseURL(url) { * - Allows overriding properties on the proxy target (overlay) to take effect. * - Delegates everything else to the real object. * - * @param {Object} options + * @param {Object} options - proxy configuration options * @param {Function} options.createReal Create the real object (lazy) - * @param {boolean} [options.bindFunctions=true] Bind real methods to the real object - * @return {Proxy} + * @param {boolean} [options.bindFunctions] Bind real methods to the real object, default is true + * @return {Proxy} the transparent proxy instance */ function createTransparentProxy({ createReal, bindFunctions = true }) { - if (typeof createReal !== 'function') { - throw new TypeError('createReal must be a function'); + if (typeof createReal !== "function") { + throw new TypeError("createReal must be a function"); } let real = null; @@ -128,81 +134,86 @@ function createTransparentProxy({ createReal, bindFunctions = true }) { } }; - return new Proxy({}, { - get(target, prop, receiver) { - init(); - // Check if property is defined on proxy target (monkeypatch overlay) - if (Object.getOwnPropertyDescriptor(target, prop)) { - return Reflect.get(target, prop, receiver); - } - const value = real[prop]; - if (bindFunctions && typeof value === 'function') { - return value.bind(real); - } - return value; + return new Proxy( + {}, + { + get(target, prop, receiver) { + init(); + // Check if property is defined on proxy target (monkeypatch overlay) + if (Object.getOwnPropertyDescriptor(target, prop)) { + return Reflect.get(target, prop, receiver); + } + const value = real[prop]; + if (bindFunctions && typeof value === "function") { + return value.bind(real); + } + return value; + }, + + set(target, prop, value, receiver) { + init(); + if (Object.getOwnPropertyDescriptor(target, prop)) { + return Reflect.set(target, prop, value, receiver); + } + return Reflect.set(real, prop, value); + }, + + has(target, prop) { + init(); + return prop in target || prop in real; + }, + + ownKeys(target) { + init(); + const keys = new Set([...Reflect.ownKeys(real), ...Reflect.ownKeys(target)]); + return Array.from(keys); + }, + + getOwnPropertyDescriptor(target, prop) { + init(); + return ( + Object.getOwnPropertyDescriptor(target, prop) || + Object.getOwnPropertyDescriptor(real, prop) + ); + }, + + deleteProperty(target, prop) { + init(); + if (Object.getOwnPropertyDescriptor(target, prop)) { + return delete target[prop]; + } + return delete real[prop]; + }, + + getPrototypeOf() { + init(); + return Object.getPrototypeOf(real); + }, + + setPrototypeOf(_target, proto) { + init(); + return Reflect.setPrototypeOf(real, proto); + }, + + isExtensible() { + init(); + return Reflect.isExtensible(real); + }, + + preventExtensions(target) { + init(); + // Must also prevent extensions on target to satisfy Proxy invariants + const result = Reflect.preventExtensions(real); + if (result) { + Reflect.preventExtensions(target); + } + return result; + }, + + defineProperty(target, prop, descriptor) { + // Used by monkeypatch libs: keep overrides on proxy target (overlay layer). + return Reflect.defineProperty(target, prop, descriptor); + }, }, - - set(target, prop, value, receiver) { - init(); - if (Object.getOwnPropertyDescriptor(target, prop)) { - return Reflect.set(target, prop, value, receiver); - } - return Reflect.set(real, prop, value); - }, - - has(target, prop) { - init(); - return prop in target || prop in real; - }, - - ownKeys(target) { - init(); - const keys = new Set([ ...Reflect.ownKeys(real), ...Reflect.ownKeys(target) ]); - return Array.from(keys); - }, - - getOwnPropertyDescriptor(target, prop) { - init(); - return Object.getOwnPropertyDescriptor(target, prop) - || Object.getOwnPropertyDescriptor(real, prop); - }, - - deleteProperty(target, prop) { - init(); - if (Object.getOwnPropertyDescriptor(target, prop)) { - return delete target[prop]; - } - return delete real[prop]; - }, - - getPrototypeOf() { - init(); - return Object.getPrototypeOf(real); - }, - - setPrototypeOf(_target, proto) { - init(); - return Reflect.setPrototypeOf(real, proto); - }, - - isExtensible() { - init(); - return Reflect.isExtensible(real); - }, - - preventExtensions(target) { - init(); - // Must also prevent extensions on target to satisfy Proxy invariants - const result = Reflect.preventExtensions(real); - if (result) { - Reflect.preventExtensions(target); - } - return result; - }, - - defineProperty(target, prop, descriptor) { - // Used by monkeypatch libs: keep overrides on proxy target (overlay layer). - return Reflect.defineProperty(target, prop, descriptor); - }, - }); + ); } diff --git a/lib/egg.js b/lib/egg.js index 4b462d8ec5..ffa5625c01 100644 --- a/lib/egg.js +++ b/lib/egg.js @@ -1,30 +1,30 @@ -const { performance } = require('node:perf_hooks'); -const path = require('node:path'); -const fs = require('node:fs'); -const ms = require('ms'); -const http = require('node:http'); -const EggCore = require('egg-core').EggCore; -const cluster = require('cluster-client'); -const extend = require('extend2'); -const ContextLogger = require('egg-logger').EggContextLogger; -const ContextCookies = require('egg-cookies'); -const CircularJSON = require('circular-json-for-egg'); -const ContextHttpClient = require('./core/context_httpclient'); -const Messenger = require('./core/messenger'); -const DNSCacheHttpClient = require('./core/dnscache_httpclient'); -const HttpClient = require('./core/httpclient'); -const HttpClientNext = require('./core/httpclient_next'); -const { FetchFactory, safeFetch, fetch } = require('./core/fetch_factory'); -const createLoggers = require('./core/logger'); -const Singleton = require('./core/singleton'); -const utils = require('./core/utils'); -const BaseContextClass = require('./core/base_context_class'); -const BaseHookClass = require('./core/base_hook_class'); - -const HTTPCLIENT = Symbol('EggApplication#httpclient'); -const LOGGERS = Symbol('EggApplication#loggers'); -const EGG_PATH = Symbol.for('egg#eggPath'); -const CLUSTER_CLIENTS = Symbol.for('egg#clusterClients'); +const { performance } = require("node:perf_hooks"); +const path = require("node:path"); +const fs = require("node:fs"); +const ms = require("ms"); +const http = require("node:http"); +const EggCore = require("egg-core").EggCore; +const cluster = require("cluster-client"); +const extend = require("extend2"); +const ContextLogger = require("egg-logger").EggContextLogger; +const ContextCookies = require("egg-cookies"); +const CircularJSON = require("circular-json-for-egg"); +const ContextHttpClient = require("./core/context_httpclient"); +const Messenger = require("./core/messenger"); +const DNSCacheHttpClient = require("./core/dnscache_httpclient"); +const HttpClient = require("./core/httpclient"); +const HttpClientNext = require("./core/httpclient_next"); +const { FetchFactory, safeFetch, fetch } = require("./core/fetch_factory"); +const createLoggers = require("./core/logger"); +const Singleton = require("./core/singleton"); +const utils = require("./core/utils"); +const BaseContextClass = require("./core/base_context_class"); +const BaseHookClass = require("./core/base_hook_class"); + +const HTTPCLIENT = Symbol("EggApplication#httpclient"); +const LOGGERS = Symbol("EggApplication#loggers"); +const EGG_PATH = Symbol.for("egg#eggPath"); +const CLUSTER_CLIENTS = Symbol.for("egg#clusterClients"); /** * Based on koa's Application @@ -33,7 +33,6 @@ const CLUSTER_CLIENTS = Symbol.for('egg#clusterClients'); * @augments EggCore */ class EggApplication extends EggCore { - /** * @class * @param {Object} options @@ -43,7 +42,7 @@ class EggApplication extends EggCore { * - {String} [mode] - process mode, can be cluster / single, default is `cluster` */ constructor(options = {}) { - options.mode = options.mode || 'cluster'; + options.mode = options.mode || "cluster"; super(options); // export context base classes, let framework can impl sub class and over context extend easily. @@ -68,27 +67,32 @@ class EggApplication extends EggCore { // trigger `serverDidReady` hook when all the app workers // and agent worker are ready - this.messenger.once('egg-ready', () => { + this.messenger.once("egg-ready", () => { this.lifecycle.triggerServerDidReady(); }); // dump config after ready, ensure all the modifications during start will be recorded // make sure dumpConfig is the last ready callback - this.ready(() => process.nextTick(() => { - const dumpStartTime = Date.now(); - this.dumpConfig(); - this.dumpTiming(); - this.coreLogger.info('[egg:core] dump config after ready, %s', ms(Date.now() - dumpStartTime)); - })); + this.ready(() => + process.nextTick(() => { + const dumpStartTime = Date.now(); + this.dumpConfig(); + this.dumpTiming(); + this.coreLogger.info( + "[egg:core] dump config after ready, %s", + ms(Date.now() - dumpStartTime), + ); + }), + ); this._setupTimeoutTimer(); - this.console.info('[egg:core] App root: %s', this.baseDir); - this.console.info('[egg:core] All *.log files save on %j', this.config.logger.dir); - this.console.info('[egg:core] Loaded enabled plugin %j', this.loader.orderPlugins); + this.console.info("[egg:core] App root: %s", this.baseDir); + this.console.info("[egg:core] All *.log files save on %j", this.config.logger.dir); + this.console.info("[egg:core] Loaded enabled plugin %j", this.loader.orderPlugins); // Listen the error that promise had not catch, then log it in common-error this._unhandledRejectionHandler = this._unhandledRejectionHandler.bind(this); - process.on('unhandledRejection', this._unhandledRejectionHandler); + process.on("unhandledRejection", this._unhandledRejectionHandler); this[CLUSTER_CLIENTS] = []; @@ -112,14 +116,15 @@ class EggApplication extends EggCore { */ this.cluster = (clientClass, options) => { options = Object.assign({}, this.config.clusterClient, options, { - singleMode: this.options.mode === 'single', + singleMode: this.options.mode === "single", // cluster need a port that can't conflict on the environment port: this.options.clusterPort, // agent worker is leader, app workers are follower - isLeader: this.type === 'agent', + isLeader: this.type === "agent", logger: this.coreLogger, // debug mode does not check heartbeat - isCheckHeartbeat: this.config.env === 'prod' ? true : require('node:inspector').url() === undefined, + isCheckHeartbeat: + this.config.env === "prod" ? true : require("node:inspector").url() === undefined, }); const client = cluster(clientClass, options); this._patchClusterClient(client); @@ -129,7 +134,7 @@ class EggApplication extends EggCore { // register close function this.beforeClose(async () => { // single process mode will close agent before app close - if (this.type === 'application' && this.options.mode === 'single') { + if (this.type === "application" && this.options.mode === "single") { await this.agent.close(); } @@ -137,7 +142,7 @@ class EggApplication extends EggCore { logger.close(); } this.messenger.close(); - process.removeListener('unhandledRejection', this._unhandledRejectionHandler); + process.removeListener("unhandledRejection", this._unhandledRejectionHandler); }); /** @@ -225,20 +230,16 @@ class EggApplication extends EggCore { } } - delegate(res, this, [ - 'name', - 'baseDir', - 'subdomainOffset', - ]); + delegate(res, this, ["name", "baseDir", "subdomainOffset"]); abbr(res, this, [ - 'config', - 'controller', - 'httpclient', - 'loggers', - 'middlewares', - 'router', - 'serviceClasses', + "config", + "controller", + "httpclient", + "loggers", + "middlewares", + "router", + "serviceClasses", ]); return res; @@ -372,7 +373,7 @@ class EggApplication extends EggCore { * @since 1.0.0 */ get logger() { - return this.getLogger('logger'); + return this.getLogger("logger"); } /** @@ -381,7 +382,7 @@ class EggApplication extends EggCore { * @since 1.0.0 */ get coreLogger() { - return this.getLogger('coreLogger'); + return this.getLogger("coreLogger"); } _unhandledRejectionHandler(err) { @@ -397,8 +398,8 @@ class EggApplication extends EggCore { err = newError; } /* istanbul ignore else */ - if (err.name === 'Error') { - err.name = 'unhandledRejectionError'; + if (err.name === "Error") { + err.name = "unhandledRejectionError"; } this.coreLogger.error(err); } @@ -424,7 +425,11 @@ class EggApplication extends EggCore { ignoreKeyPaths = {}; } - const json = extend(true, {}, { config: this.config, plugins: this.loader.allPlugins, appInfo: this.loader.appInfo }); + const json = extend( + true, + {}, + { config: this.config, plugins: this.loader.allPlugins, appInfo: this.loader.appInfo }, + ); utils.convertObject(json, ignoreList, ignoreKeyPaths ? Object.keys(ignoreKeyPaths) : []); return { config: json, @@ -470,8 +475,12 @@ class EggApplication extends EggCore { for (const item of items) { // ignore #0 name: Process Start if (item.index > 0 && item.duration >= this.config.dump.timing.slowBootActionMinDuration) { - this.coreLogger.warn('[egg:core][slow-boot-action] #%d %dms, name: %s', - item.index, item.duration, item.name); + this.coreLogger.warn( + "[egg:core][slow-boot-action] #%d %dms, name: %s", + item.index, + item.duration, + item.name, + ); } } } catch (err) { @@ -480,13 +489,15 @@ class EggApplication extends EggCore { } get [EGG_PATH]() { - return path.join(__dirname, '..'); + return path.join(__dirname, ".."); } _setupTimeoutTimer() { const startTimeoutTimer = setTimeout(() => { this.coreLogger.error(this.timing.toString()); - this.coreLogger.error(`${this.type} still doesn't ready after ${this.config.workerStartTimeout} ms.`); + this.coreLogger.error( + `${this.type} still doesn't ready after ${this.config.workerStartTimeout} ms.`, + ); // log unfinished const items = this.timing.toJSON(); for (const item of items) { @@ -494,7 +505,7 @@ class EggApplication extends EggCore { this.coreLogger.error(`unfinished timing item: ${CircularJSON.stringify(item)}`); } this.coreLogger.error(`check run/${this.type}_timing_${process.pid}.json for more details.`); - this.emit('startTimeout'); + this.emit("startTimeout"); this.dumpConfig(); this.dumpTiming(); }, this.config.workerStartTimeout); @@ -506,21 +517,24 @@ class EggApplication extends EggCore { * @deprecated */ get env() { - this.deprecate('please use app.config.env instead'); + this.deprecate("please use app.config.env instead"); return this.config.env; } - /* eslint no-empty-function: off */ - set env(_) { } + set env(_) { + // no-op, deprecated setter + } /** * app.proxy delegate app.config.proxy * @deprecated */ get proxy() { - this.deprecate('please use app.config.proxy instead'); + this.deprecate("please use app.config.proxy instead"); return this.config.proxy; } - set proxy(_) { } + set proxy(_) { + // no-op, deprecated setter + } /** * create a singleton instance @@ -561,26 +575,26 @@ class EggApplication extends EggCore { createAnonymousContext(req) { const request = { headers: { - host: '127.0.0.1', - 'x-forwarded-for': '127.0.0.1', + host: "127.0.0.1", + "x-forwarded-for": "127.0.0.1", }, query: {}, - querystring: '', - host: '127.0.0.1', - hostname: '127.0.0.1', - protocol: 'http', - secure: 'false', - method: 'GET', - url: '/', - path: '/', + querystring: "", + host: "127.0.0.1", + hostname: "127.0.0.1", + protocol: "http", + secure: "false", + method: "GET", + url: "/", + path: "/", socket: { - remoteAddress: '127.0.0.1', + remoteAddress: "127.0.0.1", remotePort: 7001, }, }; if (req) { for (const key in req) { - if (key === 'headers' || key === 'query' || key === 'socket') { + if (key === "headers" || key === "query" || key === "socket") { Object.assign(request[key], req[key]); } else { request[key] = req[key]; @@ -601,8 +615,8 @@ class EggApplication extends EggCore { createContext(req, res) { const app = this; const context = Object.create(app.context); - const request = context.request = Object.create(app.request); - const response = context.response = Object.create(app.response); + const request = (context.request = Object.create(app.request)); + const response = (context.response = Object.create(app.response)); context.app = request.app = response.app = app; context.req = request.req = response.req = req; context.res = request.res = response.res = res; @@ -627,7 +641,6 @@ class EggApplication extends EggCore { } return context; } - } module.exports = EggApplication; diff --git a/lib/loader/agent_worker_loader.js b/lib/loader/agent_worker_loader.js index abf4c3bde1..b1b4fac89b 100644 --- a/lib/loader/agent_worker_loader.js +++ b/lib/loader/agent_worker_loader.js @@ -1,13 +1,12 @@ -'use strict'; +"use strict"; -const EggLoader = require('egg-core').EggLoader; +const EggLoader = require("egg-core").EggLoader; /** * Agent worker process loader * @see https://github.com/eggjs/egg-loader */ class AgentWorkerLoader extends EggLoader { - /** * loadPlugin first, then loadConfig */ diff --git a/lib/loader/app_worker_loader.js b/lib/loader/app_worker_loader.js index f2de253de3..b9dc438c4e 100644 --- a/lib/loader/app_worker_loader.js +++ b/lib/loader/app_worker_loader.js @@ -1,13 +1,12 @@ -'use strict'; +"use strict"; -const EggLoader = require('egg-core').EggLoader; +const EggLoader = require("egg-core").EggLoader; /** * App worker process Loader, will load plugins * @see https://github.com/eggjs/egg-loader */ class AppWorkerLoader extends EggLoader { - /** * loadPlugin first, then loadConfig * @since 1.0.0 @@ -42,7 +41,6 @@ class AppWorkerLoader extends EggLoader { // app this.loadRouter(); // Depend on controllers } - } module.exports = AppWorkerLoader; diff --git a/lib/loader/index.js b/lib/loader/index.js index 8c4e7c979d..8a275b31fd 100644 --- a/lib/loader/index.js +++ b/lib/loader/index.js @@ -1,5 +1,5 @@ -'use strict'; +"use strict"; -exports.EggLoader = require('egg-core').EggLoader; -exports.AppWorkerLoader = require('./app_worker_loader'); -exports.AgentWorkerLoader = require('./agent_worker_loader'); +exports.EggLoader = require("egg-core").EggLoader; +exports.AppWorkerLoader = require("./app_worker_loader"); +exports.AgentWorkerLoader = require("./agent_worker_loader"); diff --git a/lib/start.js b/lib/start.js index 28dde70ab3..83fae78274 100644 --- a/lib/start.js +++ b/lib/start.js @@ -1,16 +1,15 @@ -'use strict'; +"use strict"; -const path = require('node:path'); +const path = require("node:path"); module.exports = async (options = {}) => { - options.baseDir = options.baseDir || process.cwd(); - options.mode = 'single'; + options.mode = "single"; // get agent from options.framework and package.egg.framework if (!options.framework) { try { - options.framework = require(path.join(options.baseDir, 'package.json')).egg.framework; + options.framework = require(path.join(options.baseDir, "package.json")).egg.framework; } catch { // ignore } @@ -21,8 +20,8 @@ module.exports = async (options = {}) => { Agent = require(options.framework).Agent; Application = require(options.framework).Application; } else { - Application = require('./application'); - Agent = require('./agent'); + Application = require("./application"); + Agent = require("./agent"); } const agent = new Agent(Object.assign({}, options)); @@ -33,7 +32,7 @@ module.exports = async (options = {}) => { await application.ready(); // emit egg-ready message in agent and application - application.messenger.broadcast('egg-ready'); + application.messenger.broadcast("egg-ready"); return application; }; diff --git a/package.json b/package.json index 0fa5e7e782..09f883d435 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,54 @@ { "name": "egg", "version": "3.34.0", - "publishConfig": { - "tag": "release-3.x", - "access": "public" - }, "description": "A web framework's framework for Node.js", "keywords": [ - "web", "app", - "http", "application", + "egg", "framework", - "middleware", + "http", "koa", - "egg" + "middleware", + "web" + ], + "homepage": "https://github.com/eggjs/egg", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/eggjs/egg.git" + }, + "files": [ + "index.js", + "lib", + "app", + "config", + "agent.js", + "index.d.ts" ], + "main": "index.js", + "types": "index.d.ts", + "publishConfig": { + "access": "public", + "tag": "release-3.x" + }, + "scripts": { + "lint": "vp lint app config lib test *.js", + "tsd": "tsd", + "test": "npm run lint -- --fix && npm run tsd && npm run test-local", + "test-local": "egg-bin test --ts false", + "test-local-changed": "egg-bin test --changed --ts false", + "cov": "egg-bin cov --timeout 100000 --ts false", + "ci": "npm run lint && npm run tsd && npm run cov", + "site:dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider APP_ROOT=./site dumi dev", + "site:devWithNode14-16": "cross-env APP_ROOT=./site dumi dev", + "site:build": "cross-env NODE_OPTIONS=--openssl-legacy-provider APP_ROOT=./site dumi build", + "site:buildWithNode14-16": "cross-env APP_ROOT=./site dumi build", + "site:prettier": "prettier --config site/.prettierrc --ignore-path site/.prettierignore --write \"site/**/*.{js,jsx,tsx,ts,less,md,json}\"", + "puml": "puml . --dest ./site", + "commits": "./scripts/commits.sh", + "prepare": "vp config" + }, "dependencies": { "@types/accepts": "^1.3.5", "@types/koa": "^2.13.5", @@ -62,6 +95,9 @@ }, "devDependencies": { "@eggjs/tsconfig": "^1.1.0", + "@eslint/compat": "^2.0.3", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "^9.39.4", "@types/node": "^20.1.2", "@umijs/preset-react": "^2.1.6", "address": "^1.2.1", @@ -76,13 +112,12 @@ "egg-plugin-puml": "^2.4.0", "egg-tracer": "^2.0.0", "egg-view-nunjucks": "^2.3.0", - "@eslint/compat": "^2.0.3", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "^9.39.4", - "eslint": "^9.39.4", "eslint-config-egg": "^14.1.0", - "globals": "^16.2.0", + "eslint-plugin-eggache": "^2.0.0", + "eslint-plugin-jsdoc": "^62.7.1", + "eslint-plugin-node": "^11.1.0", "formstream": "^1.1.1", + "globals": "^16.2.0", "jsdoc": "^3.6.11", "koa": "^2.13.4", "koa-static": "^5.0.0", @@ -99,41 +134,17 @@ "ts-node": "^10.9.1", "tsd": "^0.28.1", "typescript": "^5.0.4", - "umi": "^3.5.36" - }, - "main": "index.js", - "types": "index.d.ts", - "files": [ - "index.js", - "lib", - "app", - "config", - "agent.js", - "index.d.ts" - ], - "scripts": { - "lint": "eslint app config lib test *.js", - "tsd": "tsd", - "test": "npm run lint -- --fix && npm run tsd && npm run test-local", - "test-local": "egg-bin test --ts false", - "test-local-changed": "egg-bin test --changed --ts false", - "cov": "egg-bin cov --timeout 100000 --ts false", - "ci": "npm run lint && npm run tsd && npm run cov", - "site:dev": "cross-env NODE_OPTIONS=--openssl-legacy-provider APP_ROOT=./site dumi dev", - "site:devWithNode14-16": "cross-env APP_ROOT=./site dumi dev", - "site:build": "cross-env NODE_OPTIONS=--openssl-legacy-provider APP_ROOT=./site dumi build", - "site:buildWithNode14-16": "cross-env APP_ROOT=./site dumi build", - "site:prettier": "prettier --config site/.prettierrc --ignore-path site/.prettierignore --write \"site/**/*.{js,jsx,tsx,ts,less,md,json}\"", - "puml": "puml . --dest ./site", - "commits": "./scripts/commits.sh" - }, - "homepage": "https://github.com/eggjs/egg", - "repository": { - "type": "git", - "url": "git+https://github.com/eggjs/egg.git" + "umi": "^3.5.36", + "vite-plus": "latest" }, "engines": { "node": ">= 14.20.0" }, - "license": "MIT" + "packageManager": "pnpm@10.31.0", + "pnpm": { + "overrides": { + "vite": "npm:@voidzero-dev/vite-plus-core@latest", + "vitest": "npm:@voidzero-dev/vite-plus-test@latest" + } + } } diff --git a/site/app.ts b/site/app.ts index 2b5d6c2152..910775fbcc 100644 --- a/site/app.ts +++ b/site/app.ts @@ -1,20 +1,20 @@ // @ts-ignore -import { history, Route } from 'umi'; +import { history, Route } from "umi"; export function onRouteChange(props: any) { const { location }: RouterChangeProps = props; let pathname = location.pathname; - if (pathname.startsWith('/en')) { - pathname = pathname.replace('/en', ''); - pathname = pathname.replace('.html', ''); + if (pathname.startsWith("/en")) { + pathname = pathname.replace("/en", ""); + pathname = pathname.replace(".html", ""); history.push(pathname); } - if (pathname.startsWith('/zh-cn')) { - pathname = pathname.replace('zh-cn', 'zh-CN'); - pathname = pathname.replace('.html', ''); + if (pathname.startsWith("/zh-cn")) { + pathname = pathname.replace("zh-cn", "zh-CN"); + pathname = pathname.replace(".html", ""); history.push(pathname); } } diff --git a/site/config/config.ts b/site/config/config.ts index 649551afb0..70228f2081 100644 --- a/site/config/config.ts +++ b/site/config/config.ts @@ -1,13 +1,13 @@ -import { defineConfig } from 'dumi'; +import { defineConfig } from "dumi"; export default defineConfig({ - mode: 'site', - title: 'Egg', + mode: "site", + title: "Egg", - description: 'Born to build better enterprise frameworks and apps', + description: "Born to build better enterprise frameworks and apps", - logo: '/logo.svg', - favicon: '/favicon.png', + logo: "/logo.svg", + favicon: "/favicon.png", // algolia: { // apiKey: '1561de31a86f79507ea00cdb54ce647c', @@ -15,60 +15,60 @@ export default defineConfig({ // }, theme: { - '@c-primary': '#22ab28', + "@c-primary": "#22ab28", }, exportStatic: {}, sitemap: { - hostname: 'https://v3.eggjs.org', + hostname: "https://v3.eggjs.org", }, navs: { - 'en-US': [ + "en-US": [ null, { - title: 'GitHub', - path: 'https://github.com/eggjs/egg', + title: "GitHub", + path: "https://github.com/eggjs/egg", }, { - title: 'Release', - path: 'https://github.com/eggjs/egg/releases', + title: "Release", + path: "https://github.com/eggjs/egg/releases", }, { - title: 'Plugins', - path: 'https://github.com/search?q=topic%3Aegg-plugin&type=Repositories', + title: "Plugins", + path: "https://github.com/search?q=topic%3Aegg-plugin&type=Repositories", }, { - title: 'v3.x', - path: 'https://v3.eggjs.org', + title: "v3.x", + path: "https://v3.eggjs.org", }, { - title: 'v4.x', - path: 'https://eggjs.org', + title: "v4.x", + path: "https://eggjs.org", }, ], - 'zh-CN': [ + "zh-CN": [ null, { - title: 'GitHub', - path: 'https://github.com/eggjs/egg', + title: "GitHub", + path: "https://github.com/eggjs/egg", }, { - title: 'ๅ‘ๅธƒๆ—ฅๅฟ—', - path: 'https://github.com/eggjs/egg/releases', + title: "ๅ‘ๅธƒๆ—ฅๅฟ—", + path: "https://github.com/eggjs/egg/releases", }, { - title: 'ๆ’ไปถๅˆ—่กจ', - path: 'https://github.com/search?q=topic%3Aegg-plugin&type=Repositories', + title: "ๆ’ไปถๅˆ—่กจ", + path: "https://github.com/search?q=topic%3Aegg-plugin&type=Repositories", }, { - title: 'v3.x', - path: 'https://v3.eggjs.org', + title: "v3.x", + path: "https://v3.eggjs.org", }, { - title: 'v4.x', - path: 'https://eggjs.org', + title: "v4.x", + path: "https://eggjs.org", }, ], }, @@ -76,49 +76,49 @@ export default defineConfig({ themeConfig: { links: [ { - title: 'Resources', + title: "Resources", list: [ { - name: 'Egg', - url: 'https://github.com/eggjs/egg', + name: "Egg", + url: "https://github.com/eggjs/egg", }, { - name: 'Organization', - url: 'https://github.com/eggjs', + name: "Organization", + url: "https://github.com/eggjs", }, ], }, { - title: 'XTech', + title: "XTech", list: [ - { name: 'EggJS - ไผไธš็บง Node.js ๅผ€ๅ‘ๆก†ๆžถ', url: 'https://eggjs.org' }, - { name: 'Ant Design - UI ไฝ“็ณป', url: 'https://ant.design' }, - { name: 'AntV - ๆ•ฐๆฎๅฏ่ง†ๅŒ–', url: 'https://antv.vision' }, + { name: "EggJS - ไผไธš็บง Node.js ๅผ€ๅ‘ๆก†ๆžถ", url: "https://eggjs.org" }, + { name: "Ant Design - UI ไฝ“็ณป", url: "https://ant.design" }, + { name: "AntV - ๆ•ฐๆฎๅฏ่ง†ๅŒ–", url: "https://antv.vision" }, { - name: '่ฏญ้›€ - ็Ÿฅ่ฏ†ๅˆ›ไฝœไธŽๅˆ†ไบซๅทฅๅ…ท', - url: 'https://www.yuque.com', + name: "่ฏญ้›€ - ็Ÿฅ่ฏ†ๅˆ›ไฝœไธŽๅˆ†ไบซๅทฅๅ…ท", + url: "https://www.yuque.com", }, ], }, { - title: 'Community', + title: "Community", list: [ - { name: 'Artus.js ๅฎ˜็ฝ‘', url: 'https://artusjs.org' }, - { name: 'CNode ็คพๅŒบ', url: 'https://cnodejs.org/' }, - { name: 'Node.js ไธ“ๆ ', url: 'https://www.yuque.com/egg/nodejs' }, + { name: "Artus.js ๅฎ˜็ฝ‘", url: "https://artusjs.org" }, + { name: "CNode ็คพๅŒบ", url: "https://cnodejs.org/" }, + { name: "Node.js ไธ“ๆ ", url: "https://www.yuque.com/egg/nodejs" }, { - name: 'ๆไบคๅ้ฆˆ', - url: 'https://github.com/eggjs/egg/issues', + name: "ๆไบคๅ้ฆˆ", + url: "https://github.com/eggjs/egg/issues", }, - { name: 'ๅ‘ๅธƒๆ—ฅๅฟ—', url: 'https://github.com/eggjs/egg/releases' }, + { name: "ๅ‘ๅธƒๆ—ฅๅฟ—", url: "https://github.com/eggjs/egg/releases" }, ], }, { - title: 'Egg.js Telegram Channel', + title: "Egg.js Telegram Channel", list: [ { - name: '้’‰้’‰', - qrcode: '/img_egg/qrcode_egg_channel.png', + name: "้’‰้’‰", + qrcode: "/img_egg/qrcode_egg_channel.png", }, ], }, diff --git a/site/docs/advanced/cluster-client.md b/site/docs/advanced/cluster-client.md index bbe6b834f2..084f21ec03 100644 --- a/site/docs/advanced/cluster-client.md +++ b/site/docs/advanced/cluster-client.md @@ -70,7 +70,7 @@ We abstract the client interface into the following two broad categories, which Client example ```js -const Base = require('sdk-base'); +const Base = require("sdk-base"); class Client extends Base { constructor(options) { @@ -168,14 +168,14 @@ In the following I will use a simple example to introduce how to make a client s ```js // registry_client.js -const URL = require('url'); -const Base = require('sdk-base'); +const URL = require("url"); +const Base = require("sdk-base"); class RegistryClient extends Base { constructor(options) { super({ // Specify a method for asynchronous start - initMethod: 'init', + initMethod: "init", }); this._options = options; this._registered = new Map(); @@ -249,7 +249,7 @@ module.exports = RegistryClient; ```js // agent.js -const RegistryClient = require('registry_client'); +const RegistryClient = require("registry_client"); module.exports = (agent) => { // encapsulate and instantiate RegistryClient @@ -259,7 +259,7 @@ module.exports = (agent) => { agent.beforeStart(async () => { await agent.registryClient.ready(); - agent.coreLogger.info('registry client is ready'); + agent.coreLogger.info("registry client is ready"); }); }; ``` @@ -268,18 +268,18 @@ module.exports = (agent) => { ```js // app.js -const RegistryClient = require('registry_client'); +const RegistryClient = require("registry_client"); module.exports = (app) => { app.registryClient = app.cluster(RegistryClient).create({}); app.beforeStart(async () => { await app.registryClient.ready(); - app.coreLogger.info('registry client is ready'); + app.coreLogger.info("registry client is ready"); // invoke subscribe to subscribe app.registryClient.subscribe( { - dataId: 'demo.DemoService', + dataId: "demo.DemoService", }, (val) => { // ... @@ -288,12 +288,12 @@ module.exports = (app) => { // invoke publish to publsih data app.registryClient.publish({ - dataId: 'demo.DemoService', - publishData: 'xxx', + dataId: "demo.DemoService", + publishData: "xxx", }); // invoke getConfig interface - const res = await app.registryClient.getConfig('demo.DemoService'); + const res = await app.registryClient.getConfig("demo.DemoService"); console.log(res); }); }; @@ -339,7 +339,7 @@ module.exports = (agent) => { agent.mockClient = agent .cluster(MockClient) // delegate sub to logic of subscribe - .delegate('sub', 'subscribe') + .delegate("sub", "subscribe") .create(); agent.beforeStart(async () => { @@ -354,13 +354,13 @@ module.exports = (app) => { app.mockClient = app .cluster(MockClient) // delegate sub to subscribe logic - .delegate('sub', 'subscribe') + .delegate("sub", "subscribe") .create(); app.beforeStart(async () => { await app.mockClient.ready(); - app.sub({ id: 'test-id' }, (val) => { + app.sub({ id: "test-id" }, (val) => { // put your code here }); }); @@ -384,8 +384,8 @@ For example, add a synchronous get method with buffer in the `APIClient` module: ```js // some-client/index.js -const cluster = require('cluster-client'); -const RegistryClient = require('./registry_client'); +const cluster = require("cluster-client"); +const RegistryClient = require("./registry_client"); class APIClient extends Base { constructor(options) { @@ -454,8 +454,8 @@ exports.apiClient = { To make it easy for you to encapsulate `APIClient`, we provide an` APIClientBase` base class in the [cluster-client](https://www.npmjs.com/package/cluster-client) module. Then `APIClient` above can be rewritten as: ```js -const APIClientBase = require('cluster-client').APIClientBase; -const RegistryClient = require('./registry_client'); +const APIClientBase = require("cluster-client").APIClientBase; +const RegistryClient = require("./registry_client"); class APIClient extends APIClientBase { // return the original client class @@ -537,8 +537,8 @@ app.registryClient = app - You can also override the `getter` attribute of `clusterOptions` in `APIClientBase`: ```js -const APIClientBase = require('cluster-client').APIClientBase; -const RegistryClient = require('./registry_client'); +const APIClientBase = require("cluster-client").APIClientBase; +const RegistryClient = require("./registry_client"); class APIClient extends APIClientBase { get DataClient() { diff --git a/site/docs/advanced/cluster-client.zh-CN.md b/site/docs/advanced/cluster-client.zh-CN.md index 9e6ba1a33a..3b460fe474 100644 --- a/site/docs/advanced/cluster-client.zh-CN.md +++ b/site/docs/advanced/cluster-client.zh-CN.md @@ -23,6 +23,7 @@ order: 4 ๅฆๅค–๏ผŒ้€š่ฟ‡ messenger ไผ ้€’ๆ•ฐๆฎๆ•ˆ็އ่พƒไฝŽ๏ผŒๅ› ไธบๅฎƒไผš้€š่ฟ‡ Master ๆฅๅšไธญ่ฝฌ๏ผ›ไธ‡ไธ€ IPC ้€š้“ๅ‡บ็Žฐ้—ฎ้ข˜๏ผŒ่ฟ˜ๅฏ่ƒฝๆŠŠ Master ่ฟ›็จ‹ๅผ„ๆŒ‚ใ€‚ ้‚ฃไนˆๆœ‰ๆฒกๆœ‰ๆ›ดๅฅฝ็š„ๆ–นๆณ•ๅ‘ข๏ผŸ็ญ”ๆกˆๆ˜ฏ่‚ฏๅฎš็š„๏ผŒๆˆ‘ไปฌๆไพ›ไบ†ไธ€็งๆ–ฐ็š„ๆจกๅผๆฅ้™ไฝŽ่ฟ™็ฑปๅฎขๆˆท็ซฏๅฐ่ฃ…็š„ๅคๆ‚ๅบฆใ€‚้€š่ฟ‡ๅปบ็ซ‹ Agent ๅ’Œ Worker ็š„ socket ็›ด่ฟž๏ผŒ่ทณ่ฟ‡ Master ็š„ไธญ่ฝฌ๏ผŒAgent ไฝœไธบๅฏนๅค–็š„้—จ้ข๏ผŒ็ปดๆŒๅคšไธช Worker ่ฟ›็จ‹็š„ๅ…ฑไบซ่ฟžๆŽฅใ€‚ + ## ๆ ธๅฟƒๆ€ๆƒณ - ๅ—ๅˆฐ [Leader/Follower](https://www.dre.vanderbilt.edu/~schmidt/PDF/lf.pdf) ๆจกๅผ็š„ๅฏๅ‘ใ€‚ @@ -56,6 +57,7 @@ win / +------------------+ \ lose | Client | | Follower(Worker2) | +--------+ +-------------------+ ``` + ## ๅฎขๆˆท็ซฏๆŽฅๅฃ็ฑปๅž‹ๆŠฝ่ฑก ๆˆ‘ไปฌๅฐ†ๅฎขๆˆท็ซฏๆŽฅๅฃๆŠฝ่ฑกไธบไปฅไธ‹ไธคๅคง็ฑป๏ผŒ่ฟ™ไนŸๆ˜ฏๅฏนๅฎขๆˆท็ซฏๆŽฅๅฃ็š„ไธ€ไธช่ง„่Œƒ๏ผŒๅฏนไบŽ็ฌฆๅˆ่ง„่Œƒ็š„ๅฎขๆˆท็ซฏ๏ผŒๆˆ‘ไปฌๅฏไปฅ่‡ชๅŠจๅฐ†ๅ…ถๅŒ…่ฃ…ไธบ Leader/Follower ๆจกๅผใ€‚ @@ -69,7 +71,7 @@ win / +------------------+ \ lose ๅฎขๆˆท็ซฏ็คบไพ‹ ```js -const Base = require('sdk-base'); +const Base = require("sdk-base"); class Client extends Base { constructor(options) { @@ -108,10 +110,12 @@ class Client extends Base { } } ``` + ## ๅผ‚ๅธธๅค„็† - ๅฆ‚ๆžœ Leader ๅฎžไพ‹โ€œๆญปๆމโ€๏ผŒๅฐ†่งฆๅ‘ๆ–ฐไธ€่ฝฎ็š„็ซฏๅฃไบ‰ๅคบใ€‚ไบ‰ๅคบๅˆฐ็ซฏๅฃ็š„ๅฎžไพ‹ๅฐ†่ขซๆŽจไธพไธบๆ–ฐ็š„ Leaderใ€‚ - ไธบไบ†ไฟ่ฏ Leader ๅ’Œ Follower ไน‹้—ด้€š้“็š„ๅฅๅบท๏ผŒ้œ€่ฆๅผ•ๅ…ฅๅฎšๆ—ถ็š„ๅฟƒ่ทณๆฃ€ๆŸฅๆœบๅˆถใ€‚ๅฆ‚ๆžœ Follower ๅœจๅ›บๅฎšๆ—ถ้—ดๅ†…ๆœชๅ‘้€ๅฟƒ่ทณๅŒ…๏ผŒLeader ไผšๅฐ†ๅ…ถไธปๅŠจๆ–ญๅผ€๏ผŒไปฅ่งฆๅ‘ Follower ็š„้‡ๆ–ฐๅˆๅง‹ๅŒ–ใ€‚ + ## ๅ่ฎฎๅ’Œ่ฐƒ็”จๆ—ถๅบ Leader ๅ’Œ Follower ้€š่ฟ‡ไธ‹้ข็š„ๅ่ฎฎ่ฟ›่กŒๆ•ฐๆฎไบคๆข๏ผš @@ -157,6 +161,7 @@ Leader ๅ’Œ Follower ้€š่ฟ‡ไธ‹้ข็š„ๅ่ฎฎ่ฟ›่กŒๆ•ฐๆฎไบคๆข๏ผš | <------------------------------------------------ + | | ``` + ## ๅ…ทไฝ“็š„ไฝฟ็”จๆ–นๆณ• ไธ‹้ขๆˆ‘็”จไธ€ไธช็ฎ€ๅ•็š„ไพ‹ๅญ๏ผŒไป‹็ปๅœจๆก†ๆžถ้‡Œ้ขๅฆ‚ไฝ•่ฎฉไธ€ไธชๅฎขๆˆท็ซฏๆ”ฏๆŒ Leader/Follower ๆจกๅผ๏ผš @@ -165,14 +170,14 @@ Leader ๅ’Œ Follower ้€š่ฟ‡ไธ‹้ข็š„ๅ่ฎฎ่ฟ›่กŒๆ•ฐๆฎไบคๆข๏ผš ```js // registry_client.js -const URL = require('url'); -const Base = require('sdk-base'); +const URL = require("url"); +const Base = require("sdk-base"); class RegistryClient extends Base { constructor(options) { super({ // ๆŒ‡ๅฎšๅผ‚ๆญฅๅฏๅŠจ็š„ๆ–นๆณ• - initMethod: 'init', + initMethod: "init", }); this._options = options; this._registered = new Map(); @@ -233,7 +238,7 @@ class RegistryClient extends Base { if (changed) { this.emit( key, - this._registered.get(key).map(url => URL.parse(url, true)), + this._registered.get(key).map((url) => URL.parse(url, true)), ); } } @@ -246,9 +251,9 @@ module.exports = RegistryClient; ```js // agent.js -const RegistryClient = require('./registry_client'); +const RegistryClient = require("./registry_client"); -module.exports = agent => { +module.exports = (agent) => { // ๅฏน RegistryClient ่ฟ›่กŒๅฐ่ฃ…ๅ’Œๅฎžไพ‹ๅŒ– agent.registryClient = agent .cluster(RegistryClient) @@ -257,7 +262,7 @@ module.exports = agent => { agent.beforeStart(async () => { await agent.registryClient.ready(); - agent.coreLogger.info('ๆณจๅ†Œๅฎขๆˆท็ซฏๅทฒๅฐฑ็ปช'); + agent.coreLogger.info("ๆณจๅ†Œๅฎขๆˆท็ซฏๅทฒๅฐฑ็ปช"); }); }; ``` @@ -266,32 +271,32 @@ module.exports = agent => { ```js // app.js -const RegistryClient = require('./registry_client'); +const RegistryClient = require("./registry_client"); -module.exports = app => { +module.exports = (app) => { app.registryClient = app.cluster(RegistryClient).create({}); app.beforeStart(async () => { await app.registryClient.ready(); - app.coreLogger.info('ๆณจๅ†Œๅฎขๆˆท็ซฏๅทฒๅฐฑ็ปช'); + app.coreLogger.info("ๆณจๅ†Œๅฎขๆˆท็ซฏๅทฒๅฐฑ็ปช"); // ่ฐƒ็”จ subscribe ่ฟ›่กŒ่ฎข้˜… app.registryClient.subscribe( { - dataId: 'demo.DemoService', + dataId: "demo.DemoService", }, - val => { + (val) => { // ... }, ); // ่ฐƒ็”จ publish ๅ‘ๅธƒๆ•ฐๆฎ app.registryClient.publish({ - dataId: 'demo.DemoService', - publishData: 'xxx', + dataId: "demo.DemoService", + publishData: "xxx", }); // ่ฐƒ็”จ getConfig ่Žทๅ–้…็ฝฎ - const res = await app.registryClient.getConfig('demo.DemoService'); + const res = await app.registryClient.getConfig("demo.DemoService"); console.log(res); }); }; @@ -305,7 +310,7 @@ module.exports = app => { class MockClient extends Base { constructor(options) { super({ - initMethod: 'init', + initMethod: "init", }); this._options = options; this._registered = new Map(); @@ -333,11 +338,11 @@ class MockClient extends Base { ```js // agent.js -module.exports = agent => { +module.exports = (agent) => { agent.mockClient = agent .cluster(MockClient) // ๅฐ† sub ไปฃ็†ๅˆฐ subscribe - .delegate('sub', 'subscribe') + .delegate("sub", "subscribe") .create(); agent.beforeStart(async () => { @@ -348,17 +353,17 @@ module.exports = agent => { ```js // app.js -module.exports = app => { +module.exports = (app) => { app.mockClient = app .cluster(MockClient) // ๅฐ† sub ไปฃ็†ๅˆฐ subscribe - .delegate('sub', 'subscribe') + .delegate("sub", "subscribe") .create(); app.beforeStart(async () => { await app.mockClient.ready(); - app.mockClient.sub({ id: 'test-id' }, val => { + app.mockClient.sub({ id: "test-id" }, (val) => { // ่ฏทๆŠŠไฝ ็š„ไปฃ็ ๆ”พๅœจ่ฟ™้‡Œ }); }); @@ -382,8 +387,8 @@ module.exports = app => { ```js // some-client/index.js -const cluster = require('cluster-client'); -const RegistryClient = require('./registry_client'); +const cluster = require("cluster-client"); +const RegistryClient = require("./registry_client"); class APIClient extends Base { constructor(options) { @@ -403,7 +408,7 @@ class APIClient extends Base { const subMap = options.subMap; for (const key in subMap) { - this.subscribe(subMap[key], value => { + this.subscribe(subMap[key], (value) => { this._cache[key] = value; }); } @@ -430,8 +435,8 @@ module.exports = APIClient; ```js // app.js ๆˆ– agent.js -const APIClient = require('some-client'); // ไธŠๆ–‡ไธญ็š„ๆจกๅ— -module.exports = app => { +const APIClient = require("some-client"); // ไธŠๆ–‡ไธญ็š„ๆจกๅ— +module.exports = (app) => { const config = app.config.apiClient; app.apiClient = new APIClient(Object.assign({}, config, { cluster: app.cluster })); app.beforeStart(async () => { @@ -443,18 +448,18 @@ module.exports = app => { exports.apiClient = { subMap: { foo: { - id: '', + id: "", }, // bar... - } + }, }; ``` ไธบไบ†ๆ–นไพฟไฝ ๅฐ่ฃ… `APIClient`๏ผŒๅœจ `cluster-client` ๆจกๅ—ไธญๆไพ›ไบ†ไธ€ไธช `APIClientBase` ๅŸบ็ฑป๏ผŒ้‚ฃไนˆไธŠๆ–‡ไธญ็š„ `APIClient` ๅฏไปฅๆ”นๅ†™ไธบ๏ผš ```js -const APIClientBase = require('cluster-client').APIClientBase; -const RegistryClient = require('./registry_client'); +const APIClientBase = require("cluster-client").APIClientBase; +const RegistryClient = require("./registry_client"); class APIClient extends APIClientBase { // ่ฟ”ๅ›žๅŽŸๅง‹็š„ๅฎขๆˆท็ซฏ็ฑป @@ -500,6 +505,7 @@ class APIClient extends APIClientBase { - `APIClient` - ๅ†…้ƒจ่ฐƒ็”จ `ClusterClient` ๅšๆ•ฐๆฎๅŒๆญฅ๏ผŒๆ— ้œ€ๅ…ณๅฟƒๅคš่ฟ›็จ‹ๆจกๅž‹๏ผŒ็”จๆˆทๆœ€็ปˆไฝฟ็”จ็š„ๆจกๅ—ใ€‚API ้€š่ฟ‡ๆญคๅค„ๆšด้œฒ๏ผŒๆ”ฏๆŒๅŒๆญฅๅ’Œๅผ‚ๆญฅใ€‚ ๆœ‰ๅ…ด่ถฃ็š„ๅŒๅญฆๅฏไปฅๆŸฅ็œ‹ใ€Šๅขžๅผบๅคš่ฟ›็จ‹็ ”ๅ‘ๆจกๅผใ€‹่ฎจ่ฎบ่ฟ‡็จ‹ใ€‚ + ## ๅœจๆก†ๆžถ้‡Œ้ข cluster-client ็›ธๅ…ณ็š„้…็ฝฎ้กน ```js @@ -514,10 +520,10 @@ config.clusterClient = { }; ``` -| ้…็ฝฎ้กน | ็ฑปๅž‹ | ้ป˜่ฎคๅ€ผ | ๆ่ฟฐ | -| --------------- | -------- | ------------------ | ------------------------------------------------------------------ | -| responseTimeout | number | 60000๏ผˆไธ€ๅˆ†้’Ÿ๏ผ‰ | ๅ…จๅฑ€็š„่ฟ›็จ‹้—ด้€š่ฎฏ็š„่ถ…ๆ—ถๆ—ถ้•ฟ๏ผŒๅ› ไธบไปฃ็†ๆŽฅๅฃๆœฌ่บซไนŸๆœ‰่ถ…ๆ—ถ่ฎพ็ฝฎ๏ผŒๆ‰€ไปฅไธๅฎœ่ฎพ็ฝฎๅคช็Ÿญ | -| transcode | function | ๆœช่ฎพ็ฝฎ๏ผˆN/A๏ผ‰ | ่ฟ›็จ‹้—ด้€š่ฎฏ็š„ๅบๅˆ—ๅŒ–ๆ–นๅผ๏ผŒ้ป˜่ฎคไฝฟ็”จ [serialize-json](https://www.npmjs.com/package/serialize-json)๏ผŒๅปบ่ฎฎไธ่ฆ่‡ช่กŒ่ฎพ็ฝฎ | +| ้…็ฝฎ้กน | ็ฑปๅž‹ | ้ป˜่ฎคๅ€ผ | ๆ่ฟฐ | +| --------------- | -------- | --------------- | ----------------------------------------------------------------------------------------------------------------- | +| responseTimeout | number | 60000๏ผˆไธ€ๅˆ†้’Ÿ๏ผ‰ | ๅ…จๅฑ€็š„่ฟ›็จ‹้—ด้€š่ฎฏ็š„่ถ…ๆ—ถๆ—ถ้•ฟ๏ผŒๅ› ไธบไปฃ็†ๆŽฅๅฃๆœฌ่บซไนŸๆœ‰่ถ…ๆ—ถ่ฎพ็ฝฎ๏ผŒๆ‰€ไปฅไธๅฎœ่ฎพ็ฝฎๅคช็Ÿญ | +| transcode | function | ๆœช่ฎพ็ฝฎ๏ผˆN/A๏ผ‰ | ่ฟ›็จ‹้—ด้€š่ฎฏ็š„ๅบๅˆ—ๅŒ–ๆ–นๅผ๏ผŒ้ป˜่ฎคไฝฟ็”จ [serialize-json](https://www.npmjs.com/package/serialize-json)๏ผŒๅปบ่ฎฎไธ่ฆ่‡ช่กŒ่ฎพ็ฝฎ | ไธŠ่ฟฐ่กจๆ ผไธบๅ…จๅฑ€้…็ฝฎๆ–นๅผใ€‚ๅฆ‚ๆžœไฝ ๆƒณไธบ็‰นๅฎšๅฎขๆˆท็ซฏๅ•็‹ฌ่ฎพ็ฝฎ๏ผŒๅฏไปฅไฝฟ็”จไปฅไธ‹ๆ–นๆณ•๏ผš @@ -536,8 +542,8 @@ app.registryClient = app - ไนŸๅฏไปฅ้€š่ฟ‡่ฆ†็›– `APIClientBase` ็š„ `clusterOptions` ่ฟ™ไธช `getter` ๅฑžๆ€งใ€‚ ```js -const APIClientBase = require('cluster-client').APIClientBase; -const RegistryClient = require('./registry_client'); +const APIClientBase = require("cluster-client").APIClientBase; +const RegistryClient = require("./registry_client"); class APIClient extends APIClientBase { get DataClient() { @@ -554,4 +560,4 @@ class APIClient extends APIClientBase { } module.exports = APIClient; -``` \ No newline at end of file +``` diff --git a/site/docs/advanced/framework.md b/site/docs/advanced/framework.md index 3eb3e8c91f..bb99f7c056 100644 --- a/site/docs/advanced/framework.md +++ b/site/docs/advanced/framework.md @@ -64,16 +64,16 @@ Each of those APIs is required to be implemented almost twice - one for Agent an This is the entry function of Egg's multiprocess launcher, based on [egg-cluster](https://github.com/eggjs/egg-cluster), to start Master, but EggCore running in a single process doesn't invoke this function while Egg does. ```js -const startCluster = require('egg').startCluster; +const startCluster = require("egg").startCluster; startCluster( { // directory of code - baseDir: '/path/to/app', + baseDir: "/path/to/app", // directory of framework - framework: '/path/to/framework', + framework: "/path/to/framework", }, () => { - console.log('app started'); + console.log("app started"); }, ); ``` @@ -145,26 +145,26 @@ Given a triple-layer framework: department level > enterprise level > Egg ```js // enterprise -const Application = require('egg').Application; +const Application = require("egg").Application; class Enterprise extends Application { get [EGG_PATH]() { - return '/path/to/enterprise'; + return "/path/to/enterprise"; } } // Customize Application exports.Application = Enterprise; // department -const Application = require('enterprise').Application; +const Application = require("enterprise").Application; // extend enterprise's Application class department extends Application { get [EGG_PATH]() { - return '/path/to/department'; + return "/path/to/department"; } } // the path of `department` have to be designated as described above -const Application = require('department').Application; +const Application = require("department").Application; const app = new Application(); app.ready(); ``` @@ -177,9 +177,9 @@ Egg's mutilprocess model is composed of Application and Agent. Therefore Agent, ```js // lib/framework.js -const path = require('path'); -const egg = require('egg'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const path = require("path"); +const egg = require("egg"); +const EGG_PATH = Symbol.for("egg#eggPath"); class Application extends egg.Application { get [EGG_PATH]() { @@ -211,9 +211,9 @@ As the same as Egg-Path, Loader exposes itself at `Symbol.for('egg#loader')` to ```js // lib/framework.js -const path = require('path'); -const egg = require('egg'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const path = require("path"); +const egg = require("egg"); +const EGG_PATH = Symbol.for("egg#eggPath"); class YadanAppWorkerLoader extends egg.AppWorkerLoader { load() { @@ -268,13 +268,13 @@ You'd better read [unittest](../core/unittest.md) first, which is similiar to fr Here are some differences between initiation of frameworks. ```js -const mock = require('egg-mock'); -describe('test/index.test.js', () => { +const mock = require("egg-mock"); +describe("test/index.test.js", () => { let app; before(() => { app = mock.app({ // test/fixtures/apps/example - baseDir: 'apps/example', + baseDir: "apps/example", // importent !! Do not miss framework: true, }); @@ -284,8 +284,8 @@ describe('test/index.test.js', () => { after(() => app.close()); afterEach(mock.restore); - it('should success', () => { - return app.httpRequest().get('/').expect(200); + it("should success", () => { + return app.httpRequest().get("/").expect(200); }); }); ``` @@ -301,24 +301,24 @@ describe('test/index.test.js', () => { `mm.app` enables cache as default, which means new envoriment setting would not work once loaded. ```js -const mock = require('egg-mock'); -describe('/test/index.test.js', () => { +const mock = require("egg-mock"); +describe("/test/index.test.js", () => { let app; afterEach(() => app.close()); - it('should test on local', () => { - mock.env('local'); + it("should test on local", () => { + mock.env("local"); app = mock.app({ - baseDir: 'apps/example', + baseDir: "apps/example", framework: true, cache: false, }); return app.ready(); }); - it('should test on prod', () => { - mock.env('prod'); + it("should test on prod", () => { + mock.env("prod"); app = mock.app({ - baseDir: 'apps/example', + baseDir: "apps/example", framework: true, cache: false, }); @@ -334,20 +334,20 @@ Mutilprocess is rarely tested because of the high cost and the unavailability of The option of `mock.cluster` have no difference with `mm.app` while their APIs are totally distinct, however, SuperTest still works. ```js -const mock = require('egg-mock'); -describe('/test/index.test.js', () => { +const mock = require("egg-mock"); +describe("/test/index.test.js", () => { let app; before(() => { app = mock.cluster({ - baseDir: 'apps/example', + baseDir: "apps/example", framework: true, }); return app.ready(); }); after(() => app.close()); afterEach(mock.restore); - it('should success', () => { - return app.httpRequest().get('/').expect(200); + it("should success", () => { + return app.httpRequest().get("/").expect(200); }); }); ``` @@ -355,20 +355,20 @@ describe('/test/index.test.js', () => { Tests of `stdout/stderr` are also avaiable, since `mm.cluster` is based on [coffee](https://github.com/popomore/coffee) in which multiprocess testing is supported. ```js -const mock = require('egg-mock'); -describe('/test/index.test.js', () => { +const mock = require("egg-mock"); +describe("/test/index.test.js", () => { let app; before(() => { app = mock.cluster({ - baseDir: 'apps/example', + baseDir: "apps/example", framework: true, }); return app.ready(); }); after(() => app.close()); - it('should get `started`', () => { + it("should get `started`", () => { // set the expectation of console - app.expect('stdout', /started/); + app.expect("stdout", /started/); }); }); ``` diff --git a/site/docs/advanced/framework.zh-CN.md b/site/docs/advanced/framework.zh-CN.md index 99dc71efac..ed0a4308ba 100644 --- a/site/docs/advanced/framework.zh-CN.md +++ b/site/docs/advanced/framework.zh-CN.md @@ -41,6 +41,7 @@ EggCore ๅฏไปฅ็œ‹ๅšๆ˜ฏ Koa `Application` ็š„ๅ‡็บง็‰ˆ๏ผŒ้ป˜่ฎคๅ†…็ฝฎไบ† [Loader ^ ^ agent worker app worker ``` + ## ๅฆ‚ไฝ•ๅฎšๅˆถไธ€ไธชๆก†ๆžถ ไฝ ๅฏไปฅ็›ดๆŽฅ้€š่ฟ‡ [egg-boilerplate-framework](https://github.com/eggjs/egg-boilerplate-framework) ่„šๆ‰‹ๆžถๅฟซ้€ŸไธŠๆ‰‹ใ€‚ @@ -63,15 +64,18 @@ Egg ๆก†ๆžถๆไพ›ไบ†ไธ€ไบ› API๏ผŒๆ‰€ๆœ‰็ปงๆ‰ฟ็š„ๆก†ๆžถ้ƒฝ้œ€่ฆๆไพ›๏ผŒๅชๅขžไธ Egg ็š„ๅคš่ฟ›็จ‹ๅฏๅŠจๅ™จ๏ผŒ้€š่ฟ‡่ฟ™ไธชๆ–นๆณ•ๆฅๅฏๅŠจ Master๏ผŒไธป่ฆ็š„ๅŠŸ่ƒฝๅฎž็Žฐๅœจ [egg-cluster](https://github.com/eggjs/egg-cluster) ไธŠใ€‚ๅ› ๆญค๏ผŒ็›ดๆŽฅไฝฟ็”จ EggCore ๆ˜ฏๅ•่ฟ›็จ‹ๆ–นๅผๅฏๅŠจ็š„๏ผŒ่€Œ Egg ๅฎž็Žฐไบ†ๅคš่ฟ›็จ‹ๆจกๅผใ€‚ ```js -const startCluster = require('egg').startCluster; -startCluster({ +const startCluster = require("egg").startCluster; +startCluster( + { // ๅบ”็”จ็š„ไปฃ็ ็›ฎๅฝ• - baseDir: '/path/to/app', + baseDir: "/path/to/app", // ้œ€่ฆ้€š่ฟ‡่ฟ™ไธชๅ‚ๆ•ฐๆฅๆŒ‡ๅฎšๆก†ๆžถ็›ฎๅฝ• - framework: '/path/to/framework', -}, () => { - console.log('app started'); -}); + framework: "/path/to/framework", + }, + () => { + console.log("app started"); + }, +); ``` ๆ‰€ๆœ‰ๅ‚ๆ•ฐๅฏไปฅๆŸฅ็œ‹ [egg-cluster](https://github.com/eggjs/egg-cluster#options)ใ€‚ @@ -145,26 +149,26 @@ module.exports = Object.assign(egg, { ```js // enterprise -const Application = require('egg').Application; +const Application = require("egg").Application; class EnterpriseApplication extends Application { get [EGG_PATH]() { - return '/path/to/enterprise'; + return "/path/to/enterprise"; } } // ่‡ชๅฎšไน‰ๆจกๅ—็š„ Application exports.Application = EnterpriseApplication; // department -const EnterpriseApplication = require('enterprise').Application; +const EnterpriseApplication = require("enterprise").Application; // ็ปงๆ‰ฟ่‡ช enterprise ็š„ Application class DepartmentApplication extends EnterpriseApplication { get [EGG_PATH]() { - return '/path/to/department'; + return "/path/to/department"; } } // ๅฏๅŠจๆ—ถ้œ€่ฆไผ ๅ…ฅ department ็š„ๆก†ๆžถ่ทฏๅพ„ -const DepartmentApplication = require('department').Application; +const DepartmentApplication = require("department").Application; const app = new DepartmentApplication(); app.ready(); ``` @@ -178,9 +182,9 @@ app.ready(); ```js // lib/framework.js -const path = require('path'); -const egg = require('egg'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const path = require("path"); +const egg = require("egg"); +const EGG_PATH = Symbol.for("egg#eggPath"); class Application extends egg.Application { get [EGG_PATH]() { @@ -212,9 +216,9 @@ Loader ๆ˜ฏๅบ”็”จๅฏๅŠจ็š„ๆ ธๅฟƒใ€‚ๅˆฉ็”จๅฎƒ๏ผŒๆˆ‘ไปฌไธไป…่ƒฝ่ง„่Œƒๅบ”็”จไปฃ็  ```js // lib/framework.js -const path = require('path'); -const egg = require('egg'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const path = require("path"); +const egg = require("egg"); +const EGG_PATH = Symbol.for("egg#eggPath"); class YadanAppWorkerLoader extends egg.AppWorkerLoader { load() { @@ -259,6 +263,7 @@ AgentWorkerLoader ็š„ๆ‰ฉๅฑ•ไนŸ็ฑปไผผ๏ผŒ่ฟ™้‡Œไธๅ†่ต˜่ฟฐใ€‚AgentWorkerLoader - ๅ•ไธช App Worker ้€š่ฟ‡ framework ๆ‰พๅˆฐๆก†ๆžถ็›ฎๅฝ•๏ผŒๅฎžไพ‹ๅŒ–่ฏฅๆก†ๆžถ็š„ Application ็ฑปใ€‚ - Application ๆ นๆฎ AppWorkerLoader ๅผ€ๅง‹ๅŠ ่ฝฝ๏ผŒๅŠ ่ฝฝ้กบๅบ็ฑปไผผ๏ผŒไผšๅผ‚ๆญฅ็ญ‰ๅพ…ๅฎŒๆˆๅŽ้€š็Ÿฅ Master ๅฏๅŠจๅฎŒๆˆใ€‚ 4. Master ๅœจ็ญ‰ๅˆฐๆ‰€ๆœ‰ App Worker ๅ‘ๆฅ็š„ๅฏๅŠจๆˆๅŠŸๆถˆๆฏๅŽ๏ผŒๅฎŒๆˆๅฏๅŠจ๏ผŒๅผ€ๅง‹ๅฏนๅค–ๆไพ›ๆœๅŠกใ€‚ + ## ๆก†ๆžถๆต‹่ฏ• ๅœจ็œ‹ไธ‹ๆ–‡ไน‹ๅ‰๏ผŒ่ฏทๅ…ˆๆŸฅ็œ‹[ๅ•ๅ…ƒๆต‹่ฏ•็ซ ่Š‚](../core/unittest.md)ใ€‚ๆก†ๆžถๆต‹่ฏ•็š„ๅคง้ƒจๅˆ†ไฝฟ็”จๅœบๆ™ฏๅ’Œๅบ”็”จ็ฑปไผผใ€‚ @@ -268,15 +273,15 @@ AgentWorkerLoader ็š„ๆ‰ฉๅฑ•ไนŸ็ฑปไผผ๏ผŒ่ฟ™้‡Œไธๅ†่ต˜่ฟฐใ€‚AgentWorkerLoader ๆก†ๆžถ็š„ๅˆๅง‹ๅŒ–ๆ–นๅผๆœ‰ไธ€ๅฎšๅทฎๅผ‚ใ€‚ ```js -const mock = require('egg-mock'); -describe('test/index.test.js', () => { +const mock = require("egg-mock"); +describe("test/index.test.js", () => { let app; before(() => { app = mock.app({ // ่ฝฌๆขๆˆ test/fixtures/apps/example - baseDir: 'apps/example', + baseDir: "apps/example", // ้‡่ฆ๏ผš้…็ฝฎ framework - framework: true + framework: true, }); return app.ready(); }); @@ -284,8 +289,8 @@ describe('test/index.test.js', () => { after(() => app.close()); afterEach(mock.restore); - it('should success', () => { - return app.httpRequest().get('/').expect(200); + it("should success", () => { + return app.httpRequest().get("/").expect(200); }); }); ``` @@ -301,26 +306,26 @@ describe('test/index.test.js', () => { ๅœจๆต‹่ฏ•ๅคš็Žฏๅขƒๅœบๆ™ฏ้œ€่ฆไฝฟ็”จๅˆฐ cache ๅ‚ๆ•ฐ๏ผŒๅ› ไธบ `mock.app` ้ป˜่ฎคๆœ‰็ผ“ๅญ˜๏ผŒๅฝ“็ฌฌไธ€ๆฌกๅŠ ่ฝฝๅŽๅ†ๆฌกๅŠ ่ฝฝไผš็›ดๆŽฅ่ฏปๅ–็ผ“ๅญ˜๏ผŒ้‚ฃไนˆ่ฎพ็ฝฎ็š„็ŽฏๅขƒไนŸไธไผš็”Ÿๆ•ˆใ€‚ ```js -const mock = require('egg-mock'); -describe('/test/index.test.js', () => { +const mock = require("egg-mock"); +describe("/test/index.test.js", () => { let app; afterEach(() => app.close()); - it('should test on local', () => { - mock.env('local'); + it("should test on local", () => { + mock.env("local"); app = mock.app({ - baseDir: 'apps/example', + baseDir: "apps/example", framework: true, - cache: false + cache: false, }); return app.ready(); }); - it('should test on prod', () => { - mock.env('prod'); + it("should test on prod", () => { + mock.env("prod"); app = mock.app({ - baseDir: 'apps/example', + baseDir: "apps/example", framework: true, - cache: false + cache: false, }); return app.ready(); }); @@ -334,20 +339,20 @@ describe('/test/index.test.js', () => { ๅคš่ฟ›็จ‹ๆต‹่ฏ•ๅ’Œ `mock.app` ๅ‚ๆ•ฐไธ€่‡ด๏ผŒไฝ† app ็š„ API ๅฎŒๅ…จไธๅŒใ€‚ไธ่ฟ‡๏ผŒSuperTest ไพ็„ถๅฏ็”จใ€‚ ```js -const mock = require('egg-mock'); -describe('/test/index.test.js', () => { +const mock = require("egg-mock"); +describe("/test/index.test.js", () => { let app; before(() => { app = mock.cluster({ - baseDir: 'apps/example', - framework: true + baseDir: "apps/example", + framework: true, }); return app.ready(); }); after(() => app.close()); afterEach(mock.restore); - it('should success', () => { - return app.httpRequest().get('/').expect(200); + it("should success", () => { + return app.httpRequest().get("/").expect(200); }); }); ``` @@ -355,20 +360,20 @@ describe('/test/index.test.js', () => { ๅคš่ฟ›็จ‹ๆต‹่ฏ•่ฟ˜ๅฏไปฅๆต‹่ฏ• stdout/stderr๏ผŒๅ› ไธบ `mock.cluster` ๆ˜ฏๅŸบไบŽ [coffee](https://github.com/popomore/coffee) ๆ‰ฉๅฑ•็š„๏ผŒๅฏ่ฟ›่กŒ่ฟ›็จ‹ๆต‹่ฏ•ใ€‚ ```js -const mock = require('egg-mock'); -describe('/test/index.test.js', () => { +const mock = require("egg-mock"); +describe("/test/index.test.js", () => { let app; before(() => { app = mock.cluster({ - baseDir: 'apps/example', - framework: true + baseDir: "apps/example", + framework: true, }); return app.ready(); }); after(() => app.close()); - it('should get `started`', () => { + it("should get `started`", () => { // ๅˆคๆ–ญ็ปˆ็ซฏ่พ“ๅ‡บ - app.expect('stdout', /started/); + app.expect("stdout", /started/); }); }); ``` diff --git a/site/docs/advanced/loader-update.zh-CN.md b/site/docs/advanced/loader-update.zh-CN.md index e933ee7757..56f91d2249 100644 --- a/site/docs/advanced/loader-update.zh-CN.md +++ b/site/docs/advanced/loader-update.zh-CN.md @@ -41,7 +41,6 @@ class AppBootHook { module.exports = AppBootHook; ``` - ## ready ๅ‡ฝๆ•ฐๆ›ฟไปฃ ๅŒๆ ทๅœฐ๏ผŒๆˆ‘ไปฌไน‹ๅ‰ๅœจ `app.ready` ไธญๅค„็†ๆˆ‘ไปฌ็š„้€ป่พ‘๏ผš @@ -71,7 +70,6 @@ class AppBootHook { module.exports = AppBootHook; ``` - ## beforeClose ๅ‡ฝๆ•ฐๆ›ฟไปฃ ๅŽŸๅ…ˆ็š„ `app.beforeClose` ๅฆ‚ไปฅไธ‹ๅฝขๅผ๏ผš diff --git a/site/docs/advanced/loader.md b/site/docs/advanced/loader.md index 8836cfc009..7f71b146d9 100644 --- a/site/docs/advanced/loader.md +++ b/site/docs/advanced/loader.md @@ -123,16 +123,16 @@ However, there are still some differences: | File | Application | Framework | Plugin | | ---------------------- | ----------- | --------- | ------ | -| app/router.js | โœ”๏ธŽ | | -| app/controller | โœ”๏ธŽ | | -| app/middleware | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | -| app/service | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | -| app/extend | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | -| app.js | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | -| agent.js | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | -| config/config.{env}.js | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | -| config/plugin.js | โœ”๏ธŽ | โœ”๏ธŽ | -| package.json | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| app/router.js | โœ”๏ธŽ | | +| app/controller | โœ”๏ธŽ | | +| app/middleware | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| app/service | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| app/extend | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| app.js | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| agent.js | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| config/config.{env}.js | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | +| config/plugin.js | โœ”๏ธŽ | โœ”๏ธŽ | +| package.json | โœ”๏ธŽ | โœ”๏ธŽ | โœ”๏ธŽ | During the loading process, Egg will traverse all loadUnits to load the files above(application, framework and plugin are different), the loading process has priority. @@ -303,9 +303,9 @@ Egg implements [AppWorkerLoader] and [AgentWorkerLoader] based on the Loader, in ```js // custom AppWorkerLoader // lib/framework.js -const path = require('path'); -const egg = require('egg'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const path = require("path"); +const egg = require("egg"); +const EGG_PATH = Symbol.for("egg#eggPath"); class YadanAppWorkerLoader extends egg.AppWorkerLoader { constructor(opt) { @@ -362,9 +362,9 @@ module.exports = (app) => { // app.js // app/xx.js, as an example, we could load this file in app.js -const path = require('path'); +const path = require("path"); module.exports = (app) => { - app.loader.loadFile(path.join(app.config.baseDir, 'app/xx.js')); + app.loader.loadFile(path.join(app.config.baseDir, "app/xx.js")); }; ``` @@ -378,8 +378,8 @@ Used to load files from a directory into the app, such as `app/controller/home.j // app.js // The following is just an example, using loadController to load controller in practice module.exports = (app) => { - const directory = path.join(app.config.baseDir, 'app/controller'); - app.loader.loadToApp(directory, 'controller'); + const directory = path.join(app.config.baseDir, "app/controller"); + app.loader.loadToApp(directory, "controller"); }; ``` @@ -398,22 +398,20 @@ We load service in this mode as an example: ```js // The following is just an example, using loadService in practice // app/service/user.js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service {} module.exports = UserService; // app.js // get all loadUnit -const servicePaths = app.loader - .getLoadUnits() - .map((unit) => path.join(unit.path, 'app/service')); +const servicePaths = app.loader.getLoadUnits().map((unit) => path.join(unit.path, "app/service")); -app.loader.loadToContext(servicePaths, 'service', { +app.loader.loadToContext(servicePaths, "service", { // service needs to inherit app.Service, so needs app as parameter // enable call will return UserService when loading call: true, // loading file into app.serviceClasses - fieldClass: 'serviceClasses', + fieldClass: "serviceClasses", }); ``` @@ -427,9 +425,9 @@ So this class will only be instantiated when first calling, and will be cached a `ignore` could ignore some files, supports glob, the default is empty. ```js -app.loader.loadToApp(directory, 'controller', { +app.loader.loadToApp(directory, "controller", { // ignore files in app/controller/util - ignore: 'util/**', + ignore: "util/**", }); ``` @@ -444,8 +442,8 @@ module.exports = class User { }; // Loading from app/model, could do some initializations when loading. -const directory = path.join(app.config.baseDir, 'app/model'); -app.loader.loadToApp(directory, 'model', { +const directory = path.join(app.config.baseDir, "app/model"); +app.loader.loadToApp(directory, "model", { initializer(model, opt) { // The first parameter is export's object // The second parameter is an object that only contains current file path. @@ -507,8 +505,8 @@ When you define a loader with `loadToApp` ```js // app.js module.exports = (app) => { - const directory = path.join(app.config.baseDir, 'app/adapter'); - app.loader.loadToApp(directory, 'adapter'); + const directory = path.join(app.config.baseDir, "app/adapter"); + app.loader.loadToApp(directory, "adapter"); }; ``` @@ -521,18 +519,19 @@ module.exports = { // the property name when load to application, E.X. app.adapter adapter: { // relative to app.config.baseDir - directory: 'app/adapter', + directory: "app/adapter", // if inject is ctx, it will use loadToContext - inject: 'app', + inject: "app", // whether load the directory of the framework and plugin loadunit: false, // you can also use other LoaderOptions - } + }, }, }; ``` + ## Reference Links + - [Loader](https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js) - [AppWorkerLoader](https://github.com/eggjs/egg/blob/master/lib/loader/app_worker_loader.js) - [AgentWorkerLoader](https://github.com/eggjs/egg/blob/master/lib/loader/agent_worker_loader.js) - diff --git a/site/docs/advanced/loader.zh-CN.md b/site/docs/advanced/loader.zh-CN.md index 074a23a284..066b390d8e 100644 --- a/site/docs/advanced/loader.zh-CN.md +++ b/site/docs/advanced/loader.zh-CN.md @@ -90,6 +90,7 @@ module.exports = { | Koa | +-----------------------------------+--------+ ``` + ## ๅŠ ่ฝฝๅ•ๅ…ƒ๏ผˆloadUnit๏ผ‰ Egg ๅฐ†ๅบ”็”จใ€ๆก†ๆžถๅ’Œๆ’ไปถ้ƒฝ็งฐไธบๅŠ ่ฝฝๅ•ๅ…ƒ๏ผˆloadUnit๏ผ‰๏ผŒๅ› ไธบๅœจไปฃ็ ็ป“ๆž„ไธŠๅ‡ ไนŽๆฒกๆœ‰ไป€ไนˆๅทฎๅผ‚ใ€‚ไธ‹้ขๆ˜ฏไธ€็งๅ…ธๅž‹็š„็›ฎๅฝ•็ป“ๆž„๏ผš @@ -188,6 +189,7 @@ plugin1 ๆ˜ฏ framework1 ไพ่ต–็š„ๆ’ไปถใ€‚็”ฑไบŽ plugin2 ๅ’Œ plugin3 ็š„ไพ่ต–ๅ…ณ - ๅŠ ่ฝฝๆ—ถๅฆ‚ๆžœ้‡ๅˆฐๅŒๅๆ–‡ไปถๅฐ†ไผš่ขซ่ฆ†็›–ใ€‚ๆฏ”ๅฆ‚๏ผŒๅฆ‚ๆžœๆƒณ่ฆ่ฆ†็›– `ctx.ip`๏ผŒๅฏไปฅๅœจๅบ”็”จ็š„ `app/extend/context.js` ไธญ็›ดๆŽฅๅฎšไน‰ `ip`ใ€‚ - ๅบ”็”จๅฎŒๆ•ดๅฏๅŠจ้กบๅบ่ฏทๆŸฅ็œ‹[ๆก†ๆžถๅผ€ๅ‘](./framework.md)ใ€‚ + ### ็”Ÿๅ‘ฝๅ‘จๆœŸ ๆก†ๆžถๆไพ›ไบ†ไปฅไธ‹็”Ÿๅ‘ฝๅ‘จๆœŸๅ‡ฝๆ•ฐไพ›ๅผ€ๅ‘่€…ไฝฟ็”จ๏ผš @@ -282,6 +284,7 @@ module.exports = AppBootHook; - `app/service/userInfo.js` => `app.service.userInfo` Loader ไนŸๆไพ›ไบ† [caseStyle](#caseStyle-string) ่ฎพ็ฝฎๆฅๅผบๅˆถๆŒ‡ๅฎšๅ‘ฝๅๆ–นๅผ๏ผŒๅฆ‚ๅฐ† model ๅŠ ่ฝฝๆ—ถ็š„ API ้ฆ–ๅญ—ๆฏๅคงๅ†™๏ผŒ`app/model/user.js` => `app.model.User`๏ผŒๅฏๆŒ‡ๅฎš `caseStyle: 'upper'`ใ€‚ + ## ๆ‰ฉๅฑ• Loader `Loader` ๆ˜ฏไธ€ไธชๅŸบ็ฑป๏ผŒๅนถๆ นๆฎๆ–‡ไปถๅŠ ่ฝฝ็š„่ง„ๅˆ™ๆไพ›ไบ†ไธ€ไบ›ๅ†…็ฝฎ็š„ๆ–นๆณ•ใ€‚ๅฎƒๆœฌ่บซๅนถไธไผšๅŽป่ฐƒ็”จ่ฟ™ไบ›ๆ–นๆณ•๏ผŒ่€Œๆ˜ฏ็”ฑ็ปงๆ‰ฟ็ฑป่ฐƒ็”จใ€‚ @@ -306,9 +309,9 @@ Loader ไนŸๆไพ›ไบ† [caseStyle](#caseStyle-string) ่ฎพ็ฝฎๆฅๅผบๅˆถๆŒ‡ๅฎšๅ‘ฝๅ ```js // ่‡ชๅฎšไน‰ AppWorkerLoader // lib/framework.js -const path = require('path'); -const egg = require('egg'); -const EGG_PATH = Symbol.for('egg#eggPath'); +const path = require("path"); +const egg = require("egg"); +const EGG_PATH = Symbol.for("egg#eggPath"); class YadanAppWorkerLoader extends egg.AppWorkerLoader { constructor(opt) { @@ -348,6 +351,7 @@ module.exports = Object.assign(egg, { ้€š่ฟ‡ `Loader` ๆไพ›็š„่ฟ™ไบ› API๏ผŒๅฏไปฅๅพˆๆ–นไพฟๅœฐๅฎšๅˆถๅ›ข้˜Ÿ็š„่‡ชๅฎšไน‰ๅŠ ่ฝฝ๏ผŒไพ‹ๅฆ‚ `this.model.xx`๏ผŒ`app/extend/filter.js` ็ญ‰็ญ‰ใ€‚ ไปฅไธŠๅชๆ˜ฏ่ฏดๆ˜Ž `Loader` ็š„ๅ†™ๆณ•๏ผŒๅ…ทไฝ“ๅฏไปฅๆŸฅ็œ‹[ๆก†ๆžถๅผ€ๅ‘](./framework.md)ใ€‚ + ## ๅŠ ่ฝฝๅ™จๅ‡ฝๆ•ฐ๏ผˆLoader API๏ผ‰ Loader ๆไพ›ไบ†ไธ€ไบ›ๅŸบ็ก€ API๏ผŒๆ–นไพฟๅœจๆ‰ฉๅฑ•ๆ—ถ็ฎ€ๅŒ–ไปฃ็ ใ€‚ๆƒณไบ†่งฃๆ‰€ๆœ‰็›ธๅ…ณ API๏ผŒ่ฏท[็‚นๅ‡ปๆญคๅค„](https://github.com/eggjs/egg-core#eggloader)ใ€‚ @@ -364,9 +368,9 @@ module.exports = (app) => { // app.js // ไปฅ app/xx.js ไธบไพ‹ๅญ๏ผŒๅœจ app.js ไธญๅŠ ่ฝฝๆญคๆ–‡ไปถ๏ผš -const path = require('path'); +const path = require("path"); module.exports = (app) => { - app.loader.loadFile(path.join(app.config.baseDir, 'app/xx.js')); + app.loader.loadFile(path.join(app.config.baseDir, "app/xx.js")); }; ``` @@ -380,8 +384,8 @@ module.exports = (app) => { // app.js // ไปฅไธ‹ๅชๆ˜ฏ็คบไพ‹๏ผŒๅŠ ่ฝฝ controller ่ฏท็”จ loadController module.exports = (app) => { - const directory = path.join(app.config.baseDir, 'app/controller'); - app.loader.loadToApp(directory, 'controller'); + const directory = path.join(app.config.baseDir, "app/controller"); + app.loader.loadToApp(directory, "controller"); }; ``` @@ -400,26 +404,25 @@ module.exports = (app) => { ```js // ไปฅไธ‹ไธบ็คบไพ‹๏ผŒ่ฏทไฝฟ็”จ loadService // app/service/user.js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service {} module.exports = UserService; // app.js // ่Žทๅ–ๆ‰€ๆœ‰็š„ loadUnit -const servicePaths = app.loader - .getLoadUnits() - .map((unit) => path.join(unit.path, 'app/service')); +const servicePaths = app.loader.getLoadUnits().map((unit) => path.join(unit.path, "app/service")); -app.loader.loadToContext(servicePaths, 'service', { +app.loader.loadToContext(servicePaths, "service", { // service ้œ€่ฆ็ปงๆ‰ฟ app.Service๏ผŒๅ› ๆญค้œ€่ฆ app ๅ‚ๆ•ฐ // ่ฎพ็ฝฎ call ไธบ true๏ผŒไผšๅœจๅŠ ่ฝฝๆ—ถ่ฐƒ็”จๅ‡ฝๆ•ฐ๏ผŒๅนถ่ฟ”ๅ›ž UserService call: true, // ๅฐ†ๆ–‡ไปถๅŠ ่ฝฝๅˆฐ app.serviceClasses - fieldClass: 'serviceClasses', + fieldClass: "serviceClasses", }); ``` ๆ–‡ไปถๅŠ ่ฝฝๅฎŒๆˆๅŽ๏ผŒ`app.serviceClasses.user` ๅฐฑไปฃ่กจ UserService ็ฑปใ€‚ๅฝ“่ฐƒ็”จ `ctx.service.user` ๆ—ถ๏ผŒไผšๅฎžไพ‹ๅŒ– UserService ็ฑปใ€‚ๅ› ๆญค๏ผŒ่ฟ™ไธช็ฑปๅชๆœ‰ๅœจๆฏๆฌก่ฏทๆฑ‚ไธญ้ฆ–ๆฌก่ขซ่ฎฟ้—ฎๆ—ถๆ‰ไผšๅฎžไพ‹ๅŒ–ใ€‚ๅฎžไพ‹ๅŒ–ๅŽ๏ผŒๅฏน่ฑกไผš่ขซ็ผ“ๅญ˜๏ผŒๅŒไธ€ไธช่ฏทๆฑ‚ไธญๅคšๆฌก่ฐƒ็”จไนŸๅชๅฎžไพ‹ๅŒ–ไธ€ๆฌกใ€‚ + ### LoaderOptions #### ignore [String] @@ -427,9 +430,9 @@ app.loader.loadToContext(servicePaths, 'service', { `ignore` ๅฏ็”จไบŽๅฟฝ็•ฅๆŸไบ›ๆ–‡ไปถ๏ผŒๆ”ฏๆŒ glob ๅŒน้…ๆจกๅผ๏ผŒ้ป˜่ฎคๅ€ผไธบ็ฉบใ€‚ ```js -app.loader.loadToApp(directory, 'controller', { +app.loader.loadToApp(directory, "controller", { // ๅฟฝ็•ฅ app/controller/util ็›ฎๅฝ•ไธ‹็š„ๆ–‡ไปถ - ignore: 'util/**', + ignore: "util/**", }); ``` @@ -444,8 +447,8 @@ module.exports = class User { }; // ไปŽ app/model ็›ฎๅฝ•ๅŠ ่ฝฝ๏ผŒไธ”ๅฏไปฅๅœจๅŠ ่ฝฝๆ—ถ่ฟ›่กŒไธ€ไบ›ๅˆๅง‹ๅŒ–ๅค„็† -const directory = path.join(app.config.baseDir, 'app/model'); -app.loader.loadToApp(directory, 'model', { +const directory = path.join(app.config.baseDir, "app/model"); +app.loader.loadToApp(directory, "model", { initializer(model, opt) { // ็ฌฌไธ€ไธชๅ‚ๆ•ฐไธบ export ็š„ๅฏน่ฑก // ็ฌฌไบŒไธชๅ‚ๆ•ฐไธบไธ€ไธชๅฏน่ฑก๏ผŒ้‡Œ้ขๅŒ…ๅซๅฝ“ๅ‰ๆ–‡ไปถ็š„่ทฏๅพ„ @@ -459,6 +462,7 @@ app.loader.loadToApp(directory, 'model', { ่ฎพ็ฝฎๆ–‡ไปถๅ‘ฝๅ็š„่ฝฌๆข่ง„ๅˆ™๏ผŒๅฏ้€‰้กนไธบ `camel`ใ€`upper` ๆˆ– `lower`๏ผŒ้ป˜่ฎคๅ€ผไธบ `camel`ใ€‚ ่ฟ™ไบ›้€‰้กน้ƒฝไผšๅฐ†ๆ–‡ไปถๅ่ฝฌๆขไธบ้ฉผๅณฐๅ‘ฝๅ๏ผŒไฝ†ๆ˜ฏ้ฆ–ๅญ—็ฌฆ็š„ๅคงๅฐๅ†™ๅค„็†ไธๅŒ๏ผš + - `camel`๏ผš้ฆ–ๅญ—ๆฏไฟๆŒไธๅ˜ใ€‚ - `upper`๏ผš้ฆ–ๅญ—ๆฏ่ฝฌไธบๅคงๅ†™ใ€‚ - `lower`๏ผš้ฆ–ๅญ—ๆฏ่ฝฌไธบๅฐๅ†™ใ€‚ @@ -466,23 +470,24 @@ app.loader.loadToApp(directory, 'model', { ๆ นๆฎไธๅŒๆ–‡ไปถ็ฑปๅž‹่ฎพ็ฝฎ็›ธๅบ”็š„่ฝฌๆข่ง„ๅˆ™๏ผŒๅฆ‚ไธ‹่กจๆ‰€็คบ๏ผš | ๆ–‡ไปถ็ฑปๅž‹ | `caseStyle` ้…็ฝฎ | -| ------------- | -------------- | -| app/controller | lower | -| app/middleware | lower | -| app/service | lower | +| -------------- | ---------------- | +| app/controller | lower | +| app/middleware | lower | +| app/service | lower | #### override [Boolean] ๅฝ“ๅญ˜ๅœจๅŒๅๆ–‡ไปถๆ—ถ๏ผŒๆ˜ฏๅฆ่ฆ†็›–ๅŽŸๆœ‰ๆ–‡ไปถ๏ผŒๆˆ–ๆŠ›ๅ‡บๅผ‚ๅธธใ€‚้ป˜่ฎคๅ€ผไธบ `false`ใ€‚ ไพ‹ๅฆ‚๏ผŒๅฝ“ๅŒๆ—ถๅŠ ่ฝฝๅบ”็”จๅ’Œๆ’ไปถไธญ็š„ `app/service/user.js` ๆ–‡ไปถๆ—ถ๏ผš + - ่‹ฅ `override` ่ฎพไธบ `true`๏ผŒๅˆ™ๅบ”็”จไธญ็š„ๆ–‡ไปถไผš่ฆ†็›–ๆ’ไปถไธญ็š„ๅŒๅๆ–‡ไปถใ€‚ - ่‹ฅ่ฎพไธบ `false`๏ผŒๅˆ™ๅœจๅฐ่ฏ•ๅŠ ่ฝฝๅบ”็”จไธญ็š„ๆ–‡ไปถๆ—ถไผšๆŠฅ้”™ใ€‚ ๆ นๆฎไธๅŒๆ–‡ไปถ็ฑปๅž‹่ฎพ็ฝฎ `override` ็š„้…็ฝฎๅ€ผ๏ผŒๅฆ‚ไธ‹่กจๆ‰€็คบ๏ผš | ๆ–‡ไปถ็ฑปๅž‹ | `override` ้…็ฝฎ | -| ------------- | --------------- | +| -------------- | --------------- | | app/controller | true | | app/middleware | false | | app/service | false | @@ -493,12 +498,11 @@ app.loader.loadToApp(directory, 'model', { ๆ นๆฎไธๅŒๆ–‡ไปถ็ฑปๅž‹่ฎพ็ฝฎ `call` ็š„้…็ฝฎๅ€ผ๏ผŒๅฆ‚ไธ‹่กจๆ‰€็คบ๏ผš -| ๆ–‡ไปถ็ฑปๅž‹ | `call` ้…็ฝฎ | -| ------------- | ------------- | -| app/controller | true | -| app/middleware | false | -| app/service | true | - +| ๆ–‡ไปถ็ฑปๅž‹ | `call` ้…็ฝฎ | +| -------------- | ----------- | +| app/controller | true | +| app/middleware | false | +| app/service | true | ## CustomLoader @@ -509,8 +513,8 @@ app.loader.loadToApp(directory, 'model', { ```js // app.js module.exports = (app) => { - const directory = path.join(app.config.baseDir, 'app/adapter'); - app.loader.loadToApp(directory, 'adapter'); + const directory = path.join(app.config.baseDir, "app/adapter"); + app.loader.loadToApp(directory, "adapter"); }; ``` @@ -523,9 +527,9 @@ module.exports = { // ๅœจ app ๅฏน่ฑกไธŠๅฎšไน‰็š„ๅฑžๆ€งๅไธบ app.adapter adapter: { // ่ทฏๅพ„็›ธๅฏนไบŽ app.config.baseDir - directory: 'app/adapter', + directory: "app/adapter", // ๅฆ‚ๆžœ็”จไบŽ ctx๏ผŒๅˆ™ๅบ”่ฏฅไฝฟ็”จ loadToContext ๆ–นๆณ• - inject: 'app', + inject: "app", // ๆ˜ฏๅฆๅŠ ่ฝฝๆก†ๆžถๅ’Œๆ’ไปถ็š„็›ฎๅฝ• loadunit: false, // ไนŸๅฏไปฅๅฎšไน‰ๅ…ถไป– LoaderOptions @@ -535,6 +539,7 @@ module.exports = { ``` ๅ‚่€ƒ้“พๆŽฅ๏ผš + - [loader](https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js) - [appworkerloader](https://github.com/eggjs/egg/blob/master/lib/loader/app_worker_loader.js) -- [agentworkerloader](https://github.com/eggjs/egg/blob/master/lib/loader/agent_worker_loader.js) \ No newline at end of file +- [agentworkerloader](https://github.com/eggjs/egg/blob/master/lib/loader/agent_worker_loader.js) diff --git a/site/docs/advanced/plugin.md b/site/docs/advanced/plugin.md index f661568924..c81b42091d 100644 --- a/site/docs/advanced/plugin.md +++ b/site/docs/advanced/plugin.md @@ -60,13 +60,11 @@ Plugin is actually a `mini application`, directory of plugin is as below: It is almost the same as the application directory, what're the differences? 1. Plugin have no independant router or controller. This is because: - - Usually routers are strongly bound to application, it is not fit here. - An application might have plenty of dependant plugins, routers of plugin are very possible conflict with others. It would be a disaster. - If you really need a general router, you should implement it as middleware of the plugin. 2. The specific information of plugin should be declared in the `package.json` of `eggPlugin`๏ผš - - `{String} name` - plugin name(required), it must be unique, it will be used in the config of the dependencies of plugins. - `{Array} dependencies` - strong dependent plugins list of the current plugin(if one of these plugins here is not found, application's startup will fail). - `{Array} optionalDependencies` - optional dependencies list of this plugin.(if these plugins are not activated, only warnings would be occurred, and will not affect the startup of the application). @@ -85,7 +83,6 @@ It is almost the same as the application directory, what're the differences? ``` 3. No `plugin.js`๏ผš - - `eggPlugin.dependencies` is for declaring dependencies only, not for importing, nor activating. - If you want to manage multiple plugins, you should do it in[upper framework](./framework.md) @@ -150,24 +147,24 @@ Extend the built-in objects of the framework, just like the application 1. First, define and implement middleware under directory `app/middleware`: ```js - 'use strict'; + "use strict"; - const staticCache = require('koa-static-cache'); - const assert = require('assert'); - const mkdirp = require('mkdirp'); + const staticCache = require("koa-static-cache"); + const assert = require("assert"); + const mkdirp = require("mkdirp"); module.exports = (options, app) => { assert.strictEqual( typeof options.dir, - 'string', - 'Must set `app.config.static.dir` when static plugin enable', + "string", + "Must set `app.config.static.dir` when static plugin enable", ); // ensure directory exists mkdirp.sync(options.dir); app.loggers.coreLogger.info( - '[egg-static] starting static serve %s -> %s', + "[egg-static] starting static serve %s -> %s", options.prefix, options.dir, ); @@ -179,14 +176,14 @@ Extend the built-in objects of the framework, just like the application 2. Insert middleware to the appropriate position in `app.js`(e.g. insert static middleware before bodyParser): ```js - const assert = require('assert'); + const assert = require("assert"); module.exports = (app) => { // insert static middleware before bodyParser - const index = app.config.coreMiddleware.indexOf('bodyParser'); - assert(index >= 0, 'bodyParser highly needed'); + const index = app.config.coreMiddleware.indexOf("bodyParser"); + assert(index >= 0, "bodyParser highly needed"); - app.config.coreMiddleware.splice(index, 0, 'static'); + app.config.coreMiddleware.splice(index, 0, "static"); }; ``` @@ -196,13 +193,13 @@ Extend the built-in objects of the framework, just like the application ```js // ${plugin_root}/app.js - const fs = require('fs'); - const path = require('path'); + const fs = require("fs"); + const path = require("path"); module.exports = (app) => { - app.customData = fs.readFileSync(path.join(app.config.baseDir, 'data.bin')); + app.customData = fs.readFileSync(path.join(app.config.baseDir, "data.bin")); - app.coreLogger.info('read data ok'); + app.coreLogger.info("read data ok"); }; ``` @@ -210,16 +207,16 @@ Extend the built-in objects of the framework, just like the application ```js // ${plugin_root}/app.js - const MyClient = require('my-client'); + const MyClient = require("my-client"); module.exports = (app) => { app.myClient = new MyClient(); - app.myClient.on('error', (err) => { + app.myClient.on("error", (err) => { app.coreLogger.error(err); }); app.beforeStart(async () => { await app.myClient.ready(); - app.coreLogger.info('my client is ready'); + app.coreLogger.info("my client is ready"); }); }; ``` @@ -228,16 +225,16 @@ Extend the built-in objects of the framework, just like the application ```js // ${plugin_root}/agent.js - const MyClient = require('my-client'); + const MyClient = require("my-client"); module.exports = (agent) => { agent.myClient = new MyClient(); - agent.myClient.on('error', (err) => { + agent.myClient.on("error", (err) => { agent.coreLogger.error(err); }); agent.beforeStart(async () => { await agent.myClient.ready(); - agent.coreLogger.info('my client is ready'); + agent.coreLogger.info("my client is ready"); }); }; ``` @@ -260,8 +257,8 @@ Extend the built-in objects of the framework, just like the application ```js exports.schedule = { - type: 'worker', - cron: '0 0 3 * * *', + type: "worker", + cron: "0 0 3 * * *", // interval: '1h', // immediate: true, }; @@ -289,7 +286,7 @@ We simplify the [egg-mysql] plugin to see how to write it: module.exports = (app) => { // The first parameter mysql defines the field mounted to app, we can access MySQL singleton instance via `app.mysql` // The second parameter createMysql accepts two parameters (config, app), and then returns a MySQL instance - app.addSingleton('mysql', createMysql); + app.addSingleton("mysql", createMysql); }; /** @@ -304,7 +301,7 @@ function createMysql(config, app) { // check before start the application app.beforeStart(async () => { - const rows = await client.query('select now() as currentTime;'); + const rows = await client.query("select now() as currentTime;"); app.coreLogger.info( `[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`, ); @@ -320,20 +317,13 @@ The initialization function also supports `Async function`, convenient for some async function createMysql(config, app) { // get mysql configurations asynchronous const mysqlConfig = await app.configManager.getMysqlConfig(config.mysql); - assert( - mysqlConfig.host && - mysqlConfig.port && - mysqlConfig.user && - mysqlConfig.database, - ); + assert(mysqlConfig.host && mysqlConfig.port && mysqlConfig.user && mysqlConfig.database); // create instance const client = new Mysql(mysqlConfig); // check before start the application - const rows = await client.query('select now() as currentTime;'); - app.coreLogger.info( - `[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`, - ); + const rows = await client.query("select now() as currentTime;"); + app.coreLogger.info(`[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`); return client; } @@ -352,11 +342,11 @@ As you can see, all we need to do for this plugin is passing the fields that nee module.exports = { mysql: { client: { - host: 'mysql.com', - port: '3306', - user: 'test_user', - password: 'test_password', - database: 'test', + host: "mysql.com", + port: "3306", + user: "test_user", + password: "test_password", + database: "test", }, }, }; @@ -383,20 +373,20 @@ As you can see, all we need to do for this plugin is passing the fields that nee clients: { // clientId, access the client instance by app.mysql.get('clientId') db1: { - user: 'user1', - password: 'upassword1', - database: 'db1', + user: "user1", + password: "upassword1", + database: "db1", }, db2: { - user: 'user2', - password: 'upassword2', - database: 'db2', + user: "user2", + password: "upassword2", + database: "db2", }, }, // default configuration for all databases default: { - host: 'mysql.com', - port: '3306', + host: "mysql.com", + port: "3306", }, }; ``` @@ -421,7 +411,7 @@ Instead of declaring the configuration in the configuration file in advance, we module.exports = (app) => { app.beforeStart(async () => { // get MySQL config from configuration center { host, post, password, ... } - const mysqlConfig = await app.configCenter.fetch('mysql'); + const mysqlConfig = await app.configCenter.fetch("mysql"); // create MySQL instance dynamically app.database = app.mysql.createInstanceAsync(mysqlConfig); }); @@ -447,7 +437,6 @@ When loading the plugins in the framework, it will follow the rules below: - If there is the path configuration, load them in path directly. - If there is no path configuration, search them with the package name, the search orders are: - 1. `node_modules` directory of the application root 2. `node_modules` directory of the dependencies 3. `node_modules` of current directory(generally for unit test compatibility) @@ -461,7 +450,6 @@ It's well welcomed to your contributions to the new plugins, but also hope you f - The corresponding plugin should be named in camel-case. The name should be translated according to the middle-lines of the `npm` name:`egg-foo-bar` => `fooBar`. - The use of middle-lines is not compulsive, e.g: userservice(egg-userservice) and user-service(egg-user-service) are both acceptable. - `package.json` Rules: - - Add `eggPlugin` property according to the details discussed before. - For convenient index, add `egg`,`egg-plugin`,`eggPlugin` in `keywords`: @@ -474,14 +462,7 @@ It's well welcomed to your contributions to the new plugins, but also hope you f "name": "nunjucks", "dep": ["security"] }, - "keywords": [ - "egg", - "egg-plugin", - "eggPlugin", - "egg-plugin-view", - "egg-view", - "nunjucks" - ] + "keywords": ["egg", "egg-plugin", "eggPlugin", "egg-plugin-view", "egg-view", "nunjucks"] } ``` diff --git a/site/docs/advanced/plugin.zh-CN.md b/site/docs/advanced/plugin.zh-CN.md index 3372cf9775..cb0ce7d6a0 100644 --- a/site/docs/advanced/plugin.zh-CN.md +++ b/site/docs/advanced/plugin.zh-CN.md @@ -59,13 +59,11 @@ $ npm test ้‚ฃๅŒบๅˆซๅœจๅ“ชๅ„ฟๅ‘ข๏ผŸ 1. ๆ’ไปถๆฒกๆœ‰็‹ฌ็ซ‹็š„ router ๅ’Œ controllerใ€‚่ฟ™ไธป่ฆๅ‡บไบŽๅ‡ ็‚น่€ƒ่™‘๏ผš - - ่ทฏ็”ฑไธ€่ˆฌๅ’Œๅบ”็”จๅผบ็ป‘ๅฎš็š„๏ผŒไธๅ…ทๅค‡้€š็”จๆ€งใ€‚ - ไธ€ไธชๅบ”็”จๅฏ่ƒฝไพ่ต–ๅพˆๅคšไธชๆ’ไปถ๏ผŒๅฆ‚ๆžœๆ’ไปถๆ”ฏๆŒ่ทฏ็”ฑๅฏ่ƒฝไผšๅฏผ่‡ด่ทฏ็”ฑๅ†ฒ็ชใ€‚ - ๅฆ‚ๆžœ็กฎๅฎžๆœ‰็ปŸไธ€่ทฏ็”ฑ็š„้œ€ๆฑ‚๏ผŒๅฏไปฅ่€ƒ่™‘ๅœจๆ’ไปถ้‡Œ้€š่ฟ‡ไธญ้—ดไปถๆฅๅฎž็Žฐใ€‚ 2. ๆ’ไปถ้œ€่ฆๅœจ `package.json` ไธญ็š„ `eggPlugin` ่Š‚็‚นๆŒ‡ๅฎšๆ’ไปถ็‰นๆœ‰็š„ไฟกๆฏ๏ผš - - `{String} name` - ๆ’ไปถๅ๏ผˆๅฟ…้กป้…็ฝฎ๏ผ‰๏ผŒๅ…ทๆœ‰ๅ”ฏไธ€ๆ€ง๏ผŒ้…็ฝฎไพ่ต–ๅ…ณ็ณปๆ—ถไผšๆŒ‡ๅฎšไพ่ต–ๆ’ไปถ็š„ nameใ€‚ - `{Array} dependencies` - ๅฝ“ๅ‰ๆ’ไปถๅผบไพ่ต–็š„ๆ’ไปถๅˆ—่กจ๏ผˆๅฆ‚ๆžœไพ่ต–็š„ๆ’ไปถๆฒกๆ‰พๅˆฐ๏ผŒๅบ”็”จๅฏๅŠจๅคฑ่ดฅ๏ผ‰ใ€‚ - `{Array} optionalDependencies` - ๅฝ“ๅ‰ๆ’ไปถ็š„ๅฏ้€‰ไพ่ต–ๆ’ไปถๅˆ—่กจ๏ผˆๅฆ‚ๆžœไพ่ต–็š„ๆ’ไปถๆœชๅผ€ๅฏ๏ผŒๅชไผš warning๏ผŒไธไผšๅฝฑๅ“ๅบ”็”จๅฏๅŠจ๏ผ‰ใ€‚ @@ -84,7 +82,6 @@ $ npm test ``` 3. ๆ’ไปถๆฒกๆœ‰ `plugin.js`๏ผš - - `eggPlugin.dependencies` ๅชๆ˜ฏ็”จไบŽๅฃฐๆ˜Žไพ่ต–ๅ…ณ็ณป๏ผŒ่€Œไธๆ˜ฏๅผ•ๅ…ฅๆ’ไปถๆˆ–ๅผ€ๅฏๆ’ไปถใ€‚ - ๅฆ‚ๆžœๆœŸๆœ›็ปŸไธ€็ฎก็†ๅคšไธชๆ’ไปถ็š„ๅผ€ๅฏๅ’Œ้…็ฝฎ๏ผŒๅฏไปฅๅœจ [ไธŠๅฑ‚ๆก†ๆžถ](./framework.md) ๅค„็†ใ€‚ @@ -128,6 +125,7 @@ $ npm test - ๅผฑไพ่ต–๏ผŒๆฏ”ๅฆ‚๏ผšA ไพ่ต– B๏ผŒไฝ†ๆ˜ฏๅฆ‚ๆžœๆฒกๆœ‰ B๏ผŒA ๆœ‰็›ธๅบ”็š„้™็บงๆ–นๆกˆใ€‚ ้œ€่ฆ็‰นๅˆซๅผบ่ฐƒ็š„ๆ˜ฏ๏ผšๅฆ‚ๆžœ้‡‡็”จ `optionalDependencies`๏ผŒ้‚ฃไนˆๆก†ๆžถไธไผšๆ ก้ชŒไพ่ต–็š„ๆ’ไปถๆ˜ฏๅฆๅผ€ๅฏ๏ผŒๅฎƒ็š„ไฝœ็”จไป…ไป…ๆ˜ฏ่ฎก็ฎ—ๅŠ ่ฝฝ้กบๅบใ€‚ๆ‰€ไปฅ๏ผŒ่ฟ™ๆ—ถๅ€™ไพ่ต–ๆ–น้œ€่ฆ้€š่ฟ‡โ€œๆŽฅๅฃๆŽขๆต‹โ€็ญ‰ๆ–นๅผๆฅๅ†ณๅฎš็›ธๅบ”็š„ๅค„็†้€ป่พ‘ใ€‚ + ## ๆ’ไปถ่ƒฝๅšไป€ไนˆ๏ผŸ ไธŠ้ข็ป™ๅ‡บไบ†ๆ’ไปถ็š„ๅฎšไน‰๏ผŒ้‚ฃๆ’ไปถๅˆฐๅบ•่ƒฝๅšไป€ไนˆ๏ผŸ @@ -148,24 +146,24 @@ $ npm test 1. ้ฆ–ๅ…ˆๅœจ `app/middleware` ็›ฎๅฝ•ไธ‹ๅฎšไน‰ๅฅฝไธญ้—ดไปถๅฎž็Žฐ๏ผš ```js - 'use strict'; + "use strict"; - const staticCache = require('koa-static-cache'); - const assert = require('assert'); - const mkdirp = require('mkdirp'); + const staticCache = require("koa-static-cache"); + const assert = require("assert"); + const mkdirp = require("mkdirp"); module.exports = (options, app) => { assert.strictEqual( typeof options.dir, - 'string', - 'Must set `app.config.static.dir` when static plugin enable', + "string", + "Must set `app.config.static.dir` when static plugin enable", ); // ็กฎไฟ็›ฎๅฝ•ๅญ˜ๅœจ mkdirp.sync(options.dir); app.loggers.coreLogger.info( - '[egg-static] starting static serve %s -> %s', + "[egg-static] starting static serve %s -> %s", options.prefix, options.dir, ); @@ -177,14 +175,14 @@ $ npm test 2. ๅœจ `app.js` ไธญๅฐ†ไธญ้—ดไปถๆ’ๅ…ฅๅˆฐๅˆ้€‚็š„ไฝ็ฝฎ๏ผˆไพ‹ๅฆ‚๏ผšไธ‹้ขๅฐ† static ไธญ้—ดไปถๆ”พๅˆฐ bodyParser ไน‹ๅ‰๏ผ‰๏ผš ```js - const assert = require('assert'); + const assert = require("assert"); module.exports = (app) => { // ๅฐ† static ไธญ้—ดไปถๆ”พๅˆฐ bodyParser ไน‹ๅ‰ - const index = app.config.coreMiddleware.indexOf('bodyParser'); - assert(index >= 0, 'bodyParser ไธญ้—ดไปถๅฟ…้กปๅญ˜ๅœจ'); + const index = app.config.coreMiddleware.indexOf("bodyParser"); + assert(index >= 0, "bodyParser ไธญ้—ดไปถๅฟ…้กปๅญ˜ๅœจ"); - app.config.coreMiddleware.splice(index, 0, 'static'); + app.config.coreMiddleware.splice(index, 0, "static"); }; ``` @@ -194,13 +192,13 @@ $ npm test ```js // ${plugin_root}/app.js - const fs = require('fs'); - const path = require('path'); + const fs = require("fs"); + const path = require("path"); module.exports = (app) => { - app.customData = fs.readFileSync(path.join(app.config.baseDir, 'data.bin')); + app.customData = fs.readFileSync(path.join(app.config.baseDir, "data.bin")); - app.coreLogger.info('Data read successfully'); + app.coreLogger.info("Data read successfully"); }; ``` @@ -208,16 +206,16 @@ $ npm test ```js // ${plugin_root}/app.js - const MyClient = require('my-client'); + const MyClient = require("my-client"); module.exports = (app) => { app.myClient = new MyClient(); - app.myClient.on('error', (err) => { + app.myClient.on("error", (err) => { app.coreLogger.error(err); }); app.beforeStart(async () => { await app.myClient.ready(); - app.coreLogger.info('My client is ready'); + app.coreLogger.info("My client is ready"); }); }; ``` @@ -226,19 +224,20 @@ $ npm test ```js // ${plugin_root}/agent.js - const MyClient = require('my-client'); + const MyClient = require("my-client"); module.exports = (agent) => { agent.myClient = new MyClient(); - agent.myClient.on('error', (err) => { + agent.myClient.on("error", (err) => { agent.coreLogger.error(err); }); agent.beforeStart(async () => { await agent.myClient.ready(); - agent.coreLogger.info('My client is ready'); + agent.coreLogger.info("My client is ready"); }); }; ``` + ### ่ฎพ็ฝฎๅฎšๆ—ถไปปๅŠก 1. ๅœจ `package.json` ้‡Œ่ฎพ็ฝฎไพ่ต– schedule ๆ’ไปถ @@ -257,8 +256,8 @@ $ npm test ```js exports.schedule = { - type: 'worker', - cron: '0 0 3 * * *', + type: "worker", + cron: "0 0 3 * * *", // interval: '1h', // immediate: true }; @@ -283,8 +282,8 @@ $ npm test ```js // egg-mysql/app.js -module.exports = app => { - app.addSingleton('mysql', createMysql); +module.exports = (app) => { + app.addSingleton("mysql", createMysql); }; /** @@ -299,8 +298,10 @@ function createMysql(config, app) { // ๅบ”็”จๅฏๅŠจๅ‰ๆฃ€ๆŸฅ app.beforeStart(async () => { - const rows = await client.query('select now() as currentTime;'); - app.coreLogger.info(`[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`); + const rows = await client.query("select now() as currentTime;"); + app.coreLogger.info( + `[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`, + ); }); return client; @@ -318,7 +319,7 @@ async function createMysql(config, app) { const client = new Mysql(mysqlConfig); // ๅบ”็”จๅฏๅŠจๅ‰ๆฃ€ๆŸฅ - const rows = await client.query('select now() as currentTime;'); + const rows = await client.query("select now() as currentTime;"); app.coreLogger.info(`[egg-mysql] init instance success, rds currentTime: ${rows[0].currentTime}`); return client; @@ -326,6 +327,7 @@ async function createMysql(config, app) { ``` ๅฏไปฅ็œ‹ๅˆฐ๏ผŒๆ’ไปถไธญๆˆ‘ไปฌๅช้œ€่ฆๆไพ›่ฆๆŒ‚่ฝฝ็š„ๅญ—ๆฎตๅ’ŒๆœๅŠก็š„ๅˆๅง‹ๅŒ–ๆ–นๆณ•๏ผŒๆ‰€ๆœ‰้…็ฝฎ็ฎก็†ใ€ๅฎžไพ‹่Žทๅ–ๆ–นๅผ็”ฑๆก†ๆžถๅฐ่ฃ…ๅนถ็ปŸไธ€ๆไพ›ใ€‚ + #### ๅบ”็”จๅฑ‚ไฝฟ็”จๆ–นๆกˆ ##### ๅ•ๅฎžไพ‹ @@ -337,11 +339,11 @@ async function createMysql(config, app) { module.exports = { mysql: { client: { - host: 'mysql.com', - port: '3306', - user: 'test_user', - password: 'test_password', - database: 'test', + host: "mysql.com", + port: "3306", + user: "test_user", + password: "test_password", + database: "test", }, }, }; @@ -368,20 +370,20 @@ async function createMysql(config, app) { clients: { // clientId๏ผŒๅฏ้€š่ฟ‡ app.mysql.get('clientId') ่ฎฟ้—ฎๅฎขๆˆท็ซฏๅฎžไพ‹ db1: { - user: 'user1', - password: 'upassword1', - database: 'db1', + user: "user1", + password: "upassword1", + database: "db1", }, db2: { - user: 'user2', - password: 'upassword2', - database: 'db2', + user: "user2", + password: "upassword2", + database: "db2", }, }, // ๆ‰€ๆœ‰ๆ•ฐๆฎๅบ“็š„้ป˜่ฎค้…็ฝฎ default: { - host: 'mysql.com', - port: '3306', + host: "mysql.com", + port: "3306", }, }; ``` @@ -392,7 +394,7 @@ async function createMysql(config, app) { // app/controller/post.js class PostController extends Controller { async list() { - const posts = await this.app.mysql.get('db1').query(sql, values); + const posts = await this.app.mysql.get("db1").query(sql, values); } } ``` @@ -403,10 +405,10 @@ async function createMysql(config, app) { ```js // app.js -module.exports = app => { +module.exports = (app) => { app.beforeStart(async () => { // ไปŽ้…็ฝฎไธญๅฟƒ่Žทๅ– MySQL ้…็ฝฎ { host, port, password, ... } - const mysqlConfig = await app.configCenter.fetch('mysql'); + const mysqlConfig = await app.configCenter.fetch("mysql"); // ๅŠจๆ€ๅˆ›ๅปบ MySQL ๅฎžไพ‹ app.database = await app.mysql.createInstanceAsync(mysqlConfig); }); @@ -435,6 +437,7 @@ class PostController extends Controller { 1. ๅบ”็”จๆ น็›ฎๅฝ•ไธ‹็š„ `node_modules` 2. ๅบ”็”จไพ่ต–ๆก†ๆžถ่ทฏๅพ„ไธ‹็š„ `node_modules` 3. ๅฝ“ๅ‰่ทฏๅพ„ไธ‹็š„ `node_modules`๏ผˆไธป่ฆๆ˜ฏๅ…ผๅฎนๅ•ๅ…ƒๆต‹่ฏ•ๅœบๆ™ฏ๏ผ‰ + ### ๆ’ไปถ่ง„่Œƒ ๆˆ‘ไปฌ้žๅธธๆฌข่ฟŽไฝ ่ดก็Œฎๆ–ฐ็š„ๆ’ไปถ๏ผŒๅŒๆ—ถไนŸๅธŒๆœ›ไฝ ้ตๅฎˆไธ‹้ขไธ€ไบ›่ง„่Œƒ๏ผš @@ -445,7 +448,6 @@ class PostController extends Controller { - ๅฏนไบŽๆ—ขๅฏไปฅๅŠ ไธญๅˆ’็บฟไนŸๅฏไปฅไธๅŠ ็š„ๆƒ…ๅ†ต๏ผŒไธๅšๅผบๅˆถ็บฆๅฎš๏ผŒไพ‹ๅฆ‚๏ผš`userservice`๏ผˆ`egg-userservice`๏ผ‰ๆˆ– `user-service`๏ผˆ`egg-user-service`๏ผ‰้ƒฝๅฏใ€‚ - `package.json` ไนฆๅ†™่ง„่Œƒ - - ๆŒ‰็…งไธŠ้ข็š„ๆ–‡ๆกฃๆทปๅŠ  `eggPlugin` ่Š‚็‚นใ€‚ - ๅœจ `keywords` ้‡ŒๆทปๅŠ  `egg`ใ€`egg-plugin`ใ€`eggPlugin` ็ญ‰ๅ…ณ้”ฎๅญ—๏ผŒไพฟไบŽ็ดขๅผ•ใ€‚ @@ -458,14 +460,7 @@ class PostController extends Controller { "name": "nunjucks", "dep": ["security"] }, - "keywords": [ - "egg", - "egg-plugin", - "eggPlugin", - "egg-plugin-view", - "egg-view", - "nunjucks" - ] + "keywords": ["egg", "egg-plugin", "eggPlugin", "egg-plugin-view", "egg-view", "nunjucks"] } ``` @@ -479,7 +474,6 @@ Egg ้€š่ฟ‡ `eggPlugin.name` ๆฅๅฎšไน‰ๆ’ไปถๅ๏ผŒๅช้œ€ๅบ”็”จๆˆ–ๆก†ๆžถๅ…ทๅค‡ๅ”ฏ **ๅฐ†็›ธๅŒๅŠŸ่ƒฝ็š„ๆ’ไปถ่ต‹ไบˆ็›ธๅŒ็š„ๆ’ไปถๅ๏ผŒไปฅๅŠๆไพ›็›ธๅŒ็š„ API๏ผŒๅฏไปฅๅฟซ้€Ÿ่ฟ›่กŒๅˆ‡ๆข**ใ€‚่ฟ™็งๅšๆณ•ๅœจๆจกๆฟใ€ๆ•ฐๆฎๅบ“็ญ‰้ข†ๅŸŸ้žๅธธ้€‚็”จใ€‚ - [egg-boilerplate-plugin]: https://github.com/eggjs/egg-boilerplate-plugin [egg-mysql]: https://github.com/eggjs/egg-mysql [egg-oss]: https://github.com/eggjs/egg-oss diff --git a/site/docs/advanced/view-plugin.md b/site/docs/advanced/view-plugin.md index af52222dab..e130695ec0 100644 --- a/site/docs/advanced/view-plugin.md +++ b/site/docs/advanced/view-plugin.md @@ -57,11 +57,10 @@ The base class of the View needs to provide `render` and `renderString` methods The following is a simplified code that can be directly [view source](https://github.com/eggjs/egg-view-ejs/blob/master/lib/view.js) ```js -const ejs = require('ejs'); +const ejs = require("ejs"); Mmdule.exports = class EjsView { render(filename, locals, viewOptions) { - const config = Object.assign({}, this.config, viewOptions, { filename }); return new Promise((resolve, reject) => { @@ -150,7 +149,7 @@ module.exports = (app) => { ```js // {plugin_root}/lib/view.js -const ViewHelper = require('./helper'); +const ViewHelper = require("./helper"); module.exports = class MyCustomView { render(filename, locals) { diff --git a/site/docs/advanced/view-plugin.zh-CN.md b/site/docs/advanced/view-plugin.zh-CN.md index e2a1617fe7..7c3ebfa4ad 100644 --- a/site/docs/advanced/view-plugin.zh-CN.md +++ b/site/docs/advanced/view-plugin.zh-CN.md @@ -8,6 +8,7 @@ order: 5 ๆœฌๆ–‡ๅฐ†้˜่ฟฐๆก†ๆžถๅฏน View ๆ’ไปถ็š„่ง„่Œƒ็บฆๆŸใ€‚ๆˆ‘ไปฌๅฏไปฅไพๆญคๆฅๅฐ่ฃ…ๅฏนๅบ”็š„ๆจกๆฟๅผ•ๆ“Žๆ’ไปถใ€‚ไปฅไธ‹ไปฅ [egg-view-ejs](https://github.com/eggjs/egg-view-ejs) ไธบไพ‹ใ€‚ ## ๆ’ไปถ็›ฎๅฝ•็ป“ๆž„ + ```bash egg-view-ejs โ”œโ”€โ”€ config @@ -54,11 +55,10 @@ View ๅŸบ็ฑป้œ€่ฆๆไพ› `render` ๅ’Œ `renderString` ไธคไธชๆ–นๆณ•๏ผŒๆ”ฏๆŒ genera ไปฅไธ‹ไธบ็ฎ€ๅŒ–ไปฃ็ ๏ผŒๆ‚จๅฏไปฅ็›ดๆŽฅ[ๆŸฅ็œ‹ๆบ็ ](https://github.com/eggjs/egg-view-ejs/blob/master/lib/view.js)๏ผš ```js -const ejs = require('ejs'); +const ejs = require("ejs"); Mmdule.exports = class EjsView { render(filename, locals, viewOptions) { - const config = Object.assign({}, this.config, viewOptions, { filename }); return new Promise((resolve, reject) => { @@ -88,14 +88,16 @@ Mmdule.exports = class EjsView { ### ๅ‚ๆ•ฐ `render` ๆ–นๆณ•็š„ๅ‚ๆ•ฐ๏ผš - - `filename`๏ผšๆ˜ฏๅฎŒๆ•ดๆ–‡ไปถ่ทฏๅพ„๏ผŒๆก†ๆžถๆŸฅๆ‰พๆ–‡ไปถๆ—ถๅทฒ็กฎ่ฎคๆ–‡ไปถๆ˜ฏๅฆๅญ˜ๅœจ๏ผŒๅ› ๆญค่ฟ™้‡Œไธ้œ€่ฆๅค„็†ใ€‚ - - `locals`๏ผšๆธฒๆŸ“ๆ‰€้œ€ๆ•ฐๆฎ๏ผŒๆฅๆบๅŒ…ๆ‹ฌ `app.locals`ใ€`ctx.locals` ไปฅๅŠ่ฐƒ็”จ `render` ๆ–นๆณ•ไผ ๅ…ฅ็š„ๆ•ฐๆฎใ€‚ๆก†ๆžถ่ฟ˜ๅ†…็ฝฎไบ† `ctx`ใ€`request` ๅ’Œ `ctx.helper` ่ฟ™ๅ‡ ไธชๅฏน่ฑกใ€‚ - - `viewOptions`๏ผš็”จๆˆทไผ ๅ…ฅ็š„้…็ฝฎ๏ผŒๅฏไปฅ่ฆ†็›–ๆจกๆฟๅผ•ๆ“Ž็š„้ป˜่ฎค้…็ฝฎใ€‚่ฟ™ไธชๅฏๆ นๆฎๆจกๆฟๅผ•ๆ“Ž็š„็‰นๅพ่€ƒ่™‘ๆ˜ฏๅฆๆ”ฏๆŒใ€‚ไพ‹ๅฆ‚๏ผŒ้ป˜่ฎคๅผ€ๅฏไบ†็ผ“ๅญ˜๏ผŒ่€ŒๆŸไธช้กต้ขไธ้œ€่ฆ็ผ“ๅญ˜ใ€‚ + +- `filename`๏ผšๆ˜ฏๅฎŒๆ•ดๆ–‡ไปถ่ทฏๅพ„๏ผŒๆก†ๆžถๆŸฅๆ‰พๆ–‡ไปถๆ—ถๅทฒ็กฎ่ฎคๆ–‡ไปถๆ˜ฏๅฆๅญ˜ๅœจ๏ผŒๅ› ๆญค่ฟ™้‡Œไธ้œ€่ฆๅค„็†ใ€‚ +- `locals`๏ผšๆธฒๆŸ“ๆ‰€้œ€ๆ•ฐๆฎ๏ผŒๆฅๆบๅŒ…ๆ‹ฌ `app.locals`ใ€`ctx.locals` ไปฅๅŠ่ฐƒ็”จ `render` ๆ–นๆณ•ไผ ๅ…ฅ็š„ๆ•ฐๆฎใ€‚ๆก†ๆžถ่ฟ˜ๅ†…็ฝฎไบ† `ctx`ใ€`request` ๅ’Œ `ctx.helper` ่ฟ™ๅ‡ ไธชๅฏน่ฑกใ€‚ +- `viewOptions`๏ผš็”จๆˆทไผ ๅ…ฅ็š„้…็ฝฎ๏ผŒๅฏไปฅ่ฆ†็›–ๆจกๆฟๅผ•ๆ“Ž็š„้ป˜่ฎค้…็ฝฎใ€‚่ฟ™ไธชๅฏๆ นๆฎๆจกๆฟๅผ•ๆ“Ž็š„็‰นๅพ่€ƒ่™‘ๆ˜ฏๅฆๆ”ฏๆŒใ€‚ไพ‹ๅฆ‚๏ผŒ้ป˜่ฎคๅผ€ๅฏไบ†็ผ“ๅญ˜๏ผŒ่€ŒๆŸไธช้กต้ขไธ้œ€่ฆ็ผ“ๅญ˜ใ€‚ `renderString` ๆ–นๆณ•็š„ไธ‰ไธชๅ‚ๆ•ฐ๏ผš - - `tpl`: ๆจกๆฟๅญ—็ฌฆไธฒ๏ผŒๆฒกๆœ‰ๆ–‡ไปถ่ทฏๅพ„ใ€‚ - - `locals`: ๅŒ `render`ใ€‚ - - `viewOptions`: ๅŒ `render`ใ€‚ + +- `tpl`: ๆจกๆฟๅญ—็ฌฆไธฒ๏ผŒๆฒกๆœ‰ๆ–‡ไปถ่ทฏๅพ„ใ€‚ +- `locals`: ๅŒ `render`ใ€‚ +- `viewOptions`: ๅŒ `render`ใ€‚ ## ๆ’ไปถ้…็ฝฎ @@ -107,8 +109,8 @@ Mmdule.exports = class EjsView { // config/config.default.js module.exports = { ejs: { - cache: true - } + cache: true, + }, }; ``` @@ -145,7 +147,7 @@ module.exports = (app) => { ```js // {plugin_root}/lib/view.js -const ViewHelper = require('./helper'); +const ViewHelper = require("./helper"); module.exports = class MyCustomView { render(filename, locals) { diff --git a/site/docs/basics/app-start.md b/site/docs/basics/app-start.md index 7ae4b05c65..3d8207adf2 100644 --- a/site/docs/basics/app-start.md +++ b/site/docs/basics/app-start.md @@ -34,8 +34,8 @@ class AppBootHook { // For example: the password in the parameter is encrypted, decrypt it here this.app.config.mysql.password = decrypt(this.app.config.mysql.password); // For example: insert a middleware into the framework's coreMiddleware - const statusIdx = this.app.config.coreMiddleware.indexOf('status'); - this.app.config.coreMiddleware.splice(statusIdx + 1, 0, 'limit'); + const statusIdx = this.app.config.coreMiddleware.indexOf("status"); + this.app.config.coreMiddleware.splice(statusIdx + 1, 0, "limit"); } async didLoad() { @@ -47,8 +47,8 @@ class AppBootHook { await this.app.queue.init(); // For example: load a custom directory - this.app.loader.loadToContext(path.join(__dirname, 'app/tasks'), 'tasks', { - fieldClass: 'tasksClasses', + this.app.loader.loadToContext(path.join(__dirname, "app/tasks"), "tasks", { + fieldClass: "tasksClasses", }); } @@ -72,7 +72,7 @@ class AppBootHook { // http / https server has started and begins accepting external requests // At this point you can get an instance of server from app.server - this.app.server.on('timeout', (socket) => { + this.app.server.on("timeout", (socket) => { // handle socket timeout }); } diff --git a/site/docs/basics/app-start.zh-CN.md b/site/docs/basics/app-start.zh-CN.md index 34123fb508..b0721c7996 100644 --- a/site/docs/basics/app-start.zh-CN.md +++ b/site/docs/basics/app-start.zh-CN.md @@ -8,6 +8,7 @@ order: 12 ๆก†ๆžถๆไพ›ไบ†็ปŸไธ€็š„ๅ…ฅๅฃๆ–‡ไปถ๏ผˆ`app.js`๏ผ‰่ฟ›่กŒๅฏๅŠจ่ฟ‡็จ‹่‡ชๅฎšไน‰ใ€‚่ฟ™ไธชๆ–‡ไปถ้œ€่ฆ่ฟ”ๅ›žไธ€ไธช Boot ็ฑปใ€‚ๆˆ‘ไปฌๅฏไปฅ้€š่ฟ‡ๅฎšไน‰ Boot ็ฑปไธญ็š„็”Ÿๅ‘ฝๅ‘จๆœŸๆ–นๆณ•ๆฅๆ‰ง่กŒๅฏๅŠจๅบ”็”จ่ฟ‡็จ‹ไธญ็š„ๅˆๅง‹ๅŒ–ๅทฅไฝœใ€‚ ๆก†ๆžถๆไพ›ไบ†ไปฅไธ‹ [็”Ÿๅ‘ฝๅ‘จๆœŸๅ‡ฝๆ•ฐ](../advanced/loader.md#life-cycles) ไพ›ๅผ€ๅ‘ไบบๅ‘˜ๅค„็†๏ผš + - ้…็ฝฎๆ–‡ไปถๅณๅฐ†ๅŠ ่ฝฝ๏ผŒ่ฟ™ๆ˜ฏๆœ€ๅŽๅŠจๆ€ไฟฎๆ”น้…็ฝฎ็š„ๆ—ถๆœบ๏ผˆ`configWillLoad`๏ผ‰๏ผ› - ้…็ฝฎๆ–‡ไปถๅŠ ่ฝฝๅฎŒๆˆ๏ผˆ`configDidLoad`๏ผ‰๏ผ› - ๆ–‡ไปถๅŠ ่ฝฝๅฎŒๆˆ๏ผˆ`didLoad`๏ผ‰๏ผ› @@ -33,8 +34,8 @@ class AppBootHook { // ไพ‹ๅฆ‚๏ผšๅ‚ๆ•ฐไธญ็š„ๅฏ†็ ๆ˜ฏๅŠ ๅฏ†็š„๏ผŒๅœจๆญคๅค„่ฟ›่กŒ่งฃๅฏ† this.app.config.mysql.password = decrypt(this.app.config.mysql.password); // ไพ‹ๅฆ‚๏ผšๆ’ๅ…ฅไธ€ไธชไธญ้—ดไปถๅˆฐๆก†ๆžถ็š„ coreMiddleware ไน‹้—ด - const statusIdx = this.app.config.coreMiddleware.indexOf('status'); - this.app.config.coreMiddleware.splice(statusIdx + 1, 0, 'limit'); + const statusIdx = this.app.config.coreMiddleware.indexOf("status"); + this.app.config.coreMiddleware.splice(statusIdx + 1, 0, "limit"); } async didLoad() { @@ -46,8 +47,8 @@ class AppBootHook { await this.app.queue.init(); // ไพ‹ๅฆ‚๏ผšๅŠ ่ฝฝ่‡ชๅฎšไน‰็›ฎๅฝ• - this.app.loader.loadToContext(path.join(__dirname, 'app/tasks'), 'tasks', { - fieldClass: 'tasksClasses', + this.app.loader.loadToContext(path.join(__dirname, "app/tasks"), "tasks", { + fieldClass: "tasksClasses", }); } @@ -70,7 +71,7 @@ class AppBootHook { // http/https ๆœๅŠกๅ™จๅทฒๅฏๅŠจ๏ผŒๅผ€ๅง‹ๆŽฅๆ”ถๅค–้ƒจ่ฏทๆฑ‚ // ๆญคๆ—ถๅฏไปฅไปŽ app.server ่Žทๅ– server ๅฎžไพ‹ - this.app.server.on('timeout', socket => { + this.app.server.on("timeout", (socket) => { // ๅค„็† socket ่ถ…ๆ—ถ }); } @@ -81,4 +82,4 @@ module.exports = AppBootHook; **ๆณจๆ„๏ผšๅœจ่‡ชๅฎšไน‰็”Ÿๅ‘ฝๅ‘จๆœŸๅ‡ฝๆ•ฐไธญ๏ผŒไธๅปบ่ฎฎ่ฟ›่กŒ่€—ๆ—ถ็š„ๆ“ไฝœ๏ผŒๅ› ไธบๆก†ๆžถไผšๆœ‰ๅฏๅŠจ็š„่ถ…ๆ—ถๆฃ€ๆต‹ใ€‚** -ๅฆ‚ๆžœไฝ ็š„ Egg ๆก†ๆžถ็š„็”Ÿๅ‘ฝๅ‘จๆœŸๅ‡ฝๆ•ฐๆ˜ฏๆ—ง็‰ˆๆœฌ็š„๏ผŒๅปบ่ฎฎไฝ ๅฐ†ๅ…ถๅ‡็บงๅˆฐ็ฑปๆ–นๆณ•ๆจกๅผ๏ผ›่ฏฆๆƒ…่ฏทๆŸฅ็œ‹[ๅ‡็บงไฝ ็š„็”Ÿๅ‘ฝๅ‘จๆœŸไบ‹ไปถๅ‡ฝๆ•ฐ](../advanced/loader-update.md)ใ€‚ \ No newline at end of file +ๅฆ‚ๆžœไฝ ็š„ Egg ๆก†ๆžถ็š„็”Ÿๅ‘ฝๅ‘จๆœŸๅ‡ฝๆ•ฐๆ˜ฏๆ—ง็‰ˆๆœฌ็š„๏ผŒๅปบ่ฎฎไฝ ๅฐ†ๅ…ถๅ‡็บงๅˆฐ็ฑปๆ–นๆณ•ๆจกๅผ๏ผ›่ฏฆๆƒ…่ฏทๆŸฅ็œ‹[ๅ‡็บงไฝ ็š„็”Ÿๅ‘ฝๅ‘จๆœŸไบ‹ไปถๅ‡ฝๆ•ฐ](../advanced/loader-update.md)ใ€‚ diff --git a/site/docs/basics/config.md b/site/docs/basics/config.md index 5ff318f8ca..5827367b85 100644 --- a/site/docs/basics/config.md +++ b/site/docs/basics/config.md @@ -37,7 +37,7 @@ The configuration file returns an object which could overwrite some configuratio // configure the catalog of logger๏ผŒthe default configuration of logger is provided by framework module.exports = { logger: { - dir: '/home/admin/logs/demoapp', + dir: "/home/admin/logs/demoapp", }, }; ``` @@ -45,9 +45,9 @@ module.exports = { The configuration file can simplify to `exports.key = value` format ```js -exports.keys = 'my-cookie-secret-key'; +exports.keys = "my-cookie-secret-key"; exports.logger = { - level: 'DEBUG', + level: "DEBUG", }; ``` @@ -55,11 +55,11 @@ The configuration file can also return a function which could receive a paramete ```js // put the catalog of logger to the catalog of codes -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { logger: { - dir: path.join(appInfo.baseDir, 'logs'), + dir: path.join(appInfo.baseDir, "logs"), }, }; }; @@ -81,10 +81,10 @@ Choose the appropriate style according to the specific situation, but please mak ```js // config/config.default.js -exports.someKeys = 'abc'; +exports.someKeys = "abc"; module.exports = (appInfo) => { const config = {}; - config.keys = '123456'; + config.keys = "123456"; return config; }; ``` diff --git a/site/docs/basics/config.zh-CN.md b/site/docs/basics/config.zh-CN.md index 300911e9b3..498e50fceb 100644 --- a/site/docs/basics/config.zh-CN.md +++ b/site/docs/basics/config.zh-CN.md @@ -12,6 +12,7 @@ order: 4 3. ไฝฟ็”จไปฃ็ ็ฎก็†้…็ฝฎ๏ผŒๅœจไปฃ็ ไธญๆทปๅŠ ๅคšไธช็Žฏๅขƒ็š„้…็ฝฎ๏ผŒๅœจๅฏๅŠจๆ—ถไผ ๅ…ฅๅฝ“ๅ‰็Žฏๅขƒ็š„ๅ‚ๆ•ฐๅณๅฏใ€‚ไฝ†ๆ— ๆณ•ๅ…จๅฑ€้…็ฝฎ๏ผŒๅฟ…้กปไฟฎๆ”นไปฃ็ ใ€‚ ๆˆ‘ไปฌ้€‰ๆ‹ฉไบ†ๆœ€ๅŽไธ€็ง้…็ฝฎๆ–นๆกˆ๏ผŒ**้…็ฝฎๅณไปฃ็ **๏ผŒ้…็ฝฎ็š„ๅ˜ๆ›ดไนŸๅบ”่ฏฅ็ป่ฟ‡ๅฎกๆ ธๅŽๆ‰่ƒฝๅ‘ๅธƒใ€‚ๅบ”็”จๅŒ…ๆœฌ่บซๆ˜ฏๅฏไปฅ้ƒจ็ฝฒๅœจๅคšไธช็Žฏๅขƒ็š„๏ผŒๅช้œ€่ฆๆŒ‡ๅฎš่ฟ่กŒ็Žฏๅขƒๅณๅฏใ€‚ + ### ๅคš็Žฏๅขƒ้…็ฝฎ ๆก†ๆžถๆ”ฏๆŒๆ นๆฎ็ŽฏๅขƒๆฅๅŠ ่ฝฝ้…็ฝฎ๏ผŒๅฎšไน‰ๅคšไธช็Žฏๅขƒ็š„้…็ฝฎๆ–‡ไปถ๏ผŒๅ…ทไฝ“็Žฏๅขƒ่ฏทๆŸฅ็œ‹[่ฟ่กŒ็Žฏๅขƒ้…็ฝฎ](./env.md)ใ€‚ @@ -27,6 +28,7 @@ config `config.default.js` ไธบ้ป˜่ฎค็š„้…็ฝฎๆ–‡ไปถ๏ผŒๆ‰€ๆœ‰็Žฏๅขƒ้ƒฝไผšๅŠ ่ฝฝ่ฟ™ไธช้…็ฝฎๆ–‡ไปถ๏ผŒไธ€่ˆฌไนŸไผšไฝœไธบๅผ€ๅ‘็Žฏๅขƒ็š„้ป˜่ฎค้…็ฝฎๆ–‡ไปถใ€‚ ๅฝ“ๆŒ‡ๅฎš `env` ๆ—ถ๏ผŒไผšๅŒๆ—ถๅŠ ่ฝฝ้ป˜่ฎค้…็ฝฎๅ’Œๅฏนๅบ”็š„้…็ฝฎ๏ผˆๅ…ทๅ้…็ฝฎ๏ผ‰ๆ–‡ไปถใ€‚ๅ…ทๅ้…็ฝฎๅ’Œ้ป˜่ฎค้…็ฝฎๅฐ†ๅˆๅนถ๏ผˆไฝฟ็”จ [extend2](https://www.npmjs.com/package/extend2) ๆทฑๆ‹ท่ด๏ผ‰ๆˆๆœ€็ปˆ้…็ฝฎ๏ผŒๅ…ทๅ้…็ฝฎ้กนไผš่ฆ†็›–้ป˜่ฎค้…็ฝฎๆ–‡ไปถ็š„ๅŒๅ้…็ฝฎใ€‚ไพ‹ๅฆ‚๏ผŒ`prod` ็ŽฏๅขƒไผšๅŠ ่ฝฝ `config.prod.js` ๅ’Œ `config.default.js` ๆ–‡ไปถ๏ผŒ`config.prod.js` ไผš่ฆ†็›– `config.default.js` ็š„ๅŒๅ้…็ฝฎใ€‚ + ### ้…็ฝฎๅ†™ๆณ• ้…็ฝฎๆ–‡ไปถ่ฟ”ๅ›ž็š„ๆ˜ฏไธ€ไธชๅฏน่ฑก๏ผŒๅฏไปฅ่ฆ†็›–ๆก†ๆžถ็š„ไธ€ไบ›้…็ฝฎ๏ผŒๅบ”็”จไนŸๅฏไปฅๅฐ†่‡ชๅทฑไธšๅŠก็š„้…็ฝฎๆ”พๅˆฐ่ฟ™้‡Œๆ–นไพฟ็ฎก็†ใ€‚ @@ -35,7 +37,7 @@ config // ้…็ฝฎ logger ๆ–‡ไปถ็š„็›ฎๅฝ•๏ผŒlogger ้ป˜่ฎค้…็ฝฎ็”ฑๆก†ๆžถๆไพ› module.exports = { logger: { - dir: '/home/admin/logs/demoapp', + dir: "/home/admin/logs/demoapp", }, }; ``` @@ -43,9 +45,9 @@ module.exports = { ้…็ฝฎๆ–‡ไปถไนŸๅฏไปฅ็ฎ€ๅŒ–ๅœฐๅ†™ๆˆ `exports.key = value` ๅฝขๅผ๏ผš ```js -exports.keys = 'my-cookie-secret-key'; +exports.keys = "my-cookie-secret-key"; exports.logger = { - level: 'DEBUG', + level: "DEBUG", }; ``` @@ -53,11 +55,11 @@ exports.logger = { ```js // ๅฐ† logger ็›ฎๅฝ•ๆ”พๅˆฐไปฃ็ ็›ฎๅฝ•ไธ‹ -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { logger: { - dir: path.join(appInfo.baseDir, 'logs'), + dir: path.join(appInfo.baseDir, "logs"), }, }; }; @@ -65,12 +67,12 @@ module.exports = (appInfo) => { ๅ†…็ฝฎ็š„ `appInfo` ๅฑžๆ€งๅŒ…ๆ‹ฌ๏ผš -| appInfo | ่ฏดๆ˜Ž | -| ------- | ------------------------------------------------------------ | -| pkg | `package.json` ๆ–‡ไปถ | -| name | ๅบ”็”จๅ็งฐ๏ผŒๅŒ `pkg.name` | -| baseDir | ๅบ”็”จไปฃ็ ็š„็›ฎๅฝ• | -| HOME | ็”จๆˆท็›ฎๅฝ•๏ผŒๅฆ‚ admin ่ดฆๆˆทไธบ `/home/admin` | +| appInfo | ่ฏดๆ˜Ž | +| ------- | -------------------------------------------------------------------------- | +| pkg | `package.json` ๆ–‡ไปถ | +| name | ๅบ”็”จๅ็งฐ๏ผŒๅŒ `pkg.name` | +| baseDir | ๅบ”็”จไปฃ็ ็š„็›ฎๅฝ• | +| HOME | ็”จๆˆท็›ฎๅฝ•๏ผŒๅฆ‚ admin ่ดฆๆˆทไธบ `/home/admin` | | root | ๅบ”็”จๆ น็›ฎๅฝ•๏ผŒๅœจ `local` ๅ’Œ `unittest` ็Žฏๅขƒไธ‹ไธบ `baseDir`๏ผŒๅ…ถไป–้ƒฝไธบ `HOME`ใ€‚ | `appInfo.root` ๆ˜ฏไธ€ไธชไผ˜้›…็š„้€‚้…ๆ–นๆกˆใ€‚ไพ‹ๅฆ‚๏ผŒๅœจๆœๅŠกๅ™จ็Žฏๅขƒๆˆ‘ไปฌ้€šๅธธไฝฟ็”จ `/home/admin/logs` ไฝœไธบๆ—ฅๅฟ—็›ฎๅฝ•๏ผŒ่€Œๅœจๆœฌๅœฐๅผ€ๅ‘ๆ—ถไธบไบ†้ฟๅ…ๆฑกๆŸ“็”จๆˆท็›ฎๅฝ•๏ผŒๆˆ‘ไปฌ้œ€่ฆไธ€็งไผ˜้›…็š„้€‚้…ๆ–นๆกˆ๏ผŒ`appInfo.root` ๆญฃๅฅฝ่งฃๅ†ณไบ†่ฟ™ไธช้—ฎ้ข˜ใ€‚ @@ -79,10 +81,10 @@ module.exports = (appInfo) => { ```js // ้…็ฝฎๆ–‡ไปถ config/config.default.js -exports.someKeys = 'abc'; +exports.someKeys = "abc"; module.exports = (appInfo) => { const config = {}; - config.keys = '123456'; + config.keys = "123456"; return config; }; ``` @@ -103,6 +105,7 @@ module.exports = (appInfo) => { ``` **ๆณจๆ„**๏ผšๆ’ไปถไน‹้—ดไนŸไผšๆœ‰ๅŠ ่ฝฝ้กบๅบ๏ผŒไฝ†ๅคง่‡ด้กบๅบ็ฑปไผผใ€‚ๅ…ทไฝ“้€ป่พ‘ๅฏ[ๆŸฅ็œ‹ๅŠ ่ฝฝๅ™จ](../advanced/loader.md)ใ€‚ + ### ๅˆๅนถ่ง„ๅˆ™ ้…็ฝฎ็š„ๅˆๅนถไฝฟ็”จ `extend2` ๆจกๅ—่ฟ›่กŒๆทฑๅบฆๆ‹ท่ด๏ผŒ`extend2` ๆฅๆบไบŽ `extend`๏ผŒไฝ†ๆ˜ฏๅœจๅค„็†ๆ•ฐ็ป„ๆ—ถ็š„่กจ็Žฐไผšๆœ‰ๆ‰€ไธๅŒใ€‚ diff --git a/site/docs/basics/controller.md b/site/docs/basics/controller.md index 02dcfaad27..2e2618baec 100644 --- a/site/docs/basics/controller.md +++ b/site/docs/basics/controller.md @@ -30,13 +30,13 @@ You can write a Controller by defining a Controller class: ```js // app/controller/post.js -const Controller = require('egg').Controller; +const Controller = require("egg").Controller; class PostController extends Controller { async create() { const { ctx, service } = this; const createRule = { - title: { type: 'string' }, - content: { type: 'string' }, + title: { type: "string" }, + content: { type: "string" }, }; // verify parameters ctx.validate(createRule); @@ -59,7 +59,7 @@ We've defined a `PostController` class above and every method of this Controller // app/router.js module.exports = (app) => { const { router, controller } = app; - router.post('createPost', '/api/posts', controller.post.create); + router.post("createPost", "/api/posts", controller.post.create); }; ``` @@ -68,7 +68,7 @@ Multi-level directory is supported, for example, put the above code into `app/co ```js // app/router.js module.exports = (app) => { - app.router.post('createPost', '/api/posts', app.controller.sub.post.create); + app.router.post("createPost", "/api/posts", app.controller.sub.post.create); }; ``` @@ -86,7 +86,7 @@ Defining a Controller class helps us not only abstract the Controller layer code ```js // app/core/base_controller.js -const { Controller } = require('egg'); +const { Controller } = require("egg"); class BaseController extends Controller { get user() { return this.ctx.session.user; @@ -100,7 +100,7 @@ class BaseController extends Controller { } notFound(msg) { - msg = msg || 'not found'; + msg = msg || "not found"; this.ctx.throw(404, msg); } } @@ -111,7 +111,7 @@ Now we can use base class' methods by inheriting from `BaseController`: ```js //app/controller/post.js -const Controller = require('../core/base_controller'); +const Controller = require("../core/base_controller"); class PostController extends Controller { async list() { const posts = await this.service.listByUser(this.user); @@ -130,8 +130,8 @@ For example, when we define a Controller relative to `POST /api/posts`, we creat // app/controller/post.js exports.create = async (ctx) => { const createRule = { - title: { type: 'string' }, - content: { type: 'string' }, + title: { type: "string" }, + content: { type: "string" }, }; // verify parameters ctx.validate(createRule); @@ -223,8 +223,8 @@ If duplicated keys exist in Query String, only the first value of this key is us This is for unity reason, because we usually do not design users to pass parameters with same keys in Query String then we write codes like below: ```js -const key = ctx.query.key || ''; -if (key.startsWith('egg')) { +const key = ctx.query.key || ""; +if (key.startsWith("egg")) { // do something } ``` @@ -259,8 +259,8 @@ In [Router](./router.md) part, we say Router is allowed to declare parameters wh // GET /projects/1/app/2 class AppController extends Controller { async listApp() { - assert.equal(this.ctx.params.projectId, '1'); - assert.equal(this.ctx.params.appId, '2'); + assert.equal(this.ctx.params.projectId, "1"); + assert.equal(this.ctx.params.appId, "2"); } } ``` @@ -284,8 +284,8 @@ The [bodyParser](https://github.com/koajs/bodyparser) middleware is built in by // {"title": "controller", "content": "what is controller"} class PostController extends Controller { async listPosts() { - assert.equal(this.ctx.request.body.title, 'controller'); - assert.equal(this.ctx.request.body.content, 'what is controller'); + assert.equal(this.ctx.request.body.title, "controller"); + assert.equal(this.ctx.request.body.content, "what is controller"); } } ``` @@ -301,8 +301,8 @@ The mostly adjusted config field is the maximum length of the request body for p ```js module.exports = { bodyParser: { - jsonLimit: '1mb', - formLimit: '1mb', + jsonLimit: "1mb", + formLimit: "1mb", }, }; ``` @@ -325,7 +325,7 @@ The `body` in the request can carry parameters as well as files. Generally speak ```js // config/config.default.js exports.multipart = { - mode: 'file', + mode: "file", }; ``` @@ -336,11 +336,7 @@ exports.multipart = { Your HTML static front-end codes should look like this below: ```html -
+ title: file:
@@ -350,14 +346,14 @@ The corresponding backend codes are: ```js // app/controller/upload.js -const Controller = require('egg').Controller; -const fs = require('fs/promises'); +const Controller = require("egg").Controller; +const fs = require("fs/promises"); module.exports = class extends Controller { async upload() { const { ctx } = this; const file = ctx.request.files[0]; - const name = 'egg-multipart-test/' + path.basename(file.filename); + const name = "egg-multipart-test/" + path.basename(file.filename); let result; try { // process file (e.g: upload to cloud storage) @@ -383,11 +379,7 @@ For multiple files, with the help of `ctx.request.files`, we can loop each of th Your HTML static front-end codes should look like this below: ```html -
+ title: file1: file2: @@ -398,27 +390,24 @@ The corresponding backend codes are: ```js // app/controller/upload.js -const Controller = require('egg').Controller; -const fs = require('fs/promises'); +const Controller = require("egg").Controller; +const fs = require("fs/promises"); module.exports = class extends Controller { async upload() { const { ctx } = this; console.log(ctx.request.body); - console.log('got %d files', ctx.request.files.length); + console.log("got %d files", ctx.request.files.length); for (const file of ctx.request.files) { - console.log('field: ' + file.fieldname); - console.log('filename: ' + file.filename); - console.log('encoding: ' + file.encoding); - console.log('mime: ' + file.mime); - console.log('tmp filepath: ' + file.filepath); + console.log("field: " + file.fieldname); + console.log("filename: " + file.filename); + console.log("encoding: " + file.encoding); + console.log("mime: " + file.mime); + console.log("tmp filepath: " + file.filepath); let result; try { // process file (e.g: upload to cloud storage) - result = await ctx.oss.put( - 'egg-multipart-test/' + file.filename, - file.filepath, - ); + result = await ctx.oss.put("egg-multipart-test/" + file.filename, file.filepath); } finally { // need to remove the tmp file await fs.unlink(file.filepath); @@ -435,26 +424,22 @@ module.exports = class extends Controller { 1. For Single File๏ผš ```html - + title: file:
``` ```js -const path = require('path'); -const sendToWormhole = require('stream-wormhole'); -const Controller = require('egg').Controller; +const path = require("path"); +const sendToWormhole = require("stream-wormhole"); +const Controller = require("egg").Controller; class UploaderController extends Controller { async upload() { const ctx = this.ctx; const stream = await ctx.getFileStream(); - const name = 'egg-multipart-test/' + path.basename(stream.filename); + const name = "egg-multipart-test/" + path.basename(stream.filename); let result; try { // process file (e.g: upload to cloud storage) @@ -486,8 +471,8 @@ To acquire the uploaded files easily, there're two conditions at least: For multiple files, you should do the following instead of using `ctx.getFileStream()`: ```js -const sendToWormhole = require('stream-wormhole'); -const Controller = require('egg').Controller; +const sendToWormhole = require("stream-wormhole"); +const Controller = require("egg").Controller; class UploaderController extends Controller { async upload() { @@ -498,10 +483,10 @@ class UploaderController extends Controller { while ((part = await parts()) != null) { if (part.length) { // arrays are busboy fields - console.log('field: ' + part[0]); - console.log('value: ' + part[1]); - console.log('valueTruncated: ' + part[2]); - console.log('fieldnameTruncated: ' + part[3]); + console.log("field: " + part[0]); + console.log("value: " + part[1]); + console.log("valueTruncated: " + part[2]); + console.log("fieldnameTruncated: " + part[3]); } else { if (!part.filename) { // When a user clicks `upload` before choosing a file, @@ -511,17 +496,14 @@ class UploaderController extends Controller { return; } // otherwise, it's a fully-filled stream - console.log('field: ' + part.fieldname); - console.log('filename: ' + part.filename); - console.log('encoding: ' + part.encoding); - console.log('mime: ' + part.mime); + console.log("field: " + part.fieldname); + console.log("filename: " + part.filename); + console.log("encoding: " + part.encoding); + console.log("mime: " + part.mime); let result; try { // process file (e.g: upload to cloud storage) - result = await ctx.oss.put( - 'egg-multipart-test/' + part.filename, - part, - ); + result = await ctx.oss.put("egg-multipart-test/" + part.filename, part); } catch (err) { // You MUST consume the file stream, otherwises the browser cannot response any more await sendToWormhole(part); @@ -530,7 +512,7 @@ class UploaderController extends Controller { console.log(result); } } - console.log('and we are done parsing the form!'); + console.log("and we are done parsing the form!"); } } @@ -572,7 +554,7 @@ Users can add new file extensions in `config/config.default.js`, or rewrite a wh ```js module.exports = { multipart: { - fileExtensions: ['.apk'], // Add support for apk files + fileExtensions: [".apk"], // Add support for apk files }, }; ``` @@ -582,7 +564,7 @@ module.exports = { ```js module.exports = { multipart: { - whitelist: ['.png'], // ONLY files of png is allowed + whitelist: [".png"], // ONLY files of png is allowed }, }; ``` @@ -640,15 +622,15 @@ Through `ctx.cookies`, we can conveniently and safely set and get Cookie in Cont class CookieController extends Controller { async add() { const ctx = this.ctx; - let count = ctx.cookies.get('count'); + let count = ctx.cookies.get("count"); count = count ? Number(count) : 0; - ctx.cookies.set('count', ++count); + ctx.cookies.set("count", ++count); ctx.body = count; } async remove() { const ctx = this.ctx; - const count = ctx.cookies.set('count', null); + const count = ctx.cookies.set("count", null); ctx.status = 204; } } @@ -676,7 +658,7 @@ e.g.: Configured application level Cookie [SameSite](https://www.ruanyifeng.com/ ```js module.exports = { cookies: { - sameSite: 'lax', + sameSite: "lax", }, }; ``` @@ -722,7 +704,7 @@ There are mainly these attributes below can be used to configure Session in `con ```js module.exports = { - key: 'EGG_SESS', // the name of key-value pairs, which is specially used by Cookie to store Session + key: "EGG_SESS", // the name of key-value pairs, which is specially used by Cookie to store Session maxAge: 86400000, // Session maximum valid time }; ``` @@ -737,7 +719,7 @@ With the help of the convenient parameter validation mechanism provided by [Vali // config/plugin.js exports.validate = { enable: true, - package: 'egg-validate', + package: "egg-validate", }; ``` @@ -749,8 +731,8 @@ class PostController extends Controller { // validate parameters // if the second parameter is absent, `ctx.request.body` is validated automatically this.ctx.validate({ - title: { type: 'string' }, - content: { type: 'string' }, + title: { type: "string" }, + content: { type: "string" }, }); } } @@ -783,11 +765,11 @@ In addition to built-in validation types introduced in the previous section, som ```js // app.js -app.validator.addRule('json', (rule, value) => { +app.validator.addRule("json", (rule, value) => { try { JSON.parse(value); } catch (err) { - return 'must be json string'; + return "must be json string"; } }); ``` @@ -799,7 +781,7 @@ class PostController extends Controller { async handler() { const ctx = this.ctx; // query.test field must be a json string - const rule = { test: 'json' }; + const rule = { test: "json" }; ctx.validate(rule, ctx.query); } } @@ -861,14 +843,14 @@ Most data is sent to requesters through the body and, just like the body in the class ViewController extends Controller { async show() { this.ctx.body = { - name: 'egg', - category: 'framework', - language: 'Node.js', + name: "egg", + category: "framework", + language: "Node.js", }; } async page() { - this.ctx.body = '

Hello

'; + this.ctx.body = "

Hello

"; } } ``` @@ -898,7 +880,7 @@ Egg itself does not integrate any template engine, but it establishes the [View class HomeController extends Controller { async index() { const ctx = this.ctx; - await ctx.render('home.tpl', { name: 'egg' }); + await ctx.render("home.tpl", { name: "egg" }); // ctx.body = await ctx.renderString('hi, {{ name }}', { name: 'egg' }); } } @@ -918,8 +900,8 @@ Since misuse of JSONP leads to dozens of security issues, the framework supplies // app/router.js module.exports = (app) => { const jsonp = app.jsonp(); - app.router.get('/api/posts/:id', jsonp, app.controller.posts.show); - app.router.get('/api/posts', jsonp, app.controller.posts.list); + app.router.get("/api/posts/:id", jsonp, app.controller.posts.show); + app.router.get("/api/posts", jsonp, app.controller.posts.list); }; ``` @@ -930,9 +912,9 @@ module.exports = (app) => { class PostController extends Controller { async show() { this.ctx.body = { - name: 'egg', - category: 'framework', - language: 'Node.js', + name: "egg", + category: "framework", + language: "Node.js", }; } } @@ -947,7 +929,7 @@ By default, the framework determines whether to return data in JSONP format or n ```js // config/config.default.js exports.jsonp = { - callback: 'callback', // inspecting the `callback` parameter in the query + callback: "callback", // inspecting the `callback` parameter in the query limit: 100, // the maximum size of the method name is 100 characters }; ``` @@ -960,12 +942,8 @@ Also we can overwrite the default configuration in `app.jsonp()` when creating t // app/router.js module.exports = (app) => { const { router, controller, jsonp } = app; - router.get( - '/api/posts/:id', - jsonp({ callback: 'callback' }), - controller.posts.show, - ); - router.get('/api/posts', jsonp({ callback: 'cb' }), controller.posts.list); + router.get("/api/posts/:id", jsonp({ callback: "callback" }), controller.posts.show); + router.get("/api/posts", jsonp({ callback: "cb" }), controller.posts.list); }; ``` @@ -1027,7 +1005,7 @@ exports.jsonp = { ```js exports.jsonp = { - whiteList: '.test.com', + whiteList: ".test.com", }; // matches domain test.com: // https://test.com/hello @@ -1038,7 +1016,7 @@ exports.jsonp = { // http://sub.sub.test.com/ exports.jsonp = { - whiteList: 'sub.test.com', + whiteList: "sub.test.com", }; // only matches domain sub.test.com: // https://sub.test.com/hello @@ -1049,7 +1027,7 @@ exports.jsonp = { ```js exports.jsonp = { - whiteList: ['sub.test.com', 'sub2.test.com'], + whiteList: ["sub.test.com", "sub2.test.com"], }; // matches domain sub.test.com and sub2.test.com: // https://sub.test.com/hello @@ -1073,7 +1051,7 @@ class ProxyController extends Controller { ctx.body = await ctx.service.post.get(); const used = Date.now() - start; // set one response header - ctx.set('show-response-time', used.toString()); + ctx.set("show-response-time", used.toString()); } } ``` @@ -1090,7 +1068,7 @@ If you use the `ctx.redirect` method, you need to configure the application conf ```js // config/config.default.js exports.security = { - domainWhiteList: ['.domain.com'], // Security whitelist, starts with `.` + domainWhiteList: [".domain.com"], // Security whitelist, starts with `.` }; ``` diff --git a/site/docs/basics/controller.zh-CN.md b/site/docs/basics/controller.zh-CN.md index bed3b21d76..ce4c976b42 100644 --- a/site/docs/basics/controller.zh-CN.md +++ b/site/docs/basics/controller.zh-CN.md @@ -19,6 +19,7 @@ order: 7 2. ๆ ก้ชŒใ€็ป„่ฃ…ๅ‚ๆ•ฐใ€‚ 3. ่ฐƒ็”จ Service ่ฟ›่กŒไธšๅŠกๅค„็†๏ผŒๅฟ…่ฆๆ—ถๅค„็†่ฝฌๆข Service ็š„่ฟ”ๅ›ž็ป“ๆžœ๏ผŒ่ฎฉๅฎƒ้€‚ๅบ”็”จๆˆท็š„้œ€ๆฑ‚ใ€‚ 4. ้€š่ฟ‡ HTTP ๅฐ†็ป“ๆžœๅ“ๅบ”็ป™็”จๆˆทใ€‚ + ## ๅฆ‚ไฝ•็ผ–ๅ†™ Controller ๆ‰€ๆœ‰็š„ Controller ๆ–‡ไปถ้ƒฝๅฟ…้กปๆ”พๅœจ `app/controller` ็›ฎๅฝ•ไธ‹๏ผŒๅฏไปฅๆ”ฏๆŒๅคš็บง็›ฎๅฝ•๏ผŒ่ฎฟ้—ฎ็š„ๆ—ถๅ€™ๅฏไปฅ้€š่ฟ‡็›ฎๅฝ•ๅ็บง่”่ฎฟ้—ฎใ€‚Controller ๆ”ฏๆŒๅคš็งๅฝขๅผ่ฟ›่กŒ็ผ–ๅ†™๏ผŒๅฏไปฅๆ นๆฎไธๅŒ็š„้กน็›ฎๅœบๆ™ฏๅ’Œๅผ€ๅ‘ไน ๆƒฏๆฅ้€‰ๆ‹ฉใ€‚ @@ -29,13 +30,13 @@ order: 7 ```javascript // app/controller/post.js -const Controller = require('egg').Controller; +const Controller = require("egg").Controller; class PostController extends Controller { async create() { const { ctx, service } = this; const createRule = { - title: { type: 'string' }, - content: { type: 'string' }, + title: { type: "string" }, + content: { type: "string" }, }; // ๆ ก้ชŒๅ‚ๆ•ฐ ctx.validate(createRule); @@ -58,7 +59,7 @@ module.exports = PostController; // app/router.js module.exports = (app) => { const { router, controller } = app; - router.post('createPost', '/api/posts', controller.post.create); + router.post("createPost", "/api/posts", controller.post.create); }; ``` @@ -66,8 +67,8 @@ Controller ๆ”ฏๆŒๅคš็บง็›ฎๅฝ•ใ€‚ไพ‹ๅฆ‚๏ผŒๅฆ‚ๆžœๆˆ‘ไปฌๅฐ†ไธŠ้ข็š„ Controller ไปฃ ```javascript // app/router.js -module.exports = app => { - app.router.post('createPost', '/api/posts', app.controller.sub.post.create); +module.exports = (app) => { + app.router.post("createPost", "/api/posts", app.controller.sub.post.create); }; ``` @@ -85,7 +86,7 @@ module.exports = app => { ```javascript // app/core/base_controller.js -const { Controller } = require('egg'); +const { Controller } = require("egg"); class BaseController extends Controller { get user() { return this.ctx.session.user; @@ -99,7 +100,7 @@ class BaseController extends Controller { } notFound(msg) { - msg = msg || 'not found'; + msg = msg || "not found"; this.ctx.throw(404, msg); } } @@ -110,7 +111,7 @@ module.exports = BaseController; ```javascript // app/controller/post.js -const Controller = require('../core/base_controller'); +const Controller = require("../core/base_controller"); class PostController extends Controller { async list() { const posts = await this.service.listByUser(this.user); @@ -127,10 +128,10 @@ class PostController extends Controller { ```javascript // app/controller/post.js -exports.create = async ctx => { +exports.create = async (ctx) => { const createRule = { - title: { type: 'string' }, - content: { type: 'string' }, + title: { type: "string" }, + content: { type: "string" }, }; // ๆ ก้ชŒๅ‚ๆ•ฐ ctx.validate(createRule); @@ -146,6 +147,7 @@ exports.create = async ctx => { ``` ไปฅไธŠๆ˜ฏไธ€ไธช็ฎ€ๅ•็›ด่ง‚็š„ไพ‹ๅญ๏ผŒๆˆ‘ไปฌๅผ•ๅ…ฅไบ†ไธ€ไบ›ๆ–ฐ็š„ๆฆ‚ๅฟต๏ผŒไฝ†ๅฎƒไปฌ้ƒฝๆ˜ฏๆ˜“ไบŽ็†่งฃ็š„ใ€‚ๆˆ‘ไปฌๅฐ†ๅœจๅŽ้ขๅฏนๅฎƒไปฌ่ฟ›่กŒๆ›ด่ฏฆ็ป†็š„ไป‹็ปใ€‚ + ## HTTP ๅŸบ็ก€ ็”ฑไบŽๆŽงๅˆถๅ™จ๏ผˆController๏ผ‰ๅŸบๆœฌไธŠๆ˜ฏไธšๅŠกๅผ€ๅ‘ไธญๅ”ฏไธ€ไธŽ HTTP ๅ่ฎฎๆ‰“ไบค้“็š„ๅœฐๆ–น๏ผŒๅœจ็ปง็ปญๆทฑๅ…ฅไบ†่งฃไน‹ๅ‰๏ผŒๆˆ‘ไปฌ้ฆ–ๅ…ˆ่ฆ็ฎ€ๅ•ไบ†่งฃไธ€ไธ‹ HTTP ๅ่ฎฎๆœฌ่บซใ€‚ @@ -195,6 +197,7 @@ Connection: keep-alive ๅ“ๅบ”ๅคดไปŽ็ฌฌไบŒ่กŒ่‡ณไธ‹ไธ€ไธช็ฉบ่กŒ๏ผŒ่ฟ™้‡Œ็š„ Content-Type ๅ’Œ Content-Length ่กจๆ˜Žๅ“ๅบ”ๆ ผๅผไธบ JSON๏ผŒ้•ฟๅบฆ 8 ๅญ—่Š‚ใ€‚ ๆœ€ๅŽ้ƒจๅˆ†ๅณๅ“ๅบ”ๅฎž้™…ๅ†…ๅฎนใ€‚ + ## ่Žทๅ– HTTP ่ฏทๆฑ‚ๅ‚ๆ•ฐ ไปŽไธŠ่ฟฐ HTTP ่ฏทๆฑ‚็คบไพ‹ไธญ, ๆˆ‘ไปฌๅฏไปฅ็œ‹ๅˆฐ, ๅคšไธชไฝ็ฝฎๅฏไปฅๆ”พ็ฝฎ็”จๆˆท็š„่ฏทๆฑ‚ๆ•ฐๆฎใ€‚ๆก†ๆžถ้€š่ฟ‡ๅœจ Controller ไธŠ็ป‘ๅฎš็š„ Context ๅฎžไพ‹, ๆไพ›ไบ†ๅคš็งไพฟๆทๆ–นๆณ•ๅ’Œๅฑžๆ€ง, ไปฅ่Žทๅ–็”จๆˆท้€š่ฟ‡ HTTP ่ฏทๆฑ‚ๅ‘้€่ฟ‡ๆฅ็š„ๅ‚ๆ•ฐใ€‚ @@ -221,8 +224,8 @@ class PostController extends Controller { ไน‹ๆ‰€ไปฅ่ฟ™ๆ ทๅค„็†ๆ˜ฏไธบไบ†ไฟๆŒไธ€่‡ดๆ€งใ€‚ไธ€่ˆฌๆˆ‘ไปฌไธไผš่ฎพ่ฎก่ฎฉ็”จๆˆทไผ ้€’็›ธๅŒ key ็š„ Query String๏ผŒๆ‰€ไปฅ็ปๅธธ็ผ–ๅ†™ๅฆ‚ไธ‹ไปฃ็ ๏ผš ```js -const key = ctx.query.key || ''; -if (key.startsWith('egg')) { +const key = ctx.query.key || ""; +if (key.startsWith("egg")) { // ๆ‰ง่กŒ็›ธๅบ”ๆ“ไฝœ } ``` @@ -258,8 +261,8 @@ class PostController extends Controller { // GET /projects/1/app/2 class AppController extends Controller { async listApp() { - assert.equal(this.ctx.params.projectId, '1'); - assert.equal(this.ctx.params.appId, '2'); + assert.equal(this.ctx.params.projectId, "1"); + assert.equal(this.ctx.params.appId, "2"); } } ``` @@ -283,8 +286,8 @@ class AppController extends Controller { // {"title": "controller", "content": "what is controller"} class PostController extends Controller { async listPosts() { - assert.equal(this.ctx.request.body.title, 'controller'); - assert.equal(this.ctx.request.body.content, 'what is controller'); + assert.equal(this.ctx.request.body.title, "controller"); + assert.equal(this.ctx.request.body.content, "what is controller"); } } ``` @@ -300,8 +303,8 @@ class PostController extends Controller { ```js module.exports = { bodyParser: { - jsonLimit: '1mb', - formLimit: '1mb', + jsonLimit: "1mb", + formLimit: "1mb", }, }; ``` @@ -311,6 +314,7 @@ module.exports = { **ๆณจๆ„๏ผš่ฐƒๆ•ด bodyParser ๆ”ฏๆŒ็š„ body ้•ฟๅบฆๆ—ถ๏ผŒๅฆ‚ๆžœๅบ”็”จไน‹ๅ‰ๆœ‰ไธ€ๅฑ‚ๅๅ‘ไปฃ็†๏ผˆๅฆ‚ Nginx๏ผ‰๏ผŒๅŒๆ ท้œ€่ฆ่ฐƒๆ•ด้…็ฝฎ็กฎไฟๆ”ฏๆŒ็›ธ็ญ‰้•ฟๅบฆ็š„่ฏทๆฑ‚ bodyใ€‚** **ๅธธ่ง้”™่ฏฏ๏ผšๅฐ† `ctx.request.body` ไธŽ `ctx.body` ๆททๆท†๏ผŒๅŽ่€…ๅฎž้™…ไธŠๆ˜ฏ `ctx.response.body` ็š„็ฎ€ๅ†™ใ€‚** + ### ่Žทๅ–ไธŠไผ ็š„ๆ–‡ไปถ ่ฏทๆฑ‚ไฝ“้™คไบ†ๅฏไปฅๅธฆๅ‚ๆ•ฐไน‹ๅค–๏ผŒ่ฟ˜ๅฏไปฅๅ‘้€ๆ–‡ไปถใ€‚้€šๅธธๆƒ…ๅ†ตไธ‹๏ผŒๆต่งˆๅ™จไผš้€š่ฟ‡ `Multipart/form-data` ๆ ผๅผๅ‘้€ๆ–‡ไปถใ€‚้€š่ฟ‡ๅ†…็ฝฎ็š„ [Multipart](https://github.com/eggjs/egg-multipart) ๆ’ไปถ๏ผŒๆก†ๆžถๆ”ฏๆŒ่Žทๅ–็”จๆˆทไธŠไผ ็š„ๆ–‡ไปถใ€‚ๆˆ‘ไปฌไธบไฝ ๆไพ›ไบ†ไธค็งๆ–นๅผ๏ผš @@ -324,7 +328,7 @@ module.exports = { ```javascript // config/config.default.js exports.multipart = { - mode: 'file', + mode: "file", }; ``` @@ -336,8 +340,7 @@ exports.multipart = { ```html
- title: - file: + title: file:
``` @@ -346,15 +349,15 @@ exports.multipart = { ```javascript // app/controller/upload.js -const Controller = require('egg').Controller; -const fs = require('fs/promises'); -const path = require('path'); // ่กฅไธŠ็ผบๅคฑ็š„ path ๆจกๅ— +const Controller = require("egg").Controller; +const fs = require("fs/promises"); +const path = require("path"); // ่กฅไธŠ็ผบๅคฑ็š„ path ๆจกๅ— class UploadController extends Controller { async upload() { const { ctx } = this; const file = ctx.request.files[0]; - const name = 'egg-multipart-test/' + path.basename(file.filename); + const name = "egg-multipart-test/" + path.basename(file.filename); let result; try { // ๅค„็†ๆ–‡ไปถ๏ผŒไพ‹ๅฆ‚ไธŠไผ ๅˆฐไบ‘้‡‡ๅญ˜ๅ‚จ @@ -381,9 +384,8 @@ module.exports = UploadController; ```html
- title: - file1: - file2: + title: file1: file2: +
``` @@ -392,9 +394,9 @@ module.exports = UploadController; ```javascript // app/controller/upload.js -const Controller = require('egg').Controller; -const fs = require('fs/promises'); -const path = require('path'); // ่กฅไธŠ็ผบๅคฑ็š„ path ๆจกๅ— +const Controller = require("egg").Controller; +const fs = require("fs/promises"); +const path = require("path"); // ่กฅไธŠ็ผบๅคฑ็š„ path ๆจกๅ— class UploadController extends Controller { async upload() { @@ -410,10 +412,7 @@ class UploadController extends Controller { let result; try { // ๅค„็†ๆ–‡ไปถ๏ผŒไพ‹ๅฆ‚ไธŠไผ ๅˆฐไบ‘้‡‡ๅญ˜ๅ‚จ - result = await ctx.oss.put( - 'egg-multipart-test/' + file.filename, - file.filepath, - ); + result = await ctx.oss.put("egg-multipart-test/" + file.filename, file.filepath); } finally { // ๆณจๆ„ๅˆ ้™คไธดๆ—ถๆ–‡ไปถ await fs.unlink(file.filepath); @@ -427,6 +426,7 @@ module.exports = UploadController; ``` ไปฅไธŠไปฃ็ ๅŒ…ๆถตไบ†ๅ‰็ซฏ็š„่กจๅ•ไปฃ็ ไปฅๅŠๅŽ็ซฏๅค„็†ไธŠไผ ๆ–‡ไปถ็š„ไปฃ็ ใ€‚ๅœจๆœๅŠกๅ™จ็ซฏ๏ผŒๆˆ‘ไปฌ้ฆ–ๅ…ˆ่Žทๅ–ไธŠไผ ๆ–‡ไปถ็š„ไฟกๆฏ๏ผŒ็„ถๅŽๅฐ†ๆ–‡ไปถไธŠไผ ๅˆฐๆŒ‡ๅฎš็š„ๅ‚จๅญ˜็ณป็ปŸ๏ผŒไพ‹ๅฆ‚ไบ‘ๅ‚จๅญ˜ใ€‚้šๅŽ๏ผŒๆˆ‘ไปฌ็กฎไฟไบ†ไธดๆ—ถๆ–‡ไปถ่ขซๅˆ ้™ค๏ผŒ้˜ฒๆญขๅ ็”จๆœๅŠกๅ™จ็ฉบ้—ดใ€‚ + #### Stream ๆจกๅผ ๅฆ‚ๆžœไฝ ๅฏน Node ไธญ็š„ Stream ๆจกๅผ้žๅธธ็†Ÿๆ‚‰๏ผŒ้‚ฃไนˆไฝ ๅฏไปฅ้€‰ๆ‹ฉๆญคๆจกๅผใ€‚ๅœจ Controller ไธญ๏ผŒๆˆ‘ไปฌๅฏไปฅ้€š่ฟ‡ `ctx.getFileStream()` ๆŽฅๅฃ่Žทๅ–ๅˆฐไธŠไผ ็š„ๆ–‡ไปถๆตใ€‚ @@ -435,7 +435,7 @@ module.exports = UploadController; ```html
- title๏ผš file๏ผš + title๏ผš file๏ผš
``` @@ -481,8 +481,8 @@ module.exports = UploaderController; ๅฆ‚ๆžœ่ฆ่Žทๅ–ๅŒๆ—ถไธŠไผ ็š„ๅคšไธชๆ–‡ไปถ๏ผŒไธ่ƒฝ้€š่ฟ‡ `ctx.getFileStream()` ๆฅ่Žทๅ–๏ผŒๅช่ƒฝ้€š่ฟ‡ไธ‹้ข่ฟ™็งๆ–นๅผ๏ผš ```js -const sendToWormhole = require('stream-wormhole'); -const Controller = require('egg').Controller; +const sendToWormhole = require("stream-wormhole"); +const Controller = require("egg").Controller; class UploaderController extends Controller { async upload() { @@ -493,10 +493,10 @@ class UploaderController extends Controller { while ((part = await parts()) != null) { if (part.length) { // ่ฟ™ๆ˜ฏ busboy ็š„ๅญ—ๆฎต - console.log('field๏ผš' + part[0]); - console.log('value๏ผš' + part[1]); - console.log('valueTruncated๏ผš' + part[2]); - console.log('fieldnameTruncated๏ผš' + part[3]); + console.log("field๏ผš" + part[0]); + console.log("value๏ผš" + part[1]); + console.log("valueTruncated๏ผš" + part[2]); + console.log("fieldnameTruncated๏ผš" + part[3]); } else { if (!part.filename) { // ่ฟ™ๆ—ถๆ˜ฏ็”จๆˆทๆฒกๆœ‰้€‰ๆ‹ฉๆ–‡ไปถๅฐฑ็‚นๅ‡ปไบ†ไธŠไผ ๏ผˆpart ๆ˜ฏ file stream๏ผŒไฝ†ๆ˜ฏ part.filename ไธบ็ฉบ๏ผ‰ @@ -504,14 +504,14 @@ class UploaderController extends Controller { return; } // part ๆ˜ฏไธŠไผ ็š„ๆ–‡ไปถๆต - console.log('field๏ผš' + part.fieldname); - console.log('filename๏ผš' + part.filename); - console.log('encoding๏ผš' + part.encoding); - console.log('mime๏ผš' + part.mime); + console.log("field๏ผš" + part.fieldname); + console.log("filename๏ผš" + part.filename); + console.log("encoding๏ผš" + part.encoding); + console.log("mime๏ผš" + part.mime); // ๆ–‡ไปถๅค„็†๏ผŒไธŠไผ ๅˆฐไบ‘ๅญ˜ๅ‚จ็ญ‰็ญ‰ let result; try { - result = await ctx.oss.put('egg-multipart-test/' + part.filename, part); + result = await ctx.oss.put("egg-multipart-test/" + part.filename, part); } catch (err) { // ๅฟ…้กปๅฐ†ไธŠไผ ็š„ๆ–‡ไปถๆตๆถˆ่ดนๆމ๏ผŒ่ฆไธ็„ถๆต่งˆๅ™จๅ“ๅบ”ไผšๅกๆญป await sendToWormhole(part); @@ -520,7 +520,7 @@ class UploaderController extends Controller { console.log(result); } } - console.log('and we are done parsing the form!'); + console.log("and we are done parsing the form!"); } } @@ -531,28 +531,34 @@ module.exports = UploaderController; ```js // images -'.jpg', '.jpeg', // image/jpeg -'.png', // image/png๏ผŒimage/x-png -'.gif', // image/gif -'.bmp', // image/bmp -'.wbmp', // image/vnd.wap.wbmp -'.webp', -'.tif', -'.psd', -// text -'.svg', -'.js', '.jsx', -'.json', -'.css', '.less', -'.html', '.htm', -'.xml', -// tar -'.zip', -'.gz', '.tgz', '.gzip', -// video -'.mp3', -'.mp4', -'.avi' +(".jpg", + ".jpeg", // image/jpeg + ".png", // image/png๏ผŒimage/x-png + ".gif", // image/gif + ".bmp", // image/bmp + ".wbmp", // image/vnd.wap.wbmp + ".webp", + ".tif", + ".psd", + // text + ".svg", + ".js", + ".jsx", + ".json", + ".css", + ".less", + ".html", + ".htm", + ".xml", + // tar + ".zip", + ".gz", + ".tgz", + ".gzip", + // video + ".mp3", + ".mp4", + ".avi"); ``` ็”จๆˆทๅฏไปฅ้€š่ฟ‡ๅœจ `config/config.default.js` ไธญ็š„้…็ฝฎๆฅๆ–ฐๅขžๆ”ฏๆŒ็š„ๆ–‡ไปถๆ‰ฉๅฑ•ๅ๏ผŒๆˆ–่€…้‡ๅ†™ๆ•ดไธช็™ฝๅๅ•ใ€‚ @@ -562,8 +568,8 @@ module.exports = UploaderController; ```js module.exports = { multipart: { - fileExtensions: ['.apk'] // ๅขžๅŠ ๅฏน '.apk' ๆ‰ฉๅฑ•ๅ็š„ๆ–‡ไปถๆ”ฏๆŒ - } + fileExtensions: [".apk"], // ๅขžๅŠ ๅฏน '.apk' ๆ‰ฉๅฑ•ๅ็š„ๆ–‡ไปถๆ”ฏๆŒ + }, }; ``` @@ -572,14 +578,15 @@ module.exports = { ```js module.exports = { multipart: { - whitelist: ['.png'] // ่ฆ†็›–ๆ•ดไธช็™ฝๅๅ•๏ผŒๅชๅ…่ฎธไธŠไผ  '.png' ๆ ผๅผ - } + whitelist: [".png"], // ่ฆ†็›–ๆ•ดไธช็™ฝๅๅ•๏ผŒๅชๅ…่ฎธไธŠไผ  '.png' ๆ ผๅผ + }, }; ``` **ๆณจๆ„๏ผšๅฝ“้‡ๅ†™ไบ† whitelist ๆ—ถ๏ผŒfileExtensions ไธ็”Ÿๆ•ˆใ€‚** ๆฌฒไบ†่งฃๆ›ดๅคšๆœ‰ๅ…ณ็š„ๆŠ€ๆœฏ็ป†่Š‚ๅ’Œไฟกๆฏ๏ผŒ่ฏทๅ‚้˜… [Egg-Multipart](https://github.com/eggjs/egg-multipart)ใ€‚ + ### Header ้™คไบ†ไปŽ URL ๅ’Œ่ฏทๆฑ‚ body ไธŠ่Žทๅ–ๅ‚ๆ•ฐไน‹ๅค–๏ผŒ่ฟ˜ๆœ‰่ฎธๅคšๅ‚ๆ•ฐๆ˜ฏ้€š่ฟ‡่ฏทๆฑ‚ header ไผ ้€’็š„ใ€‚ๆก†ๆžถๆไพ›ไบ†ไธ€ไบ›่พ…ๅŠฉๅฑžๆ€งๅ’Œๆ–นๆณ•ๆฅ่Žทๅ–๏ผš @@ -629,15 +636,15 @@ HTTP ่ฏทๆฑ‚ๆœฌ่ดจไธŠๆ˜ฏๆ— ็Šถๆ€็š„๏ผŒไฝ† Web ๅบ”็”จ้€šๅธธ้œ€่ฆ็Ÿฅ้“่ฏทๆฑ‚่€… class CookieController extends Controller { async add() { const ctx = this.ctx; - let count = ctx.cookies.get('count'); + let count = ctx.cookies.get("count"); count = count ? Number(count) : 0; - ctx.cookies.set('count', ++count); + ctx.cookies.set("count", ++count); ctx.body = count; } async remove() { const ctx = this.ctx; - ctx.cookies.set('count', null); + ctx.cookies.set("count", null); ctx.status = 204; } } @@ -663,7 +670,7 @@ module.exports = { ```js module.exports = { cookies: { - sameSite: 'lax', + sameSite: "lax", }, }; ``` @@ -709,10 +716,11 @@ Session ็›ธๅ…ณ้…็ฝฎไนŸไฝไบŽ `config.default.js`๏ผš ```js module.exports = { - key: 'EGG_SESS', // Session Cookie ๅ็งฐ + key: "EGG_SESS", // Session Cookie ๅ็งฐ maxAge: 86400000, // Session ๆœ€้•ฟๆœ‰ๆ•ˆๆœŸ }; ``` + ## ๅ‚ๆ•ฐๆ ก้ชŒ ๅœจ่Žทๅ–็”จๆˆท่ฏทๆฑ‚็š„ๅ‚ๆ•ฐๅŽ๏ผŒไธๅฏ้ฟๅ…่ฆ่ฟ›่กŒไธ€ไบ›ๆ ก้ชŒใ€‚ @@ -723,7 +731,7 @@ module.exports = { // config/plugin.js exports.validate = { enable: true, - package: 'egg-validate', + package: "egg-validate", }; ``` @@ -735,8 +743,8 @@ class PostController extends Controller { // ๆ ก้ชŒๅ‚ๆ•ฐ // ๅฆ‚ๆžœไธไผ ็ฌฌไบŒไธชๅ‚ๆ•ฐ๏ผŒไผš่‡ชๅŠจๆ ก้ชŒ `ctx.request.body` this.ctx.validate({ - title: { type: 'string' }, - content: { type: 'string' } + title: { type: "string" }, + content: { type: "string" }, }); } } @@ -769,11 +777,11 @@ class PostController extends Controller { ```js // app.js -app.validator.addRule('json', (rule, value) => { +app.validator.addRule("json", (rule, value) => { try { JSON.parse(value); } catch (err) { - return 'ๅฟ…้กปๆ˜ฏ JSON ๅญ—็ฌฆไธฒ'; + return "ๅฟ…้กปๆ˜ฏ JSON ๅญ—็ฌฆไธฒ"; } }); ``` @@ -785,7 +793,7 @@ class PostController extends Controller { async handler() { const ctx = this.ctx; // query.test ๅญ—ๆฎตๅฟ…้กปๆ˜ฏ JSON ๅญ—็ฌฆไธฒ - const rule = { test: 'json' }; + const rule = { test: "json" }; ctx.validate(rule, ctx.query); } } @@ -812,6 +820,7 @@ class PostController extends Controller { ``` Service ๅ…ทไฝ“ๅ†™ๆณ•๏ผŒๆŸฅ็œ‹ [Service](./service.md) ็ซ ่Š‚ใ€‚ + ## ๅ‘้€ HTTP ๅ“ๅบ” ๅฝ“ไธšๅŠก้€ป่พ‘ๅฎŒๆˆไน‹ๅŽ๏ผŒController ็š„ๆœ€ๅŽไธ€ไธช่Œ่ดฃๅฐฑๆ˜ฏๅฐ†ไธšๅŠก้€ป่พ‘็š„ๅค„็†็ป“ๆžœ้€š่ฟ‡ HTTP ๅ“ๅบ”ๅ‘้€็ป™็”จๆˆทใ€‚ @@ -846,14 +855,14 @@ class PostController extends Controller { class ViewController extends Controller { async show() { this.ctx.body = { - name: 'egg', - category: 'framework', - language: 'Node.js' + name: "egg", + category: "framework", + language: "Node.js", }; } async page() { - this.ctx.body = '

Hello

'; + this.ctx.body = "

Hello

"; } } ``` @@ -865,7 +874,7 @@ class ProxyController extends Controller { async proxy() { const ctx = this.ctx; const result = await ctx.curl(url, { - streaming: true + streaming: true, }); ctx.set(result.header); // result.res ๆ˜ฏไธ€ไธช stream @@ -882,7 +891,7 @@ class ProxyController extends Controller { class HomeController extends Controller { async index() { const ctx = this.ctx; - await ctx.render('home.tpl', { name: 'egg' }); + await ctx.render("home.tpl", { name: "egg" }); // ctx.body = await ctx.renderString('hi, {{ name }}', { name: 'egg' }); } } @@ -900,10 +909,10 @@ class HomeController extends Controller { ```js // app/router.js -module.exports = app => { +module.exports = (app) => { const jsonp = app.jsonp(); - app.router.get('/api/posts/:id', jsonp, app.controller.posts.show); - app.router.get('/api/posts', jsonp, app.controller.posts.list); + app.router.get("/api/posts/:id", jsonp, app.controller.posts.show); + app.router.get("/api/posts", jsonp, app.controller.posts.list); }; ``` @@ -914,9 +923,9 @@ module.exports = app => { class PostController extends Controller { async show() { this.ctx.body = { - name: 'egg', - category: 'framework', - language: 'Node.js' + name: "egg", + category: "framework", + language: "Node.js", }; } } @@ -931,8 +940,8 @@ class PostController extends Controller { ```js // config/config.default.js exports.jsonp = { - callback: 'callback', // ่ฏ†ๅˆซ query ไธญ็š„ `callback` ๅ‚ๆ•ฐ - limit: 100 // ๅ‡ฝๆ•ฐๅๆœ€้•ฟไธบ 100 ไธชๅญ—็ฌฆ + callback: "callback", // ่ฏ†ๅˆซ query ไธญ็š„ `callback` ๅ‚ๆ•ฐ + limit: 100, // ๅ‡ฝๆ•ฐๅๆœ€้•ฟไธบ 100 ไธชๅญ—็ฌฆ }; ``` @@ -942,14 +951,10 @@ exports.jsonp = { ```js // app/router.js -module.exports = app => { +module.exports = (app) => { const { router, controller, jsonp } = app; - router.get( - '/api/posts/:id', - jsonp({ callback: 'callback' }), - controller.posts.show - ); - router.get('/api/posts', jsonp({ callback: 'cb' }), controller.posts.list); + router.get("/api/posts/:id", jsonp({ callback: "callback" }), controller.posts.show); + router.get("/api/posts", jsonp({ callback: "cb" }), controller.posts.list); }; ``` @@ -971,8 +976,8 @@ module.exports = app => { // config/config.default.js module.exports = { jsonp: { - csrf: true - } + csrf: true, + }, }; ``` @@ -987,7 +992,7 @@ module.exports = { ```javascript // config/config.default.js exports.jsonp = { - whiteList: /^https?:\/\/test.com\// + whiteList: /^https?:\/\/test.com\//, // whiteList: '.test.com' // whiteList: 'sub.test.com' // whiteList: ['sub.test.com', 'sub2.test.com'] @@ -1000,7 +1005,7 @@ exports.jsonp = { ```javascript exports.jsonp = { - whiteList: /^https?:\/\/test.com\// + whiteList: /^https?:\/\/test.com\//, }; // Matches referrer: // https://test.com/hello @@ -1011,7 +1016,7 @@ exports.jsonp = { ```javascript exports.jsonp = { - whiteList: '.test.com' + whiteList: ".test.com", }; // Matches domain test.com: // https://test.com/hello @@ -1022,7 +1027,7 @@ exports.jsonp = { // http://sub.sub.test.com/ exports.jsonp = { - whiteList: 'sub.test.com' + whiteList: "sub.test.com", }; // Only matches domain sub.test.com: // https://sub.test.com/hello @@ -1033,7 +1038,7 @@ exports.jsonp = { ```javascript exports.jsonp = { - whiteList: ['sub.test.com', 'sub2.test.com'] + whiteList: ["sub.test.com", "sub2.test.com"], }; // Matches domain sub.test.com and sub2.test.com: // https://sub.test.com/hello @@ -1057,7 +1062,7 @@ class ProxyController extends Controller { ctx.body = await ctx.service.post.get(); const used = Date.now() - start; // ่ฎพ็ฝฎไธ€ไธชๅ“ๅบ”ๅคด - ctx.set('show-response-time', used.toString()); + ctx.set("show-response-time", used.toString()); } } ``` @@ -1074,7 +1079,7 @@ class ProxyController extends Controller { ```javascript // config/config.default.js exports.security = { - domainWhiteList: ['.domain.com'] // ๅฎ‰ๅ…จ็™ฝๅๅ•๏ผŒไปฅ "." ๅผ€ๅคด + domainWhiteList: [".domain.com"], // ๅฎ‰ๅ…จ็™ฝๅๅ•๏ผŒไปฅ "." ๅผ€ๅคด }; ``` diff --git a/site/docs/basics/env.zh-CN.md b/site/docs/basics/env.zh-CN.md index f67b41b205..cb70916451 100644 --- a/site/docs/basics/env.zh-CN.md +++ b/site/docs/basics/env.zh-CN.md @@ -25,22 +25,25 @@ EGG_SERVER_ENV=prod npm start ## ๅบ”็”จๅ†…่Žทๅ–่ฟ่กŒ็Žฏๅขƒ ๆก†ๆžถๆไพ›ไบ†ๅ˜้‡ `app.config.env`๏ผŒๆฅ่กจ็คบๅบ”็”จๅฝ“ๅ‰็š„่ฟ่กŒ็Žฏๅขƒใ€‚ + ## ่ฟ่กŒ็Žฏๅขƒ็›ธๅ…ณ้…็ฝฎ ไธๅŒ็š„่ฟ่กŒ็Žฏๅขƒไผšๅฏนๅบ”ไธๅŒ็š„้…็ฝฎ๏ผŒๅ…ทไฝ“่ฏท้˜…่ฏป [Config ้…็ฝฎ](./config.md)ใ€‚ + ## ไธŽ `NODE_ENV` ็š„ๅŒบๅˆซ ๅพˆๅคš Node.js ๅบ”็”จไผšไฝฟ็”จ `NODE_ENV` ๆฅๅŒบๅˆ†่ฟ่กŒ็Žฏๅขƒ๏ผŒไฝ† `EGG_SERVER_ENV` ๅŒบๅˆ†ๅพ—ๆ›ดๅŠ ็ฒพ็ป†ใ€‚ไธ€่ˆฌ็š„้กน็›ฎๅผ€ๅ‘ๆต็จ‹ๅŒ…ๆ‹ฌๆœฌๅœฐๅผ€ๅ‘็Žฏๅขƒใ€ๆต‹่ฏ•็Žฏๅขƒใ€็”Ÿไบง็Žฏๅขƒ็ญ‰๏ผŒ้™คไบ†ๆœฌๅœฐๅผ€ๅ‘็Žฏๅขƒๅ’Œๆต‹่ฏ•็Žฏๅขƒๅค–๏ผŒๅ…ถไป–็Žฏๅขƒๅฏ็ปŸ็งฐไธบ**ๆœๅŠกๅ™จ็Žฏๅขƒ**ใ€‚ๆœๅŠกๅ™จ็Žฏๅขƒ็š„ `NODE_ENV` ๅบ”่ฏฅไธบ `production`ใ€‚่€Œไธ” npm ไนŸไผšไฝฟ็”จ่ฟ™ไธชๅ˜้‡๏ผŒๅœจๅบ”็”จ้ƒจ็ฝฒๆ—ถ๏ผŒไธ€่ˆฌไธไผšๅฎ‰่ฃ… devDependencies๏ผŒๆ‰€ไปฅ่ฟ™ไธชๅ€ผไนŸๅบ”่ฏฅไธบ `production`ใ€‚ ๆก†ๆžถ้ป˜่ฎคๆ”ฏๆŒ็š„่ฟ่กŒ็ŽฏๅขƒๅŠๆ˜ ๅฐ„ๅ…ณ็ณป๏ผˆๅฆ‚ๆžœๆœชๆŒ‡ๅฎš `EGG_SERVER_ENV`๏ผŒไผšๆ นๆฎ `NODE_ENV` ๆฅๅŒน้…๏ผ‰ๅฆ‚ไธ‹่กจๆ‰€็คบ๏ผš -| `NODE_ENV` | `EGG_SERVER_ENV` | ่ฏดๆ˜Ž | -|--------------|------------------|--------------| -| ๏ผˆไธ่ฎพ็ฝฎ๏ผ‰ | local | ๆœฌๅœฐๅผ€ๅ‘็Žฏๅขƒ | -| test | unittest | ๅ•ๅ…ƒๆต‹่ฏ• | -| production | prod | ็”Ÿไบง็Žฏๅขƒ | +| `NODE_ENV` | `EGG_SERVER_ENV` | ่ฏดๆ˜Ž | +| ---------- | ---------------- | ------------ | +| ๏ผˆไธ่ฎพ็ฝฎ๏ผ‰ | local | ๆœฌๅœฐๅผ€ๅ‘็Žฏๅขƒ | +| test | unittest | ๅ•ๅ…ƒๆต‹่ฏ• | +| production | prod | ็”Ÿไบง็Žฏๅขƒ | ไพ‹ๅฆ‚๏ผŒๅฝ“ `NODE_ENV` ไธบ `production` ่€Œ `EGG_SERVER_ENV` ๆœชๆŒ‡ๅฎšๆ—ถ๏ผŒๆก†ๆžถไผšๅฐ† `EGG_SERVER_ENV` ่ฎพ็ฝฎๆˆ `prod`ใ€‚ + ## ่‡ชๅฎšไน‰็Žฏๅขƒ Egg ๆก†ๆžถๆ”ฏๆŒๅผ€ๅ‘่€…ๆ นๆฎๅฎž้™…้œ€่ฆ่‡ชๅฎšไน‰ๅผ€ๅ‘็Žฏๅขƒใ€‚ diff --git a/site/docs/basics/extend.md b/site/docs/basics/extend.md index a293605d57..f77fb53bd3 100644 --- a/site/docs/basics/extend.md +++ b/site/docs/basics/extend.md @@ -57,7 +57,7 @@ For example, if we would like to add a Getter property `app.bar`: ```js // app/extend/application.js -const BAR = Symbol('Application#bar'); +const BAR = Symbol("Application#bar"); module.exports = { get bar() { @@ -108,14 +108,14 @@ For example, if we would like to add a Getter property `ctx.bar`: ```js // app/extend/context.js -const BAR = Symbol('Context#bar'); +const BAR = Symbol("Context#bar"); module.exports = { get bar() { // `this` points to the ctx object, you can access other methods or property of ctx if (!this[BAR]) { // For example, we can get from header, but it should be more complex in real situation. - this[BAR] = this.get('x-bar'); + this[BAR] = this.get("x-bar"); } return this[BAR]; }, @@ -146,7 +146,7 @@ For instance, we could add a property `request.foo` in the following way: // app/extend/request.js module.exports = { get foo() { - return this.get('x-request-foo'); + return this.get("x-request-foo"); }, }; ``` @@ -175,7 +175,7 @@ For instance, we could add a setter `request.foo` in the following way: // app/extend/response.js module.exports = { set foo(value) { - this.set('x-response-foo', value); + this.set("x-response-foo", value); }, }; ``` @@ -196,10 +196,10 @@ Access helper object with `ctx.helper`, for example: ```js // Assume that home router has already defined in app/router.js -app.get('home', '/', 'home.index'); +app.get("home", "/", "home.index"); // Use helper to calculate the specific url path -ctx.helper.pathFor('home', { by: 'recent', limit: 20 }); +ctx.helper.pathFor("home", { by: "recent", limit: 20 }); // => /?by=recent&limit=20 ``` diff --git a/site/docs/basics/extend.zh-CN.md b/site/docs/basics/extend.zh-CN.md index 6ba5acf684..b526a836d3 100644 --- a/site/docs/basics/extend.zh-CN.md +++ b/site/docs/basics/extend.zh-CN.md @@ -20,7 +20,7 @@ order: 11 ### ่ฎฟ้—ฎๆ–นๅผ - `ctx.app` - + `ctx.app` ๆไพ›ไบ†ไธ€็ง่ฎฟ้—ฎๅ…จๅฑ€ `app` ๅฏน่ฑก็š„ๆ–นๅผใ€‚ - Controller๏ผŒMiddleware๏ผŒHelper๏ผŒService ไธญ้ƒฝๅฏไปฅ้€š่ฟ‡ `this.app` ่ฎฟ้—ฎๅˆฐ Application ๅฏน่ฑกใ€‚ไพ‹ๅฆ‚๏ผŒ้€š่ฟ‡ `this.app.config` ๅฏไปฅ่ฎฟ้—ฎ้…็ฝฎๅฏน่ฑกใ€‚ @@ -29,7 +29,7 @@ order: 11 ```js // app.js -module.exports = app => { +module.exports = (app) => { // ไฝฟ็”จ app ๅฏน่ฑก }; ``` @@ -61,7 +61,7 @@ module.exports = { ```js // app/extend/application.js -const BAR = Symbol('Application#bar'); +const BAR = Symbol("Application#bar"); module.exports = { get bar() { @@ -74,6 +74,7 @@ module.exports = { }, }; ``` + ## Context Context ๆŒ‡็š„ๆ˜ฏ Koa ็š„่ฏทๆฑ‚ไธŠไธ‹ๆ–‡๏ผŒ่ฟ™ๆ˜ฏ่ฏทๆฑ‚็บงๅˆซ็š„ๅฏน่ฑก๏ผŒๆฏๆฌก่ฏทๆฑ‚็”Ÿๆˆไธ€ไธช Context ๅฎžไพ‹๏ผŒ้€šๅธธๆˆ‘ไปฌไนŸ็ฎ€ๅ†™ๆˆ `ctx`ใ€‚ๅœจๆ‰€ๆœ‰็š„ๆ–‡ๆกฃไธญ๏ผŒContext ๅ’Œ `ctx` ้ƒฝๆ˜ฏๆŒ‡ Koa ็š„ไธŠไธ‹ๆ–‡ๅฏน่ฑกใ€‚ @@ -97,7 +98,7 @@ Context ๆŒ‡็š„ๆ˜ฏ Koa ็š„่ฏทๆฑ‚ไธŠไธ‹ๆ–‡๏ผŒ่ฟ™ๆ˜ฏ่ฏทๆฑ‚็บงๅˆซ็š„ๅฏน่ฑก๏ผŒๆฏๆฌก module.exports = { foo(param) { // this ๅฐฑๆ˜ฏ ctx ๅฏน่ฑก๏ผŒๅœจๅ…ถไธญๅฏไปฅ่ฐƒ็”จ ctx ไธŠ็š„ๅ…ถไป–ๆ–นๆณ•๏ผŒๆˆ–่ฎฟ้—ฎๅฑžๆ€ง - } + }, }; ``` @@ -111,19 +112,20 @@ module.exports = { ```js // app/extend/context.js -const BAR = Symbol('Context#bar'); +const BAR = Symbol("Context#bar"); module.exports = { get bar() { // this ๅฐฑๆ˜ฏ ctx ๅฏน่ฑก๏ผŒๅœจๅ…ถไธญๅฏไปฅ่ฐƒ็”จ ctx ไธŠ็š„ๅ…ถไป–ๆ–นๆณ•๏ผŒๆˆ–่ฎฟ้—ฎๅฑžๆ€ง if (!this[BAR]) { // ไพ‹ๅฆ‚๏ผŒไปŽ header ไธญ่Žทๅ–๏ผŒๅฎž้™…ๆƒ…ๅ†ต่‚ฏๅฎšๆ›ดๅคๆ‚ - this[BAR] = this.get('x-bar'); + this[BAR] = this.get("x-bar"); } return this[BAR]; - } + }, }; ``` + ## Request ๅฏน่ฑก Request ๅฏน่ฑกๅ’Œ Koa ็š„ Request ๅฏน่ฑก็›ธๅŒ๏ผŒๆ˜ฏ **่ฏทๆฑ‚็บงๅˆซ** ็š„ๅฏน่ฑก๏ผŒๅฎƒๆไพ›ไบ†ๅคง้‡่ฏทๆฑ‚็›ธๅ…ณ็š„ๅฑžๆ€งๅ’Œๆ–นๆณ•ไพ›ไฝฟ็”จใ€‚ @@ -148,7 +150,7 @@ Koa ๅ†…็ฝฎ็š„ไปฃ็† `request` ็š„ๅฑžๆ€งๅ’Œๆ–นๆณ•ๅˆ—่กจๅฏๅ‚้˜…๏ผš[Koa - Request // app/extend/request.js module.exports = { get foo() { - return this.get('x-request-foo'); + return this.get("x-request-foo"); }, }; ``` @@ -177,7 +179,7 @@ ctx.response; // app/extend/response.js module.exports = { set foo(value) { - this.set('x-response-foo', value); + this.set("x-response-foo", value); }, }; ``` @@ -198,10 +200,10 @@ Helper ๅ‡ฝๆ•ฐ็”จๆฅๆไพ›ไธ€ไบ›ๅฎž็”จ็š„ utility ๅ‡ฝๆ•ฐใ€‚ ```js // ๅ‡่ฎพๅœจ app/router.js ไธญๅฎšไน‰ไบ† home router -app.get('home', '/', 'home.index'); +app.get("home", "/", "home.index"); // ไฝฟ็”จ helper ่ฎก็ฎ—ๆŒ‡ๅฎš url path -ctx.helper.pathFor('home', { by: 'recent', limit: 20 }); +ctx.helper.pathFor("home", { by: "recent", limit: 20 }); // => /?by=recent&limit=20 ``` diff --git a/site/docs/basics/middleware.md b/site/docs/basics/middleware.md index ba286c521d..e8a9711fc0 100644 --- a/site/docs/basics/middleware.md +++ b/site/docs/basics/middleware.md @@ -12,8 +12,8 @@ In [the previous chapter](../intro/egg-and-koa.md), we say that Egg is based on Let's take a look at how to write a middleware from a simple gzip example. ```js -const isJSON = require('koa-is-json'); -const zlib = require('zlib'); +const isJSON = require("koa-is-json"); +const zlib = require("zlib"); async function gzip(ctx, next) { await next(); @@ -27,7 +27,7 @@ async function gzip(ctx, next) { const stream = zlib.createGzip(); stream.end(body); ctx.body = stream; - ctx.set('Content-Encoding', 'gzip'); + ctx.set("Content-Encoding", "gzip"); } ``` @@ -44,8 +44,8 @@ We will do a simple optimization to the gzip middleware above, making it do gzip ```js // app/middleware/gzip.js -const isJSON = require('koa-is-json'); -const zlib = require('zlib'); +const isJSON = require("koa-is-json"); +const zlib = require("zlib"); module.exports = (options) => { return async function gzip(ctx, next) { @@ -64,7 +64,7 @@ module.exports = (options) => { const stream = zlib.createGzip(); stream.end(body); ctx.body = stream; - ctx.set('Content-Encoding', 'gzip'); + ctx.set("Content-Encoding", "gzip"); }; }; ``` @@ -82,7 +82,7 @@ we can edit `config.default.js` like this: ```js module.exports = { // configure the middleware you need, which loads in the order of array - middleware: ['gzip'], + middleware: ["gzip"], // configure the gzip middleware gzip: { @@ -101,7 +101,7 @@ Framework and Plugin don't support to configure `middleware` in `config.default. // app.js module.exports = (app) => { // put to the first place to count request cost - app.config.coreMiddleware.unshift('report'); + app.config.coreMiddleware.unshift("report"); }; // app/middleware/report.js @@ -125,7 +125,7 @@ If you do want to take effect only for single route, you could just instantiate ```js module.exports = (app) => { const gzip = app.middleware.gzip({ threshold: 1024 }); - app.router.get('/needgzip', gzip, app.controller.handler); + app.router.get("/needgzip", gzip, app.controller.handler); }; ``` @@ -136,7 +136,7 @@ In addition to application layer loading middleware, the framework itself and ot ```js module.exports = { bodyParser: { - jsonLimit: '10m', + jsonLimit: "10m", }, }; ``` @@ -150,8 +150,8 @@ Developer is free to use Koa Middleware, all middlewares used in Koa can be dire For example, Koa uses [koa-compress](https://github.com/koajs/compress) in this way: ```js -const koa = require('koa'); -const compress = require('koa-compress'); +const koa = require("koa"); +const compress = require("koa-compress"); const app = koa(); @@ -164,13 +164,13 @@ We can load the middleware according to the framework specification like this: ```js // app/middleware/compress.js // interfaces(`(options) => middleware`) exposed by koa-compress match the framework middleware requirements -module.exports = require('koa-compress'); +module.exports = require("koa-compress"); ``` ```js // config/config.default.js module.exports = { - middleware: ['compress'], + middleware: ["compress"], compress: { threshold: 2048, }, @@ -189,7 +189,7 @@ module.exports = { }; // app/middleware/webpack.js -const webpackMiddleware = require('some-koa-middleware'); +const webpackMiddleware = require("some-koa-middleware"); module.exports = (options, app) => { return webpackMiddleware(options.compiler, options.others); @@ -225,7 +225,7 @@ If we want gzip to be used only by url requests starting with `/static`, the mat ```js module.exports = { gzip: { - match: '/static', + match: "/static", }, }; ``` @@ -242,7 +242,7 @@ module.exports = { match(ctx) { // enabled on ios devices const reg = /iphone|ipad|ipod/i; - return reg.test(ctx.get('user-agent')); + return reg.test(ctx.get("user-agent")); }, }, }; diff --git a/site/docs/basics/middleware.zh-CN.md b/site/docs/basics/middleware.zh-CN.md index ac53170237..6300f7e258 100644 --- a/site/docs/basics/middleware.zh-CN.md +++ b/site/docs/basics/middleware.zh-CN.md @@ -13,8 +13,8 @@ order: 5 ```js // app/middleware/gzip.js -const isJSON = require('koa-is-json'); -const zlib = require('zlib'); +const isJSON = require("koa-is-json"); +const zlib = require("zlib"); async function gzip(ctx, next) { await next(); @@ -28,7 +28,7 @@ async function gzip(ctx, next) { const stream = zlib.createGzip(); stream.end(body); ctx.body = stream; - ctx.set('Content-Encoding', 'gzip'); + ctx.set("Content-Encoding", "gzip"); } ``` @@ -45,8 +45,8 @@ async function gzip(ctx, next) { ```js // app/middleware/gzip.js -const isJSON = require('koa-is-json'); -const zlib = require('zlib'); +const isJSON = require("koa-is-json"); +const zlib = require("zlib"); module.exports = (options) => { return async function gzip(ctx, next) { @@ -65,10 +65,11 @@ module.exports = (options) => { const stream = zlib.createGzip(); stream.end(body); ctx.body = stream; - ctx.set('Content-Encoding', 'gzip'); + ctx.set("Content-Encoding", "gzip"); }; }; ``` + ## ไฝฟ็”จไธญ้—ดไปถ ไธญ้—ดไปถ็ผ–ๅ†™ๅฎŒๆˆๅŽ๏ผŒๆˆ‘ไปฌ่ฟ˜้œ€่ฆๆ‰‹ๅŠจๆŒ‚่ฝฝ๏ผŒๆ”ฏๆŒไปฅไธ‹ๆ–นๅผ๏ผš @@ -82,12 +83,12 @@ module.exports = (options) => { ```js module.exports = { // ้…็ฝฎ้œ€่ฆ็š„ไธญ้—ดไปถ๏ผŒๆ•ฐ็ป„้กบๅบๅณไธบไธญ้—ดไปถ็š„ๅŠ ่ฝฝ้กบๅบ - middleware: ['gzip'], + middleware: ["gzip"], // ้…็ฝฎ gzip ไธญ้—ดไปถ็š„้…็ฝฎ gzip: { - threshold: 1024 // ๅฐไบŽ 1k ็š„ๅ“ๅบ”ไฝ“ไธๅŽ‹็ผฉ - } + threshold: 1024, // ๅฐไบŽ 1k ็š„ๅ“ๅบ”ไฝ“ไธๅŽ‹็ผฉ + }, }; ``` @@ -99,14 +100,14 @@ module.exports = { ```js // app.js -module.exports = app => { +module.exports = (app) => { // ๅœจไธญ้—ดไปถๆœ€ๅ‰้ข็ปŸ่ฎก่ฏทๆฑ‚ๆ—ถ้—ด - app.config.coreMiddleware.unshift('report'); + app.config.coreMiddleware.unshift("report"); }; // app/middleware/report.js module.exports = () => { - return async function(ctx, next) { + return async function (ctx, next) { const startTime = Date.now(); await next(); // ไธŠๆŠฅ่ฏทๆฑ‚ๆ—ถ้—ด @@ -123,11 +124,12 @@ module.exports = () => { ๅฆ‚ๆžœไฝ ๅชๆƒณ้’ˆๅฏนๅ•ไธช่ทฏ็”ฑ็”Ÿๆ•ˆ๏ผŒๅฏไปฅ็›ดๆŽฅๅœจ `app/router.js` ไธญๅฎžไพ‹ๅŒ–ๅ’ŒๆŒ‚่ฝฝ๏ผŒๅฆ‚ไธ‹๏ผš ```js -module.exports = app => { +module.exports = (app) => { const gzip = app.middleware.gzip({ threshold: 1024 }); - app.router.get('/needgzip', gzip, app.controller.handler); + app.router.get("/needgzip", gzip, app.controller.handler); }; ``` + ## ๆก†ๆžถ้ป˜่ฎคไธญ้—ดไปถ ้™คไบ†ๅบ”็”จๅฑ‚ๅŠ ่ฝฝไธญ้—ดไปถไน‹ๅค–๏ผŒๆก†ๆžถ่‡ช่บซๅ’Œๅ…ถไป–ๆ’ไปถไนŸไผšๅŠ ่ฝฝ่ฎธๅคšไธญ้—ดไปถใ€‚ๆ‰€ๆœ‰่ฟ™ไบ›่‡ชๅธฆไธญ้—ดไปถ็š„้…็ฝฎ้กน้ƒฝๅฏไปฅ้€š่ฟ‡ไฟฎๆ”น้…็ฝฎๆ–‡ไปถไธญ็š„ๅŒๅ้…็ฝฎ้กนๆฅ่ฟ›่กŒๆ›ดๆ”นใ€‚ไพ‹ๅฆ‚๏ผŒๆก†ๆžถ่‡ชๅธฆ็š„ไธญ้—ดไปถๅˆ—่กจไธญๆœ‰ไธ€ไธชๅไธบ `bodyParser` ็š„ไธญ้—ดไปถ๏ผˆๆก†ๆžถ็š„ๅŠ ่ฝฝๅ™จไผšๅฐ†ๆ–‡ไปถๅไธญ็š„ๅˆ†้š”็ฌฆ้ƒฝ่ฝฌๆขไธบ้ฉผๅณฐๅฝขๅผ็š„ๅ˜้‡ๅ๏ผ‰ใ€‚ๅฆ‚ๆžœๆˆ‘ไปฌๆƒณ่ฆไฟฎๆ”น `bodyParser` ็š„้…็ฝฎ๏ผŒๅช้œ€่ฆๅœจ `config/config.default.js` ไธญ็ผ–ๅ†™ๅฆ‚ไธ‹ๅ†…ๅฎน๏ผš @@ -135,12 +137,13 @@ module.exports = app => { ```js module.exports = { bodyParser: { - jsonLimit: '10mb', + jsonLimit: "10mb", }, }; ``` **ๆณจๆ„๏ผšๆก†ๆžถๅ’Œๆ’ไปถๅŠ ่ฝฝ็š„ไธญ้—ดไปถไผšๅœจๅบ”็”จๅฑ‚้…็ฝฎ็š„ไธญ้—ดไปถไน‹ๅ‰่ขซๅŠ ่ฝฝใ€‚ๆก†ๆžถ้ป˜่ฎคไธญ้—ดไปถไธ่ƒฝ่ขซๅบ”็”จๅฑ‚ไธญ้—ดไปถ่ฆ†็›–ใ€‚ๅฆ‚ๆžœๅบ”็”จๅฑ‚ๆœ‰่‡ชๅฎšไน‰ๅŒๅไธญ้—ดไปถ๏ผŒๅฏๅŠจๆ—ถๅฐ†ไผšๆŠฅ้”™ใ€‚** + ## ไฝฟ็”จ Koa ็š„ไธญ้—ดไปถ ๅœจๆก†ๆžถ้‡Œ้ขๅฏไปฅ้žๅธธๅฎนๆ˜“ๅœฐๅผ•ๅ…ฅ Koa ไธญ้—ดไปถ็”Ÿๆ€ใ€‚ @@ -148,8 +151,8 @@ module.exports = { ไปฅ [`koa-compress`](https://github.com/koajs/compress) ไธบไพ‹๏ผŒๅœจ Koa ไธญไฝฟ็”จๆ—ถ๏ผš ```js -const koa = require('koa'); -const compress = require('koa-compress'); +const koa = require("koa"); +const compress = require("koa-compress"); const app = new koa(); @@ -162,13 +165,13 @@ app.use(compress(options)); ```js // app/middleware/compress.js // koa-compress ๆšด้œฒ็š„ๆŽฅๅฃ๏ผˆ`(options) => middleware`๏ผ‰ๅ’Œๆก†ๆžถๅฏนไธญ้—ดไปถ่ฆๆฑ‚ไธ€่‡ด -module.exports = require('koa-compress'); +module.exports = require("koa-compress"); ``` ```js // config/config.default.js module.exports = { - middleware: ['compress'], + middleware: ["compress"], compress: { threshold: 2048, }, @@ -187,12 +190,13 @@ module.exports = { }; // app/middleware/webpack.js -const webpackMiddleware = require('some-koa-middleware'); +const webpackMiddleware = require("some-koa-middleware"); module.exports = (options, app) => { return webpackMiddleware(options.compiler, options.others); }; ``` + ## ้€š็”จ้…็ฝฎ ๆ— ่ฎบๆ˜ฏๅบ”็”จๅฑ‚ๅŠ ่ฝฝ็š„ไธญ้—ดไปถ่ฟ˜ๆ˜ฏๆก†ๆžถ่‡ชๅธฆไธญ้—ดไปถ๏ผŒ้ƒฝๆ”ฏๆŒๅ‡ ไธช้€š็”จ็š„้…็ฝฎ้กน๏ผš @@ -222,7 +226,7 @@ module.exports = { ```js module.exports = { gzip: { - match: '/static', + match: "/static", }, }; ``` @@ -239,7 +243,7 @@ module.exports = { match(ctx) { // ๅชๆœ‰ iOS ่ฎพๅค‡ๆ‰ๅผ€ๅฏ const reg = /iphone|ipad|ipod/i; - return reg.test(ctx.get('user-agent')); + return reg.test(ctx.get("user-agent")); }, }, }; diff --git a/site/docs/basics/objects.md b/site/docs/basics/objects.md index 9478c0881e..15db7d7c59 100644 --- a/site/docs/basics/objects.md +++ b/site/docs/basics/objects.md @@ -21,16 +21,16 @@ Framework will emits some events when server running, application developers or // app.js module.exports = (app) => { - app.once('server', (server) => { + app.once("server", (server) => { // websocket }); - app.on('error', (err, ctx) => { + app.on("error", (err, ctx) => { // report error }); - app.on('request', (ctx) => { + app.on("request", (ctx) => { // log receive request }); - app.on('response', (ctx) => { + app.on("response", (ctx) => { // ctx.starttime is set by framework const used = Date.now() - ctx.starttime; // log total cost @@ -174,7 +174,7 @@ In the Controller file, there are two ways to use the Controller base class: // app/controller/user.js // get from egg (recommend) -const Controller = require('egg').Controller; +const Controller = require("egg").Controller; class UserController extends Controller { // implement } @@ -198,7 +198,7 @@ The properties of the Service base class are the same as those of the [Controlle // app/service/user.js // get from egg (recommend) -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { // implement } @@ -249,7 +249,7 @@ In application development, we may often customize some helper methods, such as // app/extend/helper.js module.exports = { formatUser(user) { - return only(user, ['name', 'phone']); + return only(user, ["name", "phone"]); }, }; ``` @@ -300,7 +300,7 @@ Subscription is a common model for subscribing, for example, the consumer in mes The base class of Subscription can be exported in the following way. ```js -const Subscription = require('egg').Subscription; +const Subscription = require("egg").Subscription; class Schedule extends Subscription { // This method should be implemented diff --git a/site/docs/basics/objects.zh-CN.md b/site/docs/basics/objects.zh-CN.md index 5b6ac0a4d7..5ff4fcd0b9 100644 --- a/site/docs/basics/objects.zh-CN.md +++ b/site/docs/basics/objects.zh-CN.md @@ -21,16 +21,16 @@ Application ๆ˜ฏๅ…จๅฑ€ๅบ”็”จๅฏน่ฑกใ€‚ๅœจไธ€ไธชๅบ”็”จไธญ๏ผŒๆฏไธช่ฟ›็จ‹ๅชไผšๅฎž // app.js module.exports = (app) => { - app.once('server', (server) => { + app.once("server", (server) => { // websocket ็›ธๅ…ณๆ“ไฝœ }); - app.on('error', (err, ctx) => { + app.on("error", (err, ctx) => { // ไธŠๆŠฅ้”™่ฏฏ }); - app.on('request', (ctx) => { + app.on("request", (ctx) => { // ่ฎฐๅฝ•ๆ”ถๅˆฐ็š„่ฏทๆฑ‚ }); - app.on('response', (ctx) => { + app.on("response", (ctx) => { // ctx.starttime ๆ˜ฏ็”ฑๆก†ๆžถ่ฎพ็ฝฎ็š„ const used = Date.now() - ctx.starttime; // ่ฎฐๅฝ•่ฏทๆฑ‚ๆ€ป่€—ๆ—ถ @@ -85,6 +85,7 @@ class UserController extends Controller { } } ``` + ## Context Context ๆ˜ฏไธ€ไธช**่ฏทๆฑ‚็บงๅˆซ็š„ๅฏน่ฑก**๏ผŒ็ปงๆ‰ฟ่‡ช [Koa.Context]ใ€‚ๅœจๆฏๆฌกๆ”ถๅˆฐ็”จๆˆท่ฏทๆฑ‚ๆ—ถ๏ผŒๆก†ๆžถ้ƒฝไผšๅฎžไพ‹ๅŒ–ไธ€ไธช Context ๅฏน่ฑกใ€‚่ฟ™ไธชๅฏน่ฑกๅฐ่ฃ…ไบ†่ฟ™ๆฌก็”จๆˆท่ฏทๆฑ‚็š„ไฟกๆฏ๏ผŒๅนถๆไพ›ไบ†่ฎธๅคšไพฟๆท็š„ๆ–นๆณ•ๆฅ่Žทๅ–่ฏทๆฑ‚ๅ‚ๆ•ฐๆˆ–่€…่ฎพ็ฝฎๅ“ๅบ”ไฟกๆฏใ€‚ๆก†ๆžถไผšๅฐ†ๆ‰€ๆœ‰็š„ [Service] ๆŒ‚่ฝฝๅˆฐ Context ๅฎžไพ‹ไธŠใ€‚้ƒจๅˆ†ๆ’ไปถไนŸไผšๅฐ†ๅ…ถไป–ๆ–นๆณ•ๅ’Œๅฏน่ฑกๆŒ‚่ฝฝ่‡ณๅ…ถไธŠ๏ผˆๅฆ‚ [egg-sequelize] ไผšๅฐ†ๆ‰€ๆœ‰็š„ model ๆŒ‚ๅˆฐ Context ไธŠ๏ผ‰ใ€‚ @@ -131,6 +132,7 @@ exports.task = async (ctx) => { await ctx.service.posts.refresh(); }; ``` + ## Request & Response Request ๆ˜ฏไธ€ไธช**่ฏทๆฑ‚็บงๅˆซ็š„ๅฏน่ฑก**๏ผŒ็ปงๆ‰ฟ่‡ช `[Koa.Request]`ใ€‚ๅฐ่ฃ…ไบ† Node.js ๅŽŸ็”Ÿ็š„ HTTP Request ๅฏน่ฑก๏ผŒๆไพ›ไบ†ไธ€็ณปๅˆ—่พ…ๅŠฉๆ–นๆณ•่Žทๅ– HTTP ่ฏทๆฑ‚ๅธธ็”จๅ‚ๆ•ฐใ€‚ @@ -157,6 +159,7 @@ class UserController extends Controller { - `[Koa]` ไผšๅœจ Context ไธŠไปฃ็†ไธ€้ƒจๅˆ† Request ๅ’Œ Response ไธŠ็š„ๆ–นๆณ•ๅ’Œๅฑžๆ€ง๏ผŒๅ‚่ง `[Koa.Context]`ใ€‚ - ๅฆ‚ไธŠ้ขไพ‹ๅญไธญ็š„ `ctx.request.query.id` ๅ’Œ `ctx.query.id` ๆ˜ฏ็ญ‰ไปท็š„๏ผŒ`ctx.response.body =` ๅ’Œ `ctx.body =` ไนŸๆ˜ฏ็ญ‰ไปท็š„ใ€‚ - ้œ€่ฆๆณจๆ„็š„ๆ˜ฏ๏ผŒ่Žทๅ– POST ็š„ body ๅบ”่ฏฅไฝฟ็”จ `ctx.request.body`๏ผŒ่€Œไธๆ˜ฏ `ctx.body`ใ€‚ + ## Controller ๆก†ๆžถๆไพ›ไบ†ไธ€ไธช Controller ๅŸบ็ฑป๏ผŒๅนถๆŽจ่ๆ‰€ๆœ‰็š„ `Controller` ้ƒฝ็ปงๆ‰ฟไบŽ่ฏฅๅŸบ็ฑปๅฎž็Žฐใ€‚่ฟ™ไธช Controller ๅŸบ็ฑปๆœ‰ไธ‹ๅˆ—ๅฑžๆ€ง๏ผš @@ -173,7 +176,7 @@ class UserController extends Controller { // app/controller/user.js // ไปŽ egg ไธŠ่Žทๅ–๏ผˆๆŽจ่๏ผ‰ -const Controller = require('egg').Controller; +const Controller = require("egg").Controller; class UserController extends Controller { // ๅฎž็Žฐ } @@ -186,6 +189,7 @@ module.exports = (app) => { }; }; ``` + ## Service ๆก†ๆžถๆไพ›ไบ†ไธ€ไธช Service ๅŸบ็ฑป๏ผŒๅนถๆŽจ่ๆ‰€ๆœ‰็š„ Service ้ƒฝ็ปงๆ‰ฟไบŽ่ฏฅๅŸบ็ฑปๅฎž็Žฐใ€‚ @@ -196,7 +200,7 @@ Service ๅŸบ็ฑป็š„ๅฑžๆ€งๅ’Œ [Controller](#controller) ๅŸบ็ฑปๅฑžๆ€งไธ€่‡ด๏ผŒ่ฎฟ้—ฎ // app/service/user.js // ไปŽ egg ไธŠ่Žทๅ–๏ผˆๆŽจ่๏ผ‰ -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { // implement } @@ -209,6 +213,7 @@ module.exports = (app) => { }; }; ``` + ## Helper Helper ็”จๆฅๆไพ›ไธ€ไบ›ๅฎž็”จ็š„ utility ๅ‡ฝๆ•ฐใ€‚ๅฎƒ็š„ไฝœ็”จๅœจไบŽๆˆ‘ไปฌๅฏไปฅๅฐ†ไธ€ไบ›ๅธธ็”จ็š„ๅŠจไฝœๆŠฝ็ฆปๅœจ `helper.js` ้‡Œ้ขๆˆไธบไธ€ไธช็‹ฌ็ซ‹็š„ๅ‡ฝๆ•ฐใ€‚่ฟ™ๆ ทๅฏไปฅๅˆฉ็”จ JavaScript ็ผ–ๅ†™ๅคๆ‚็š„้€ป่พ‘๏ผŒ้ฟๅ…้€ป่พ‘ๅˆ†ๆ•ฃไบŽๅ„ไธชๅœฐๆ–น๏ผŒๅŒๆ—ถไพฟไบŽๆ›ดๅฅฝๅœฐ็ผ–ๅ†™ๆต‹่ฏ•็”จไพ‹ใ€‚ @@ -246,10 +251,11 @@ class UserController extends Controller { // app/extend/helper.js module.exports = { formatUser(user) { - return only(user, ['name', 'phone']); + return only(user, ["name", "phone"]); }, }; ``` + ## Config ๆˆ‘ไปฌๆŽจ่ๅบ”็”จๅผ€ๅ‘้ตๅพช้…็ฝฎๅ’Œไปฃ็ ๅˆ†็ฆป็š„ๅŽŸๅˆ™๏ผŒๅฐ†ไธ€ไบ›้œ€่ฆ็กฌ็ผ–็ ็š„ไธšๅŠก้…็ฝฎ้ƒฝๆ”พๅˆฐ้…็ฝฎๆ–‡ไปถไธญใ€‚ๅŒๆ—ถ๏ผŒ้…็ฝฎๆ–‡ไปถๆ”ฏๆŒๅ„ไธชไธๅŒ็š„่ฟ่กŒ็Žฏๅขƒไฝฟ็”จไธๅŒ็š„้…็ฝฎ๏ผŒไฝฟ็”จ่ตทๆฅไนŸ้žๅธธๆ–นไพฟใ€‚ๆ‰€ๆœ‰ๆก†ๆžถใ€ๆ’ไปถๅ’Œๅบ”็”จ็บงๅˆซ็š„้…็ฝฎ้ƒฝๅฏไปฅ้€š่ฟ‡ `Config` ๅฏน่ฑก่Žทๅ–ๅˆฐใ€‚ๅ…ณไบŽๆก†ๆžถ็š„้…็ฝฎ๏ผŒๅฏไปฅ่ฏฆ็ป†้˜…่ฏป[Config ้…็ฝฎ](./config.md)็ซ ่Š‚ใ€‚ @@ -257,6 +263,7 @@ module.exports = { ### ่Žทๅ–ๆ–นๅผ ๆˆ‘ไปฌๅฏไปฅ้€š่ฟ‡ `app.config` ไปŽ `Application` ๅฎžไพ‹ไธŠ่Žทๅ–ๅˆฐ `config` ๅฏน่ฑก๏ผŒไนŸๅฏไปฅๅœจ Controllerใ€Serviceใ€Helper ็š„ๅฎžไพ‹ไธŠ้€š่ฟ‡ `this.config` ่Žทๅ–ๅˆฐ `config` ๅฏน่ฑกใ€‚ + ## Logger ๆก†ๆžถๅ†…็ฝฎไบ†ๅŠŸ่ƒฝๅผบๅคง็š„[ๆ—ฅๅฟ—ๅŠŸ่ƒฝ](../core/logger.md)๏ผŒๅฏไปฅ้žๅธธๆ–นไพฟๅœฐๆ‰“ๅฐๅ„็ง็บงๅˆซ็š„ๆ—ฅๅฟ—ๅˆฐๅฏนๅบ”็š„ๆ—ฅๅฟ—ๆ–‡ไปถไธญ๏ผŒๆฏไธ€ไธช logger ๅฏน่ฑก้ƒฝๆไพ›ไบ† 4 ไธช็บงๅˆซ็š„ๆ–นๆณ•๏ผš @@ -295,7 +302,7 @@ module.exports = { ไฝ ๅฏไปฅ้€š่ฟ‡ไปฅไธ‹ๆ–นๅผๆฅๅผ•็”จ `Subscription` ๅŸบ็ฑป๏ผš ```js -const Subscription = require('egg').Subscription; +const Subscription = require("egg").Subscription; class Schedule extends Subscription { // ้œ€่ฆๅฎž็Žฐๆญคๆ–นๆณ• @@ -307,6 +314,7 @@ class Schedule extends Subscription { ๆ’ไปถๅผ€ๅ‘่€…ๅฏไปฅๆ นๆฎ่‡ชๅทฑ็š„้œ€ๆฑ‚๏ผŒๅŸบไบŽๅฎƒๅฎšๅˆถ่ฎข้˜…่ง„่Œƒ๏ผŒไพ‹ๅฆ‚ๅฎšๆ—ถไปปๅŠกๅฐฑๆ˜ฏไฝฟ็”จ่ฟ™็ง่ง„่Œƒๅฎž็Žฐ็š„ใ€‚ ็›ธๅ…ณ้“พๆŽฅ๏ผš + - [koa](http://koajs.com) - [koa.application](http://koajs.com/#application) - [koa.context](http://koajs.com/#context) diff --git a/site/docs/basics/plugin.md b/site/docs/basics/plugin.md index 2bb91b711f..3432f1bc6e 100644 --- a/site/docs/basics/plugin.md +++ b/site/docs/basics/plugin.md @@ -61,7 +61,7 @@ Then you need to declare it in the `config / plugin.js` application or framework // Use mysql plugin exports.mysql = { enable: true, - package: 'egg-mysql', + package: "egg-mysql", }; ``` @@ -111,7 +111,7 @@ Then declare in `plugin.local.js`: // config / plugin.local.js exports.dev = { enable: true, - package: 'egg-dev', + package: "egg-dev", }; ``` @@ -131,10 +131,10 @@ In this way, `npm i --production` in the production environment does not need to ```js // config / plugin.js -const path = require('path'); +const path = require("path"); exports.mysql = { enable: true, - path: path.join(__dirname, '../lib/plugin/egg-mysql'), + path: path.join(__dirname, "../lib/plugin/egg-mysql"), }; ``` @@ -146,11 +146,11 @@ The plugin will usually contain its own default configuration, you can overwrite // config / config.default.js exports.mysql = { client: { - host: 'mysql.com', - port: '3306', - user: 'test_user', - password: 'test_password', - database: 'test', + host: "mysql.com", + port: "3306", + user: "test_user", + password: "test_password", + database: "test", }, }; ``` diff --git a/site/docs/basics/plugin.zh-CN.md b/site/docs/basics/plugin.zh-CN.md index d2aaa8b67d..513ead1761 100644 --- a/site/docs/basics/plugin.zh-CN.md +++ b/site/docs/basics/plugin.zh-CN.md @@ -11,6 +11,7 @@ order: 9 - ๅฆ‚ไฝ•็ผ–ๅ†™ไธ€ไธชๆ’ไปถ๏ผŸ ๆŽฅไธ‹ๆฅๆˆ‘ไปฌๅฐฑๆฅ้€ไธ€่ฎจ่ฎบใ€‚ + ## ไธบไป€ไนˆ่ฆๆ’ไปถ ๆˆ‘ไปฌๅœจไฝฟ็”จ Koa ไธญ้—ดไปถ่ฟ‡็จ‹ไธญๅ‘็Žฐไบ†ไธ‹้ขไธ€ไบ›้—ฎ้ข˜๏ผš @@ -35,6 +36,7 @@ order: 9 - ๅฝ“้‡ๅˆฐไธŠไธ€่Š‚ๆๅˆฐ็š„ๅœบๆ™ฏๆ—ถ๏ผŒๅบ”็”จ้œ€ๅผ•ๅ…ฅๆ’ไปถใ€‚ - ๆ’ไปถๆœฌ่บซๅฏไปฅๅŒ…ๅซไธญ้—ดไปถใ€‚ - ๅคšไธชๆ’ไปถๅฏไปฅๅŒ…่ฃ…ไธบไธ€ไธช[ไธŠๅฑ‚ๆก†ๆžถ](../advanced/framework.md)ใ€‚ + ## ไฝฟ็”จๆ’ไปถ ๆ’ไปถ้€šๅธธ้€š่ฟ‡ npm ๆจกๅ—็š„ๆ–นๅผ่ฟ›่กŒๅค็”จ๏ผš @@ -60,7 +62,7 @@ $ npm i egg-mysql --save // ไฝฟ็”จ mysql ๆ’ไปถ exports.mysql = { enable: true, - package: 'egg-mysql', + package: "egg-mysql", }; ``` @@ -110,7 +112,7 @@ exports.onerror = false; // config/plugin.local.js exports.dev = { enable: true, - package: 'egg-dev', + package: "egg-dev", }; ``` @@ -118,7 +120,7 @@ exports.dev = { **ๆณจๆ„:** -- `plugin.default.js` ไธๅญ˜ๅœจ +- `plugin.default.js` ไธๅญ˜ๅœจ - **ๅช่ƒฝๅœจๅบ”็”จๅฑ‚ไฝฟ็”จ๏ผŒๆก†ๆžถๅฑ‚่ฏทๅ‹ฟไฝฟ็”จใ€‚** ### package ๅ’Œ path @@ -129,12 +131,13 @@ exports.dev = { ```js // config/plugin.js -const path = require('path'); +const path = require("path"); exports.mysql = { enable: true, - path: path.join(__dirname, '../lib/plugin/egg-mysql'), + path: path.join(__dirname, "../lib/plugin/egg-mysql"), }; ``` + ## ๆ’ไปถ้…็ฝฎ ๆ’ไปถไธ€่ˆฌไผšๅŒ…ๅซ่‡ชๅทฑ็š„้ป˜่ฎค้…็ฝฎใ€‚ๅบ”็”จๅผ€ๅ‘่€…ๅฏไปฅๅœจ `config.default.js` ไธญ่ฆ†็›–ๅฏนๅบ”็š„้…็ฝฎ๏ผš @@ -143,16 +146,17 @@ exports.mysql = { // config/config.default.js exports.mysql = { client: { - host: 'mysql.com', - port: '3306', - user: 'test_user', - password: 'test_password', - database: 'test' - } + host: "mysql.com", + port: "3306", + user: "test_user", + password: "test_password", + database: "test", + }, }; ``` ๅ…ทไฝ“็š„ๅˆๅนถ่ง„ๅˆ™ๅฏไปฅๅ‚่ง[้…็ฝฎ](./config.md)ใ€‚ + ## ๆ’ไปถๅˆ—่กจ - ๆก†ๆžถ้ป˜่ฎคๅ†…็ฝฎไบ†ไผไธš็บงๅบ”็”จ[ๅธธ็”จ็š„ๆ’ไปถ](https://eggjs.org/zh-cn/plugins/)๏ผš diff --git a/site/docs/basics/router.md b/site/docs/basics/router.md index 1af5cedaf0..74167c94de 100644 --- a/site/docs/basics/router.md +++ b/site/docs/basics/router.md @@ -15,7 +15,7 @@ By unifying routing rules, we can avoid the routing logics scattered in many pla // app/router.js module.exports = (app) => { const { router, controller } = app; - router.get('/user/:id', controller.user.info); + router.get("/user/:id", controller.user.info); }; ``` @@ -78,11 +78,11 @@ Here are some examples of writing routing rules: // app/router.js module.exports = (app) => { const { router, controller } = app; - router.get('/home', controller.home); - router.get('/user/:id', controller.user.page); - router.post('/admin', isAdmin, controller.admin); - router.post('/user', isLoginUser, hasAdminPermission, controller.user.create); - router.post('/api/v1/comments', controller.v1.comments.create); // app/controller/v1/comments.js + router.get("/home", controller.home); + router.get("/user/:id", controller.user.page); + router.post("/admin", isAdmin, controller.admin); + router.post("/user", isLoginUser, hasAdminPermission, controller.user.create); + router.post("/api/v1/comments", controller.v1.comments.create); // app/controller/v1/comments.js }; ``` @@ -94,8 +94,8 @@ We provide `app.router.resources('routerName', 'pathMatch', 'controller')` to ge // app/router.js module.exports = (app) => { const { router, controller } = app; - router.resources('posts', '/posts', controller.posts); - router.resources('users', '/api/v1/users', controller.v1.users); // app/controller/v1/users.js + router.resources("posts", "/posts", controller.posts); + router.resources("users", "/api/v1/users", controller.v1.users); // app/controller/v1/users.js }; ``` @@ -141,7 +141,7 @@ More practical examples will be shown below to demonstrate how to use the router ```js // app/router.js module.exports = (app) => { - app.router.get('/search', app.controller.search.index); + app.router.get("/search", app.controller.search.index); }; // app/controller/search.js @@ -157,7 +157,7 @@ exports.index = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get('/user/:id/:name', app.controller.user.info); + app.router.get("/user/:id/:name", app.controller.user.info); }; // app/controller/user.js @@ -175,10 +175,7 @@ Regular expressions, as well, can be used in routing rules to acquire parameters ```js // app/router.js module.exports = (app) => { - app.router.get( - /^\/package\/([\w-.]+\/[\w-.]+)$/, - app.controller.package.detail, - ); + app.router.get(/^\/package\/([\w-.]+\/[\w-.]+)$/, app.controller.package.detail); }; // app/controller/package.js @@ -196,7 +193,7 @@ exports.detail = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.post('/form', app.controller.form.post); + app.router.post("/form", app.controller.form.post); }; // app/controller/form.js @@ -231,17 +228,17 @@ exports.security = { ```js // app/router.js module.exports = (app) => { - app.router.post('/user', app.controller.user); + app.router.post("/user", app.controller.user); }; // app/controller/user.js const createRule = { username: { - type: 'email', + type: "email", }, password: { - type: 'password', - compare: 're-password', + type: "password", + compare: "re-password", }, }; @@ -261,13 +258,13 @@ exports.create = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get('index', '/home/index', app.controller.home.index); - app.redirect('/', '/home/index', 302); + app.router.get("index", "/home/index", app.controller.home.index); + app.redirect("/", "/home/index", 302); }; // app/controller/home.js exports.index = async (ctx) => { - ctx.body = 'hello controller'; + ctx.body = "hello controller"; }; // curl -L http://localhost:7001 @@ -278,15 +275,15 @@ exports.index = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get('/search', app.controller.search.index); + app.router.get("/search", app.controller.search.index); }; // app/controller/search.js exports.index = async (ctx) => { const type = ctx.query.type; - const q = ctx.query.q || 'nodejs'; + const q = ctx.query.q || "nodejs"; - if (type === 'bing') { + if (type === "bing") { ctx.redirect(`http://cn.bing.com/search?q=${q}`); } else { ctx.redirect(`https://www.google.co.kr/search?q=${q}`); @@ -318,12 +315,7 @@ module.exports = () => { // app/router.js module.exports = (app) => { - app.router.get( - 's', - '/search', - app.middleware.uppercase(), - app.controller.search, - ); + app.router.get("s", "/search", app.middleware.uppercase(), app.controller.search); }; // curl http://localhost:7001/search?name=egg @@ -338,20 +330,20 @@ If there is a need for some reasons, you can split routing rules like below: ```js // app/router.js module.exports = (app) => { - require('./router/news')(app); - require('./router/admin')(app); + require("./router/news")(app); + require("./router/admin")(app); }; // app/router/news.js module.exports = (app) => { - app.router.get('/news/list', app.controller.news.list); - app.router.get('/news/detail', app.controller.news.detail); + app.router.get("/news/list", app.controller.news.list); + app.router.get("/news/detail", app.controller.news.detail); }; // app/router/admin.js module.exports = (app) => { - app.router.get('/admin/user', app.controller.admin.user); - app.router.get('/admin/log', app.controller.admin.log); + app.router.get("/admin/user", app.controller.admin.user); + app.router.get("/admin/log", app.controller.admin.log); }; ``` diff --git a/site/docs/basics/router.zh-CN.md b/site/docs/basics/router.zh-CN.md index 7f8101a330..02bb37f54b 100644 --- a/site/docs/basics/router.zh-CN.md +++ b/site/docs/basics/router.zh-CN.md @@ -6,6 +6,7 @@ order: 6 Router ไธป่ฆ็”จๆฅๆ่ฟฐ่ฏทๆฑ‚ URL ๅ’Œๅ…ทไฝ“ๆ‰ฟๆ‹…ๆ‰ง่กŒๅŠจไฝœ็š„ Controller ็š„ๅฏนๅบ”ๅ…ณ็ณป๏ผŒๆก†ๆžถ็บฆๅฎšไบ† `app/router.js` ๆ–‡ไปถ็”จไบŽ็ปŸไธ€ๆ‰€ๆœ‰่ทฏ็”ฑ่ง„ๅˆ™ใ€‚ ้€š่ฟ‡็ปŸไธ€็š„้…็ฝฎ๏ผŒๆˆ‘ไปฌๅฏไปฅ้ฟๅ…่ทฏ็”ฑ่ง„ๅˆ™้€ป่พ‘ๆ•ฃ่ฝๅœจๅคšไธชๅœฐๆ–น๏ผŒไปŽ่€Œๅ‡บ็Žฐๆœช็Ÿฅ็š„ๅ†ฒ็ชใ€‚้›†ไธญๅœจไธ€่ตท๏ผŒๆˆ‘ไปฌๅฏไปฅๆ›ดๆ–นไพฟๅœฐๆฅๆŸฅ็œ‹ๅ…จๅฑ€็š„่ทฏ็”ฑ่ง„ๅˆ™ใ€‚ + ## ๅฆ‚ไฝ•ๅฎšไน‰ Router - `app/router.js` ้‡Œ้ขๅฎšไน‰ URL ่ทฏ็”ฑ่ง„ๅˆ™ @@ -14,7 +15,7 @@ Router ไธป่ฆ็”จๆฅๆ่ฟฐ่ฏทๆฑ‚ URL ๅ’Œๅ…ทไฝ“ๆ‰ฟๆ‹…ๆ‰ง่กŒๅŠจไฝœ็š„ Controller // app/router.js module.exports = (app) => { const { router, controller } = app; - router.get('/user/:id', controller.user.info); + router.get("/user/:id", controller.user.info); }; ``` @@ -33,6 +34,7 @@ class UserController extends Controller { ``` ่ฟ™ๆ ทๅฐฑๅฎŒๆˆไบ†ไธ€ไธชๆœ€็ฎ€ๅ•็š„ Router ๅฎšไน‰๏ผŒๅฝ“็”จๆˆทๆ‰ง่กŒ `GET /user/123`๏ผŒ`user.js` ่ฟ™ไธช้‡Œ้ข็š„ info ๆ–นๆณ•ๅฐฑไผšๆ‰ง่กŒใ€‚ + ## Router ่ฏฆ็ป†ๅฎšไน‰่ฏดๆ˜Ž ไธ‹้ขๆ˜ฏ่ทฏ็”ฑ็š„ๅฎŒๆ•ดๅฎšไน‰๏ผŒๅ‚ๆ•ฐๅฏไปฅๆ นๆฎๅœบๆ™ฏ็š„ไธๅŒ๏ผŒ่‡ช็”ฑ้€‰ๆ‹ฉ๏ผš @@ -74,13 +76,13 @@ router.verb('router-name', 'path-match', middleware1, ..., middlewareN, app.cont ```js // app/router.js -module.exports = app => { +module.exports = (app) => { const { router, controller } = app; - router.get('/home', controller.home); - router.get('/user/:id', controller.user.page); - router.post('/admin', isAdmin, controller.admin); - router.post('/user', isLoginUser, hasAdminPermission, controller.user.create); - router.post('/api/v1/comments', controller.v1.comments.create); // app/controller/v1/comments.js + router.get("/home", controller.home); + router.get("/user/:id", controller.user.page); + router.post("/admin", isAdmin, controller.admin); + router.post("/user", isLoginUser, hasAdminPermission, controller.user.create); + router.post("/api/v1/comments", controller.v1.comments.create); // app/controller/v1/comments.js }; ``` @@ -90,10 +92,10 @@ module.exports = app => { ```js // app/router.js -module.exports = app => { +module.exports = (app) => { const { router, controller } = app; - router.resources('posts', '/api/posts', controller.posts); - router.resources('users', '/api/v1/users', controller.v1.users); // app/controller/v1/users.js + router.resources("posts", "/api/posts", controller.posts); + router.resources("users", "/api/v1/users", controller.v1.users); // app/controller/v1/users.js }; ``` @@ -127,6 +129,7 @@ exports.destroy = async () => {}; ``` ๅฆ‚ๆžœๆˆ‘ไปฌไธ้œ€่ฆๅ…ถไธญ็š„ๆŸไบ›ๆ–นๆณ•๏ผŒๅฏไปฅ็œ็•ฅๅœจ `posts.js` ้‡Œ้ข็š„ๅฎž็Žฐ๏ผŒ่ฟ™ๆ ทๅฏนๅบ”็š„ URL ่ทฏๅพ„ไนŸไธไผšๆณจๅ†Œๅˆฐ Router ไธญใ€‚ + ## router ๅฎžๆˆ˜ ไธ‹้ข้€š่ฟ‡ๆ›ดๅคšๅฎž้™…็š„ไพ‹ๅญ๏ผŒๆฅ่ฏดๆ˜Ž `router` ็š„็”จๆณ•ใ€‚ @@ -138,7 +141,7 @@ exports.destroy = async () => {}; ```js // app/router.js module.exports = (app) => { - app.router.get('/search', app.controller.search.index); + app.router.get("/search", app.controller.search.index); }; // app/controller/search.js @@ -154,7 +157,7 @@ exports.index = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get('/user/:id/:name', app.controller.user.info); + app.router.get("/user/:id/:name", app.controller.user.info); }; // app/controller/user.js @@ -172,10 +175,7 @@ exports.info = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get( - /^\/package\/([\w-.]+\/[\w-.]+)$/, - app.controller.package.detail, - ); + app.router.get(/^\/package\/([\w-.]+\/[\w-.]+)$/, app.controller.package.detail); }; // app/controller/package.js @@ -193,7 +193,7 @@ exports.detail = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.post('/form', app.controller.form.post); + app.router.post("/form", app.controller.form.post); }; // app/controller/form.js @@ -217,7 +217,7 @@ exports.post = async (ctx) => { ```javascript exports.security = { - csrf: false + csrf: false, }; ``` @@ -226,17 +226,17 @@ exports.security = { ```js // app/router.js module.exports = (app) => { - app.router.post('/user', app.controller.user); + app.router.post("/user", app.controller.user); }; // app/controller/user.js const createRule = { username: { - type: 'email', + type: "email", }, password: { - type: 'password', - compare: 're-password', + type: "password", + compare: "re-password", }, }; @@ -256,13 +256,13 @@ exports.create = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get('index', '/home/index', app.controller.home.index); - app.router.redirect('/', '/home/index', 302); + app.router.get("index", "/home/index", app.controller.home.index); + app.router.redirect("/", "/home/index", 302); }; // app/controller/home.js exports.index = async (ctx) => { - ctx.body = 'hello controller'; + ctx.body = "hello controller"; }; // curl -L http://localhost:7001 @@ -273,15 +273,15 @@ exports.index = async (ctx) => { ```js // app/router.js module.exports = (app) => { - app.router.get('/search', app.controller.search.index); + app.router.get("/search", app.controller.search.index); }; // app/controller/search.js exports.index = async (ctx) => { const type = ctx.query.type; - const q = ctx.query.q || 'nodejs'; + const q = ctx.query.q || "nodejs"; - if (type === 'bing') { + if (type === "bing") { ctx.redirect(`http://cn.bing.com/search?q=${q}`); } else { ctx.redirect(`https://www.google.co.kr/search?q=${q}`); @@ -313,12 +313,7 @@ module.exports = () => { // app/router.js module.exports = (app) => { - app.router.get( - 's', - '/search', - app.middleware.uppercase(), - app.controller.search.index, - ); + app.router.get("s", "/search", app.middleware.uppercase(), app.controller.search.index); }; // curl http://localhost:7001/search?name=egg @@ -333,20 +328,20 @@ module.exports = (app) => { ```js // app/router.js module.exports = (app) => { - require('./router/news')(app); - require('./router/admin')(app); + require("./router/news")(app); + require("./router/admin")(app); }; // app/router/news.js module.exports = (app) => { - app.router.get('/news/list', app.controller.news.list); - app.router.get('/news/detail', app.controller.news.detail); + app.router.get("/news/list", app.controller.news.list); + app.router.get("/news/detail", app.controller.news.detail); }; // app/router/admin.js module.exports = (app) => { - app.router.get('/admin/user', app.controller.admin.user); - app.router.get('/admin/log', app.controller.admin.log); + app.router.get("/admin/user", app.controller.admin.user); + app.router.get("/admin/log", app.controller.admin.log); }; ``` diff --git a/site/docs/basics/schedule.md b/site/docs/basics/schedule.md index 734f72bf9c..fd3095e415 100644 --- a/site/docs/basics/schedule.md +++ b/site/docs/basics/schedule.md @@ -18,21 +18,21 @@ All scheduled tasks should be placed in directory `app/schedule`. Each file is a A simple example, to define a scheduled task to update the remote data to the memory cache, we can create a `update_cache.js` file in the directory 'app/schedule` ```js -const Subscription = require('egg').Subscription; +const Subscription = require("egg").Subscription; class UpdateCache extends Subscription { // using `schedule` property to set the scheduled task execution interval and other configurations static get schedule() { return { - interval: '1m', // 1 minute interval - type: 'all', // specify all `workers` need to execute + interval: "1m", // 1 minute interval + type: "all", // specify all `workers` need to execute }; } // `subscribe` is the function to be executed when the scheduled task is triggered async subscribe() { - const res = await this.ctx.curl('http://www.api.com/cache', { - dataType: 'json', + const res = await this.ctx.curl("http://www.api.com/cache", { + dataType: "json", }); this.ctx.app.cache = res.data; } @@ -46,12 +46,12 @@ Can also be abbreviated as ```js module.exports = { schedule: { - interval: '1m', // 1 minute interval - type: 'all', // specify all `workers` need to execute + interval: "1m", // 1 minute interval + type: "all", // specify all `workers` need to execute }, async task(ctx) { - const res = await ctx.curl('http://www.api.com/cache', { - dataType: 'json', + const res = await ctx.curl("http://www.api.com/cache", { + dataType: "json", }); ctx.app.cache = res.data; }, @@ -80,7 +80,7 @@ Configure the scheduled tasks by `schedule.interval`, scheduled tasks will be ex module.exports = { schedule: { // executed every 10 seconds - interval: '10s', + interval: "10s", }, }; ``` @@ -107,7 +107,7 @@ Configure the scheduled tasks by `schedule.cron`, scheduled tasks will be execut module.exports = { schedule: { // executed every three hours (zero minutes and zero seconds) - cron: '0 0 */3 * * *', + cron: "0 0 */3 * * *", }, }; ``` @@ -151,11 +151,11 @@ module.exports = (app) => { return { schedule: { interval: app.config.cacheTick, - type: 'all', + type: "all", }, async task(ctx) { - const res = await ctx.curl('http://www.api.com/cache', { - contentType: 'json', + const res = await ctx.curl("http://www.api.com/cache", { + contentType: "json", }); ctx.app.cache = res.data; }, @@ -172,13 +172,13 @@ There are some scenarios we may need to manually execute scheduled tasks, for ex - Executing scheduled tasks manually for more elegant unit testing of scheduled tasks. ```js -const mm = require('egg-mock'); -const assert = require('assert'); +const mm = require("egg-mock"); +const assert = require("assert"); -it('should schedule work fine', async () => { +it("should schedule work fine", async () => { const app = mm.app(); await app.ready(); - await app.runSchedule('update_cache'); + await app.runSchedule("update_cache"); assert(app.cache); }); ``` @@ -190,7 +190,7 @@ module.exports = (app) => { app.beforeStart(async () => { // ensure the data is ready before the application starts listening port // follow-up data updates automatically by the scheduled task - await app.runSchedule('update_cache'); + await app.runSchedule("update_cache"); }); }; ``` @@ -212,7 +212,7 @@ module.exports = (agent) => { agent.mq.subscribe(this.schedule.scene, () => this.sendOne()); } } - agent.schedule.use('cluster', ClusterStrategy); + agent.schedule.use("cluster", ClusterStrategy); }; ``` diff --git a/site/docs/basics/schedule.zh-CN.md b/site/docs/basics/schedule.zh-CN.md index 40f9946bd1..a0b7391567 100644 --- a/site/docs/basics/schedule.zh-CN.md +++ b/site/docs/basics/schedule.zh-CN.md @@ -10,6 +10,7 @@ order: 10 3. ๅฎšๆ—ถ่ฟ›่กŒๆ–‡ไปถๅˆ‡ๅ‰ฒใ€ไธดๆ—ถๆ–‡ไปถๅˆ ้™คใ€‚ ๆก†ๆžถๆไพ›ไบ†ไธ€ๅฅ—ๆœบๅˆถๆฅ่ฎฉๅฎšๆ—ถไปปๅŠก็š„็ผ–ๅ†™ๅ’Œ็ปดๆŠคๆ›ดๅŠ ไผ˜้›…ใ€‚ + ## ็ผ–ๅ†™ๅฎšๆ—ถไปปๅŠก ๆ‰€ๆœ‰็š„ๅฎšๆ—ถไปปๅŠก้ƒฝ็ปŸไธ€ๅญ˜ๆ”พๅœจ `app/schedule` ็›ฎๅฝ•ไธ‹๏ผŒๆฏไธ€ไธชๆ–‡ไปถ้ƒฝๆ˜ฏไธ€ไธช็‹ฌ็ซ‹็š„ๅฎšๆ—ถไปปๅŠก๏ผŒๅฏไปฅ้…็ฝฎๅฎšๆ—ถไปปๅŠก็š„ๅฑžๆ€งๅ’Œ่ฆๆ‰ง่กŒ็š„ๆ–นๆณ•ใ€‚ @@ -17,21 +18,21 @@ order: 10 ไธ€ไธช็ฎ€ๅ•็š„ไพ‹ๅญ๏ผŒๆˆ‘ไปฌๅฎšไน‰ไธ€ไธชๆ›ดๆ–ฐ่ฟœ็จ‹ๆ•ฐๆฎๅˆฐๅ†…ๅญ˜็ผ“ๅญ˜็š„ๅฎšๆ—ถไปปๅŠก๏ผŒๅฐฑๅฏไปฅๅœจ `app/schedule` ็›ฎๅฝ•ไธ‹ๅˆ›ๅปบไธ€ไธช `update_cache.js` ๆ–‡ไปถใ€‚ ```js -const Subscription = require('egg').Subscription; +const Subscription = require("egg").Subscription; class UpdateCache extends Subscription { // ้€š่ฟ‡ schedule ๅฑžๆ€งๆฅ่ฎพ็ฝฎๅฎšๆ—ถไปปๅŠก็š„ๆ‰ง่กŒ้—ด้š”็ญ‰้…็ฝฎ static get schedule() { return { - interval: '1m', // 1 ๅˆ†้’Ÿ้—ด้š” - type: 'all', // ๆŒ‡ๅฎšๆ‰€ๆœ‰็š„ worker ้ƒฝ้œ€่ฆๆ‰ง่กŒ + interval: "1m", // 1 ๅˆ†้’Ÿ้—ด้š” + type: "all", // ๆŒ‡ๅฎšๆ‰€ๆœ‰็š„ worker ้ƒฝ้œ€่ฆๆ‰ง่กŒ }; } // subscribe ๆ˜ฏ็œŸๆญฃๅฎšๆ—ถไปปๅŠกๆ‰ง่กŒๆ—ถ่ขซ่ฟ่กŒ็š„ๅ‡ฝๆ•ฐ async subscribe() { - const res = await this.ctx.curl('http://www.api.com/cache', { - dataType: 'json', + const res = await this.ctx.curl("http://www.api.com/cache", { + dataType: "json", }); this.ctx.app.cache = res.data; } @@ -45,12 +46,12 @@ module.exports = UpdateCache; ```js module.exports = { schedule: { - interval: '1m', // 1 ๅˆ†้’Ÿ้—ด้š” - type: 'all', // ๆŒ‡ๅฎšๆ‰€ๆœ‰็š„ worker ้ƒฝ้œ€่ฆๆ‰ง่กŒ + interval: "1m", // 1 ๅˆ†้’Ÿ้—ด้š” + type: "all", // ๆŒ‡ๅฎšๆ‰€ๆœ‰็š„ worker ้ƒฝ้œ€่ฆๆ‰ง่กŒ }, async task(ctx) { - const res = await ctx.curl('http://www.api.com/cache', { - dataType: 'json', + const res = await ctx.curl("http://www.api.com/cache", { + dataType: "json", }); ctx.app.cache = res.data; }, @@ -79,7 +80,7 @@ module.exports = { module.exports = { schedule: { // ๆฏ 10 ็ง’ๆ‰ง่กŒไธ€ๆฌก - interval: '10s', + interval: "10s", }, }; ``` @@ -106,7 +107,7 @@ module.exports = { module.exports = { schedule: { // ๆฏไธ‰ๅฐๆ—ถๅ‡†็‚นๆ‰ง่กŒไธ€ๆฌก - cron: '0 0 */3 * * *', + cron: "0 0 */3 * * *", }, }; ``` @@ -140,6 +141,7 @@ config.customLogger = { }, }; ``` + ### ๅŠจๆ€้…็ฝฎๅฎšๆ—ถไปปๅŠก ๆœ‰ๆ—ถๅ€™๏ผŒๆˆ‘ไปฌ้œ€่ฆ้…็ฝฎๅฎšๆ—ถไปปๅŠก็š„ๅ‚ๆ•ฐใ€‚ๅฎšๆ—ถไปปๅŠก่ฟ˜ๅฏไปฅๆ”ฏๆŒๅฆไธ€็งๅ†™ๆณ•๏ผš @@ -149,11 +151,11 @@ module.exports = (app) => { return { schedule: { interval: app.config.cacheTick, - type: 'all', + type: "all", }, async task(ctx) { - const res = await ctx.curl('http://www.api.com/cache', { - contentType: 'json', + const res = await ctx.curl("http://www.api.com/cache", { + contentType: "json", }); ctx.app.cache = res.data; }, @@ -170,13 +172,13 @@ module.exports = (app) => { - ๆ‰‹ๅŠจๆ‰ง่กŒๅฎšๆ—ถไปปๅŠกๅฏไปฅๆ›ดไผ˜้›…ๅœฐ็ผ–ๅ†™ๅฎšๆ—ถไปปๅŠก็š„ๅ•ๅ…ƒๆต‹่ฏ•ใ€‚ ```js -const mm = require('egg-mock'); -const assert = require('assert'); +const mm = require("egg-mock"); +const assert = require("assert"); -it('should schedule work fine', async () => { +it("should schedule work fine", async () => { const app = mm.app(); await app.ready(); - await app.runSchedule('update_cache'); + await app.runSchedule("update_cache"); assert(app.cache); }); ``` @@ -188,7 +190,7 @@ module.exports = (app) => { app.beforeStart(async () => { // ไฟ่ฏๅบ”็”จๅฏๅŠจ็›‘ๅฌ็ซฏๅฃๅ‰๏ผŒๆ•ฐๆฎๅทฒ็ปๅ‡†ๅค‡ๅฅฝ // ๅŽ็ปญๆ•ฐๆฎ็š„ๆ›ดๆ–ฐ็”ฑๅฎšๆ—ถไปปๅŠก่‡ชๅŠจ่งฆๅ‘ - await app.runSchedule('update_cache'); + await app.runSchedule("update_cache"); }); }; ``` @@ -210,7 +212,7 @@ module.exports = (agent) => { agent.mq.subscribe(this.schedule.scene, () => this.sendOne()); } } - agent.schedule.use('cluster', ClusterStrategy); + agent.schedule.use("cluster", ClusterStrategy); }; ``` @@ -218,4 +220,4 @@ module.exports = (agent) => { - `this.schedule` - ๅฎšๆ—ถไปปๅŠก็š„ๅฑžๆ€ง๏ผŒๆ‰€ๆœ‰ไปปๅŠก้ป˜่ฎคๆ”ฏๆŒ็š„ `disable` ๅฑžๆ€ง๏ผŒไปฅๅŠๅ…ถไป–่‡ชๅฎšไน‰้…็ฝฎ็š„่งฃๆžใ€‚ - `this.sendOne(...args)` - ้šๆœบ้€š็ŸฅๆŸไธช worker ๆ‰ง่กŒ task๏ผŒ`args` ไผšไผ ้€’็ป™ `subscribe(...args)` ๆˆ– `task(ctx, ...args)` ๆ–นๆณ•ใ€‚ -- `this.sendAll(...args)` - ้€š็Ÿฅๆ‰€ๆœ‰็š„ worker ๆ‰ง่กŒ taskใ€‚ \ No newline at end of file +- `this.sendAll(...args)` - ้€š็Ÿฅๆ‰€ๆœ‰็š„ worker ๆ‰ง่กŒ taskใ€‚ diff --git a/site/docs/basics/service.md b/site/docs/basics/service.md index 3a8e3af6f2..c4cd7cf4c0 100644 --- a/site/docs/basics/service.md +++ b/site/docs/basics/service.md @@ -18,14 +18,11 @@ Simply speaking, Service is an abstract layer which is used to encapsulate busin ```js // app/service/user.js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { async find(uid) { - const user = await this.ctx.db.query( - 'select * from user where uid = ?', - uid, - ); + const user = await this.ctx.db.query("select * from user where uid = ?", uid); return user; } } @@ -73,11 +70,11 @@ We begin to see how to use Service from a complete example below. ```js // app/router.js module.exports = (app) => { - app.router.get('/user/:id', app.controller.user.info); + app.router.get("/user/:id", app.controller.user.info); }; // app/controller/user.js -const Controller = require('egg').Controller; +const Controller = require("egg").Controller; class UserController extends Controller { async info() { const { ctx } = this; @@ -89,7 +86,7 @@ class UserController extends Controller { module.exports = UserController; // app/service/user.js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { // the constructor is not a must by default // constructor(ctx) { @@ -99,10 +96,7 @@ class UserService extends Service { // } async find(uid) { // suppose we've got user's id and are going to get detailed user information from databases - const user = await this.ctx.db.query( - 'select * from user where uid = ?', - uid, - ); + const user = await this.ctx.db.query("select * from user where uid = ?", uid); // suppose some complex processes should be made here, and demanded informations are returned then. const picture = await this.getPicture(uid); @@ -116,7 +110,7 @@ class UserService extends Service { async getPicture(uid) { const result = await this.ctx.curl(`http://photoserver/uid=${uid}`, { - dataType: 'json', + dataType: "json", }); return result.data; } diff --git a/site/docs/basics/service.zh-CN.md b/site/docs/basics/service.zh-CN.md index 330852ddc7..ab77a21e2a 100644 --- a/site/docs/basics/service.zh-CN.md +++ b/site/docs/basics/service.zh-CN.md @@ -8,22 +8,21 @@ order: 8 - ไฟๆŒ Controller ไธญ็š„้€ป่พ‘ๆ›ด็ฎ€ๆดใ€‚ - ไฟๆŒไธšๅŠก้€ป่พ‘็š„็‹ฌ็ซ‹ๆ€ง๏ผŒๆŠฝ่ฑกๅ‡บ็š„ Service ๅฏไปฅ่ขซๅคšไธช Controller ้‡ๅคไฝฟ็”จใ€‚ - ๅˆ†็ฆป้€ป่พ‘ๅ’Œๅฑ•็คบ๏ผŒ่ฟ™ๆ ทๆ›ดไพฟไบŽ็ผ–ๅ†™ๆต‹่ฏ•็”จไพ‹ใ€‚ๅ…ทไฝ“็š„ๆต‹่ฏ•็”จไพ‹็ผ–ๅ†™ๆ–นๆณ•๏ผŒๅฏไปฅๅ‚่ง[่ฟ™้‡Œ](../core/unittest.md)ใ€‚ + ## ไฝฟ็”จๅœบๆ™ฏ - ๆ•ฐๆฎๅค„็†๏ผšๅฝ“้œ€่ฆๅฑ•็คบ็š„ไฟกๆฏ้กปไปŽๆ•ฐๆฎๅบ“่Žทๅ–๏ผŒๅนถ็ป่ง„ๅˆ™่ฎก็ฎ—ๅŽๆ‰่ƒฝๆ˜พ็คบ็ป™็”จๆˆท๏ผŒๆˆ–่ฎก็ฎ—ๅŽ้œ€ๆ›ดๆ–ฐๆ•ฐๆฎๅบ“ๆ—ถใ€‚ - ็ฌฌไธ‰ๆ–นๆœๅŠก่ฐƒ็”จ๏ผšไพ‹ๅฆ‚่Žทๅ– GitHub ไฟกๆฏ็ญ‰ใ€‚ + ## ๅฎšไน‰ Service ```js // app/service/user.js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { async find(uid) { - const user = await this.ctx.db.query( - 'select * from user where uid = ?', - uid - ); + const user = await this.ctx.db.query("select * from user where uid = ?", uid); return user; } } @@ -65,14 +64,15 @@ module.exports = UserService; - ไธ€ไธช Service ๆ–‡ไปถไป…ๅŒ…ๅซไธ€ไธช็ฑป๏ผŒ่ฏฅ็ฑป้œ€้€š่ฟ‡ `module.exports` ๅฏผๅ‡บใ€‚ - Service ๅบ”้€š่ฟ‡ Class ๅฝขๅผๅฎšไน‰๏ผŒไธ”็ปงๆ‰ฟ่‡ช `egg.Service`ใ€‚ - Service ไธๆ˜ฏๅ•ไพ‹๏ผŒๅฎƒๆ˜ฏ่ฏทๆฑ‚็บงๅˆซ็š„ๅฏน่ฑกใ€‚ๆก†ๆžถๅœจๆฏๆฌก่ฏทๆฑ‚ไธญๅˆๆฌก่ฎฟ้—ฎ `ctx.service.xx` ๆ—ถๆ‰่ฟ›่กŒๅฎžไพ‹ๅŒ–ใ€‚ๅ› ๆญค๏ผŒService ไธญๅฏไปฅ้€š่ฟ‡ `this.ctx` ่Žทๅ–ๅฝ“ๅ‰่ฏทๆฑ‚็š„ไธŠไธ‹ๆ–‡ใ€‚ + ```js // app/router.js -module.exports = app => { - app.router.get('/user/:id', app.controller.user.info); +module.exports = (app) => { + app.router.get("/user/:id", app.controller.user.info); }; // app/controller/user.js -const Controller = require('egg').Controller; +const Controller = require("egg").Controller; class UserController extends Controller { async info() { const { ctx } = this; @@ -84,7 +84,7 @@ class UserController extends Controller { module.exports = UserController; // app/service/user.js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { // ้ป˜่ฎคไธ้œ€่ฆๆไพ›ๆž„้€ ๅ‡ฝๆ•ฐใ€‚ /* constructor(ctx) { @@ -94,10 +94,7 @@ class UserService extends Service { } */ async find(uid) { // ๅ‡ๅฆ‚ๆˆ‘ไปฌๆ‹ฟๅˆฐ็”จๆˆท id๏ผŒไปŽๆ•ฐๆฎๅบ“่Žทๅ–็”จๆˆท่ฏฆ็ป†ไฟกๆฏ - const user = await this.ctx.db.query( - 'select * from user where uid = ?', - uid - ); + const user = await this.ctx.db.query("select * from user where uid = ?", uid); // ๅ‡ๅฎš่ฟ™้‡Œ่ฟ˜ๆœ‰ไธ€ไบ›ๅคๆ‚็š„่ฎก็ฎ—๏ผŒ็„ถๅŽ่ฟ”ๅ›ž้œ€่ฆ็š„ไฟกๆฏ const picture = await this.getPicture(uid); @@ -105,13 +102,13 @@ class UserService extends Service { return { name: user.user_name, age: user.age, - picture + picture, }; } async getPicture(uid) { const result = await this.ctx.curl(`http://photoserver/uid=${uid}`, { - dataType: 'json' + dataType: "json", }); return result.data; } diff --git a/site/docs/basics/structure.zh-CN.md b/site/docs/basics/structure.zh-CN.md index 884426b154..780fca55d1 100644 --- a/site/docs/basics/structure.zh-CN.md +++ b/site/docs/basics/structure.zh-CN.md @@ -58,7 +58,6 @@ egg-project - `test/**` ็”จไบŽๅ•ๅ…ƒๆต‹่ฏ•๏ผŒๅ…ทไฝ“ๅ‚่ง [ๅ•ๅ…ƒๆต‹่ฏ•](../core/unittest.md)ใ€‚ - `app.js` ๅ’Œ `agent.js` ็”จไบŽ่‡ชๅฎšไน‰ๅฏๅŠจๆ—ถ็š„ๅˆๅง‹ๅŒ–ๅทฅไฝœ๏ผŒๅ…ทไฝ“ๅ‚่ง [ๅฏๅŠจ่‡ชๅฎšไน‰](./app-start.md)ใ€‚ๅ…ณไบŽ `agent.js` ็š„ไฝœ็”จ๏ผŒๅ‚่ง [Agent ๆœบๅˆถ](../core/cluster-and-ipc.md#agent-ๆœบๅˆถ)ใ€‚ - ็”ฑๅ†…็ฝฎๆ’ไปถ็บฆๅฎš็š„็›ฎๅฝ•๏ผš - `app/public/**` ็”จไบŽๆ”พ็ฝฎ้™ๆ€่ต„ๆบ๏ผŒๅ…ทไฝ“ๅ‚่งๅ†…็ฝฎๆ’ไปถ [egg-static](https://github.com/eggjs/egg-static)ใ€‚ diff --git a/site/docs/community/CONTRIBUTING.zh-CN.md b/site/docs/community/CONTRIBUTING.zh-CN.md index e3b7a83500..e367114ca0 100644 --- a/site/docs/community/CONTRIBUTING.zh-CN.md +++ b/site/docs/community/CONTRIBUTING.zh-CN.md @@ -1,7 +1,5 @@ --- - title: ไปฃ็ ่ดก็Œฎ่ง„่Œƒ - --- ๆœ‰ไปปไฝ•็–‘้—ฎ๏ผŒๆฌข่ฟŽๆไบค [issue](https://github.com/eggjs/egg/issues)๏ผŒๆˆ–่€…็›ดๆŽฅไฟฎๆ”นๆไบค [PR](https://github.com/eggjs/egg/pulls)๏ผ @@ -54,6 +52,7 @@ $ git checkout -b branch-name # ๅผ€ๅ‘ๅฎŒๆˆๅŽ่ท‘ไธ‹ๆต‹่ฏ•ๆ˜ฏๅฆ้€š่ฟ‡๏ผŒๅฟ…่ฆๆ—ถ้œ€่ฆๆ–ฐๅขžๆˆ–ไฟฎๆ”นๆต‹่ฏ•็”จไพ‹ $ npm test ``` + # ๆต‹่ฏ•้€š่ฟ‡ๅŽ๏ผŒๆไบคไปฃ็ ๏ผŒmessage ่งไธ‹้ข็š„่ง„่Œƒ ``` @@ -63,6 +62,7 @@ $ git push origin branch-name ``` ็”ฑไบŽ่ฐไนŸๆ— ๆณ•ไฟ่ฏ่ฟ‡ไบ†ๅคšไน…ไน‹ๅŽ่ฟ˜่ฎฐๅพ—ๅคšๅฐ‘๏ผŒไธบไบ†ๅŽๆœŸๅ›žๆบฏๅކๅฒ็š„ๆ–นไพฟ๏ผŒ่ฏทๅœจๆไบค MR ๆ—ถ็กฎไฟๆไพ›ไบ†ไปฅไธ‹ไฟกๆฏใ€‚ + 1. ้œ€ๆฑ‚็‚น๏ผˆไธ€่ˆฌๅ…ณ่” issue ๆˆ–่€…ๆณจ้‡Š้ƒฝ็ฎ—๏ผ‰ 2. ๅ‡็บงๅŽŸๅ› ๏ผˆไธๅŒไบŽ issue๏ผŒๅฏไปฅ็ฎ€่ฆๆ่ฟฐไธ‹ไธบไป€ไนˆ่ฆๅค„็†๏ผ‰ 3. ๆก†ๆžถๆต‹่ฏ•็‚น๏ผˆๅฏไปฅๅ…ณ่”ๅˆฐๆต‹่ฏ•ๆ–‡ไปถ๏ผŒไธ็”จ่ฏฆ็ป†ๆ่ฟฐ๏ผŒๅ…ณ้”ฎ็‚นๅณๅฏ๏ผ‰ @@ -115,7 +115,7 @@ $ git push origin branch-name - **ๅฝ“ๆœ‰้žๅ…ผๅฎนไฟฎๆ”น๏ผˆBreaking Change๏ผ‰ๆ—ถๅฟ…้กปๅœจ่ฟ™้‡Œๆ่ฟฐๆธ…ๆฅš** - ๅ…ณ่”็›ธๅ…ณ issue๏ผŒๅฆ‚ `Closes #1, Closes #2, #3` -- ๅฆ‚ๆžœๅŠŸ่ƒฝ็‚นๆœ‰ๆ–ฐๅขžๆˆ–ไฟฎๆ”น็š„๏ผŒ่ฟ˜้œ€่ฆๅ…ณ่”ๆ–‡ๆกฃ `doc` ๅ’Œ `egg-core` ็š„ PR๏ผŒๅฆ‚ `eggjs/egg-core#123` +- ๅฆ‚ๆžœๅŠŸ่ƒฝ็‚นๆœ‰ๆ–ฐๅขžๆˆ–ไฟฎๆ”น็š„๏ผŒ่ฟ˜้œ€่ฆๅ…ณ่”ๆ–‡ๆกฃ `doc` ๅ’Œ `egg-core` ็š„ PR๏ผŒๅฆ‚ `eggjs/egg-core#123` ็คบไพ‹ @@ -149,6 +149,7 @@ BREAKING CHANGE: - ๅฆ‚ๆžœๆ ‡้ข˜่ขซๅฝ“ๅšไธ€ไธชๅฎŒๆ•ด็š„่‹ฑ่ฏญๅฅๅญ๏ผŒ่ฏทๆŒ‰็…ง่‹ฑ่ฏญๅฅๅญ็š„่ฏญๆณ•ๆ ผๅผๅคงๅฐๅ†™๏ผˆไพ‹ๅฆ‚๏ผšๅธธ่ง้—ฎ้ข˜ FAQ ไธญๆฏไธ€ไธชๆ ‡้ข˜้ƒฝๆ˜ฏไธ€ไธช่‹ฑ่ฏญๅฅๅญ๏ผ‰ใ€‚ ๆœ‰ๅ…ณ่ฏฆๆƒ…๏ผŒๅฏไปฅๅ‚่€ƒ[่‹ฑ่ฏญๆ ‡้ข˜ๅคงๅฐๅ†™]ใ€‚ + ## ๅ‘ๅธƒ็ฎก็† Egg ๅŸบไบŽ [semver]๏ผˆ่ฏญไน‰ๅŒ–็‰ˆๆœฌๅท๏ผ‰่ฟ›่กŒๅ‘ๅธƒใ€‚ @@ -163,7 +164,7 @@ Egg ๅŸบไบŽ [semver]๏ผˆ่ฏญไน‰ๅŒ–็‰ˆๆœฌๅท๏ผ‰่ฟ›่กŒๅ‘ๅธƒใ€‚ - `next` ๅˆ†ๆ”ฏ่ฎพ็ฝฎ tag ไธบ `next`ใ€‚ไธŠๅฑ‚ๆก†ๆžถๅฏไปฅ้€š่ฟ‡ `egg@next` ๅผ•็”จๅผ€ๅ‘ไธญ็š„็‰ˆๆœฌ่ฟ›่กŒๆต‹่ฏ•ใ€‚ - Egg ๆŒ็ปญ็ปดๆŠค็š„็‰ˆๆœฌไปฅ Milestone ไธบๅ‡†ใ€‚ๅช่ฆๆ˜ฏๅผ€็€็š„็‰ˆๆœฌ๏ผŒ้ƒฝไผš่ฟ›่กŒไฟฎๅคใ€‚ -### ๅ‘ๅธƒ็ญ–็•ฅ +### ๅ‘ๅธƒ็ญ–็•ฅ ๆฏไธชๅคง็‰ˆๆœฌ้ƒฝๆœ‰ไธ€ไธชๅ‘ๅธƒ็ป็†๏ผˆPM๏ผ‰่ดŸ่ดฃ็ฎก็†ใ€‚ไป–/ๅฅน็š„ๅทฅไฝœๅ†…ๅฎนๅŒ…ๆ‹ฌ๏ผš @@ -196,10 +197,10 @@ Egg ๅŸบไบŽ [semver]๏ผˆ่ฏญไน‰ๅŒ–็‰ˆๆœฌๅท๏ผ‰่ฟ›่กŒๅ‘ๅธƒใ€‚ } ``` -[semver]: https://semver.org/lang/zh-CN/ -[Release Proposal MR]: https://github.com/nodejs/node/pull/4181 -[Node CHANGELOG]: https://github.com/nodejs/node/blob/master/CHANGELOG.md -[1.x Milestone]: https://github.com/eggjs/egg/milestone/1 -[npm]: http://npmjs.com/ -[ๆˆ‘ๆ˜ฏๅฆ‚ไฝ•ๅ‘ๅธƒไธ€ไธช npm ๅŒ…็š„]: https://fengmk2.com/blog/2016/how-i-publish-a-npm-package -[่‹ฑ่ฏญๆ ‡้ข˜ๅคงๅฐๅ†™]: https://headlinecapitalization.com/ \ No newline at end of file +[semver]: https://semver.org/lang/zh-CN/ +[Release Proposal MR]: https://github.com/nodejs/node/pull/4181 +[Node CHANGELOG]: https://github.com/nodejs/node/blob/master/CHANGELOG.md +[1.x Milestone]: https://github.com/eggjs/egg/milestone/1 +[npm]: http://npmjs.com/ +[ๆˆ‘ๆ˜ฏๅฆ‚ไฝ•ๅ‘ๅธƒไธ€ไธช npm ๅŒ…็š„]: https://fengmk2.com/blog/2016/how-i-publish-a-npm-package +[่‹ฑ่ฏญๆ ‡้ข˜ๅคงๅฐๅ†™]: https://headlinecapitalization.com/ diff --git a/site/docs/community/faq.md b/site/docs/community/faq.md index 02ac70500d..874546b2af 100644 --- a/site/docs/community/faq.md +++ b/site/docs/community/faq.md @@ -27,10 +27,10 @@ Please make sure you don't make a mistake like the code below: ```js // config/config.default.js -exports.someKeys = 'abc'; +exports.someKeys = "abc"; module.exports = (appInfo) => { const config = {}; - config.keys = '123456'; + config.keys = "123456"; return config; }; ``` @@ -55,9 +55,9 @@ Firstly, put a start file in the root directory of your project: ```js // server.js -const egg = require('egg'); +const egg = require("egg"); -const workers = Number(process.argv[2] || require('os').cpus().length); +const workers = Number(process.argv[2] || require("os").cpus().length); egg.startCluster({ workers, baseDir: __dirname, diff --git a/site/docs/community/faq.zh-CN.md b/site/docs/community/faq.zh-CN.md index 199122f1af..ac5afb851d 100644 --- a/site/docs/community/faq.zh-CN.md +++ b/site/docs/community/faq.zh-CN.md @@ -29,10 +29,10 @@ PS๏ผš่ฏท็กฎไฟๆฒกๆœ‰ๅ†™ๅ‡บไปฅไธ‹ไปฃ็ ๏ผš ```js // config/config.default.js -exports.someKeys = 'abc'; +exports.someKeys = "abc"; module.exports = (appInfo) => { const config = {}; - config.keys = '123456'; + config.keys = "123456"; return config; }; ``` @@ -57,9 +57,9 @@ module.exports = (appInfo) => { ```js // server.js -const egg = require('egg'); +const egg = require("egg"); -const workers = Number(process.argv[2] || require('os').cpus().length); +const workers = Number(process.argv[2] || require("os").cpus().length); egg.startCluster({ workers, baseDir: __dirname, @@ -89,6 +89,6 @@ worker ่ฟ›็จ‹ๆฒกๆœ‰่‡ชๅŠจ้‡ๅฏ็š„ๆƒ…ๅฝข้€šๅธธๅ‘็”Ÿๅœจไฝฟ็”จ Jetbrains ๆ——ไธ‹ Jetbrains [Safe Write ๆ–‡ๆกฃ](https://www.jetbrains.com/help/webstorm/2016.3/system-settings.html) ไธญๆœ‰ๆๅˆฐ๏ผˆ็ฟป่ฏ‘ๅฆ‚ไธ‹๏ผ‰๏ผš ->โ€œๅฆ‚ๆžœๆญคๅค้€‰ๆก†ๆ‰“้’ฉ๏ผŒๅ˜ๆ›ด็š„ๆ–‡ไปถๅฐ†้ฆ–ๅ…ˆ่ขซๅญ˜ๅ‚จๅœจไธ€ไธชไธดๆ—ถๆ–‡ไปถไธญใ€‚ๅฆ‚ๆžœๆ–‡ไปถไฟๅญ˜ๆˆๅŠŸ๏ผŒๅˆ™ไธดๆ—ถๆ–‡ไปถไผšๆ›ฟๆขๅŽŸๆ–‡ไปถ๏ผˆไปŽๆŠ€ๆœฏไธŠ่ฎฒ๏ผŒๅŽŸๆ–‡ไปถ่ขซๅˆ ้™ค๏ผŒไธดๆ—ถๆ–‡ไปถ่ขซ้‡ๅ‘ฝๅ๏ผ‰ใ€‚โ€ +> โ€œๅฆ‚ๆžœๆญคๅค้€‰ๆก†ๆ‰“้’ฉ๏ผŒๅ˜ๆ›ด็š„ๆ–‡ไปถๅฐ†้ฆ–ๅ…ˆ่ขซๅญ˜ๅ‚จๅœจไธ€ไธชไธดๆ—ถๆ–‡ไปถไธญใ€‚ๅฆ‚ๆžœๆ–‡ไปถไฟๅญ˜ๆˆๅŠŸ๏ผŒๅˆ™ไธดๆ—ถๆ–‡ไปถไผšๆ›ฟๆขๅŽŸๆ–‡ไปถ๏ผˆไปŽๆŠ€ๆœฏไธŠ่ฎฒ๏ผŒๅŽŸๆ–‡ไปถ่ขซๅˆ ้™ค๏ผŒไธดๆ—ถๆ–‡ไปถ่ขซ้‡ๅ‘ฝๅ๏ผ‰ใ€‚โ€ ็”ฑไบŽไฝฟ็”จไบ†้‡ๅ‘ฝๅ๏ผŒๆ–‡ไปถ็›‘ๅฌๅคฑๆ•ˆใ€‚่งฃๅ†ณๆ–นๆณ•ๆ˜ฏๅ…ณ้—ญ Safe Write ้€‰้กนใ€‚๏ผˆSettings | Appearance & Behavior | System Settings | Use "safe write"๏ผŒ่ทฏๅพ„ๅฏ่ƒฝๅ› ็‰ˆๆœฌไธๅŒๆœ‰ๆ‰€ๅทฎๅผ‚๏ผ‰ diff --git a/site/docs/community/style-guide.md b/site/docs/community/style-guide.md index 6bba90db3d..4e1aa160bd 100644 --- a/site/docs/community/style-guide.md +++ b/site/docs/community/style-guide.md @@ -12,7 +12,7 @@ Old Style: module.exports = (app) => { class UserService extends app.Service { async list() { - return await this.ctx.curl('https://eggjs.org'); + return await this.ctx.curl("https://eggjs.org"); } } return UserService; @@ -22,10 +22,10 @@ module.exports = (app) => { change to: ```js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { async list() { - return await this.ctx.curl('https://eggjs.org'); + return await this.ctx.curl("https://eggjs.org"); } } module.exports = UserService; @@ -34,7 +34,7 @@ module.exports = UserService; Additionally, the `framework developer` needs to change the syntax as follows, otherwise the `application developer` will have problems customizing base classes such as Service: ```js -const egg = require('egg'); +const egg = require("egg"); module.exports = Object.assign(egg, { Application: class MyApplication extends egg.Application { @@ -52,8 +52,8 @@ module.exports = Object.assign(egg, { ```js // app/extend/application.js -const CACHE = Symbol('Application#cache'); -const CacheManager = require('../../lib/cache_manager'); +const CACHE = Symbol("Application#cache"); +const CacheManager = require("../../lib/cache_manager"); module.exports = { get cache() { diff --git a/site/docs/community/style-guide.zh-CN.md b/site/docs/community/style-guide.zh-CN.md index ba168aa0c9..df64589491 100644 --- a/site/docs/community/style-guide.zh-CN.md +++ b/site/docs/community/style-guide.zh-CN.md @@ -12,7 +12,7 @@ title: ไปฃ็ ้ฃŽๆ ผๆŒ‡ๅ— module.exports = (app) => { class UserService extends app.Service { async list() { - return await this.ctx.curl('https://eggjs.org'); + return await this.ctx.curl("https://eggjs.org"); } } return UserService; @@ -22,10 +22,10 @@ module.exports = (app) => { ไฟฎๆ”นไธบ๏ผš ```js -const Service = require('egg').Service; +const Service = require("egg").Service; class UserService extends Service { async list() { - return await this.ctx.curl('https://eggjs.org'); + return await this.ctx.curl("https://eggjs.org"); } } module.exports = UserService; @@ -34,7 +34,7 @@ module.exports = UserService; ๅŒๆ—ถ๏ผŒๆก†ๆžถๅผ€ๅ‘่€…้œ€่ฆๆ”นๅ˜ๅ†™ๆณ•ๅฆ‚ไธ‹๏ผŒๅฆๅˆ™ๅบ”็”จๅผ€ๅ‘่€…่‡ชๅฎšไน‰ Service ็ญ‰ๅŸบ็ฑปไผšๆœ‰้—ฎ้ข˜๏ผš ```js -const egg = require('egg'); +const egg = require("egg"); module.exports = Object.assign(egg, { Application: class MyApplication extends egg.Application { @@ -52,8 +52,8 @@ module.exports = Object.assign(egg, { ```js // app/extend/application.js -const CACHE = Symbol('Application#cache'); -const CacheManager = require('../../lib/cache_manager'); +const CACHE = Symbol("Application#cache"); +const CacheManager = require("../../lib/cache_manager"); module.exports = { get cache() { diff --git a/site/docs/core/cluster-and-ipc.md b/site/docs/core/cluster-and-ipc.md index 0558ab611f..fd38052e81 100644 --- a/site/docs/core/cluster-and-ipc.md +++ b/site/docs/core/cluster-and-ipc.md @@ -28,9 +28,9 @@ of which: - usually the number of Worker processes depends on the CPU core number, only in this way can we take full advantage of multi-core resources. ```js -const cluster = require('cluster'); -const http = require('http'); -const numCPUs = require('os').cpus().length; +const cluster = require("cluster"); +const http = require("http"); +const numCPUs = require("os").cpus().length; if (cluster.isMaster) { // Fork workers. @@ -38,8 +38,8 @@ if (cluster.isMaster) { cluster.fork(); } - cluster.on('exit', function (worker, code, signal) { - console.log('worker ' + worker.process.pid + ' died'); + cluster.on("exit", function (worker, code, signal) { + console.log("worker " + worker.process.pid + " died"); }); } else { // Workers can share any TCP connection @@ -47,7 +47,7 @@ if (cluster.isMaster) { http .createServer(function (req, res) { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }) .listen(8000); } @@ -179,7 +179,7 @@ module.exports = agent => { ```js // app.js module.exports = (app) => { - app.messenger.on('xxx_action', (data) => { + app.messenger.on("xxx_action", (data) => { // ... }); }; @@ -224,17 +224,17 @@ Worker runs business codes, which are more complicated than those of Agent and M Although every Worker process runs individually, it's necessary for them to communicate with each other which is called inter-process communication(IPC). Below is an example code provided by Node.js officially. ```js -'use strict'; -const cluster = require('cluster'); +"use strict"; +const cluster = require("cluster"); if (cluster.isMaster) { const worker = cluster.fork(); - worker.send('hi there'); - worker.on('message', (msg) => { + worker.send("hi there"); + worker.on("message", (msg) => { console.log(`msg: ${msg} from worker#${worker.id}`); }); } else if (cluster.isWorker) { - process.on('message', (msg) => { + process.on("message", (msg) => { process.send(msg); }); } @@ -290,9 +290,9 @@ To simplify the invocation, we have encapsulated a messenger object and attached // app.js module.exports = (app) => { // Note, only after egg-ready event occurs can the message be sent - app.messenger.once('egg-ready', () => { - app.messenger.sendToAgent('agent-event', { foo: 'bar' }); - app.messenger.sendToApp('app-event', { foo: 'bar' }); + app.messenger.once("egg-ready", () => { + app.messenger.sendToAgent("agent-event", { foo: "bar" }); + app.messenger.sendToApp("app-event", { foo: "bar" }); }); }; ``` @@ -348,14 +348,14 @@ class SourceService extends Service { async checkUpdate() { // check if remote data source has changed const updated = await mockCheck(); - this.ctx.logger.info('check update response %s', updated); + this.ctx.logger.info("check update response %s", updated); return updated; } async update() { // update memory cache from remote memoryCache = await mockFetch(); - this.ctx.logger.info('update memory cache from remote: %j', memoryCache); + this.ctx.logger.info("update memory cache from remote: %j", memoryCache); } } ``` @@ -365,13 +365,13 @@ Write the scheduled task to implement solution one: gets data changes from the r ```js // app/schedule/force_refresh.js exports.schedule = { - interval: '10m', - type: 'all', // run in all workers + interval: "10m", + type: "all", // run in all workers }; exports.task = async (ctx) => { await ctx.service.source.update(); - ctx.app.lastUpdateBy = 'force'; + ctx.app.lastUpdateBy = "force"; }; ``` @@ -380,8 +380,8 @@ Write a scheduled task again to implement check logics of solution two: make a w ```js // app/schedule/pull_refresh.js exports.schedule = { - interval: '10s', - type: 'worker', // only run in one worker + interval: "10s", + type: "worker", // only run in one worker }; exports.task = async (ctx) => { @@ -389,7 +389,7 @@ exports.task = async (ctx) => { if (!needRefresh) return; // notify all workers to update memory cache from `file` - ctx.app.messenger.sendToApp('refresh', 'pull'); + ctx.app.messenger.sendToApp("refresh", "pull"); }; ``` @@ -398,8 +398,8 @@ Listen on the `pullRefresh` event in the customized start-up file and update dat ```js // app.js module.exports = (app) => { - app.messenger.on('refresh', (by) => { - app.logger.info('start update by %s', by); + app.messenger.on("refresh", (by) => { + app.logger.info("start update by %s", by); // create an anonymous context to access service const ctx = app.createAnonymousContext(); ctx.runInBackground(async () => { @@ -415,12 +415,12 @@ Now let's consider how to implement solution three. We need a message-oriented m ```js // agent.js -const Subscriber = require('./lib/subscriber'); +const Subscriber = require("./lib/subscriber"); module.exports = (agent) => { const subscriber = new Subscriber(); // listen changed event, broadcast to all workers - subscriber.on('changed', () => agent.messenger.sendToApp('refresh', 'push')); + subscriber.on("changed", () => agent.messenger.sendToApp("refresh", "push")); }; ``` diff --git a/site/docs/core/cluster-and-ipc.zh-CN.md b/site/docs/core/cluster-and-ipc.zh-CN.md index 602aa23a19..00c2853d0f 100644 --- a/site/docs/core/cluster-and-ipc.zh-CN.md +++ b/site/docs/core/cluster-and-ipc.zh-CN.md @@ -28,9 +28,9 @@ Node.js ๅฎ˜ๆ–นๆไพ›็š„่งฃๅ†ณๆ–นๆกˆๆ˜ฏ [Cluster ๆจกๅ—](https://nodejs.org/api/c - Worker ่ฟ›็จ‹็š„ๆ•ฐ้‡ไธ€่ˆฌๆ นๆฎๆœๅŠกๅ™จ็š„ CPU ๆ ธๆ•ฐๆฅๅฎš๏ผŒ่ฟ™ๆ ทๅฏไปฅๅฎŒ็พŽๅˆฉ็”จๅคšๆ ธ่ต„ๆบใ€‚ ```js -const cluster = require('cluster'); -const http = require('http'); -const numCPUs = require('os').cpus().length; +const cluster = require("cluster"); +const http = require("http"); +const numCPUs = require("os").cpus().length; if (cluster.isMaster) { // Fork workers. @@ -38,7 +38,7 @@ if (cluster.isMaster) { cluster.fork(); } - cluster.on('exit', (worker, code, signal) => { + cluster.on("exit", (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { @@ -47,11 +47,12 @@ if (cluster.isMaster) { http .createServer((req, res) => { res.writeHead(200); - res.end('hello world\n'); + res.end("hello world\n"); }) .listen(8000); } ``` + ## ๆก†ๆžถ็š„ๅคš่ฟ›็จ‹ๆจกๅž‹ ไธŠ้ข็š„็คบไพ‹ๆ˜ฏๅฆๅพˆ็ฎ€ๅ•ๅ‘ข๏ผŸไฝ†ไฝœไธบไผไธš็บงๅบ”็”จ่งฃๅ†ณๆ–นๆกˆ๏ผŒๆˆ‘ไปฌ้œ€่ฆ่€ƒ่™‘็š„้—ฎ้ข˜่ฟ˜ๆœ‰ๅพˆๅคšใ€‚ @@ -177,23 +178,24 @@ module.exports = agent => { ```js // app.js -module.exports = app => { - app.messenger.on('xxx_action', data => { +module.exports = (app) => { + app.messenger.on("xxx_action", (data) => { // ... }); }; ``` ่ฟ™ไธชไพ‹ๅญไธญ๏ผŒ`agent.js` ็š„ไปฃ็ ๅฐ†ๅœจ Agent ่ฟ›็จ‹ไธŠๆ‰ง่กŒ๏ผŒ`app.js` ็š„ไปฃ็ ๅˆ™ๅœจ Worker ่ฟ›็จ‹ไธŠๆ‰ง่กŒใ€‚ๅฎƒไปฌ้€š่ฟ‡ๆก†ๆžถๅฐ่ฃ…็š„ `messenger` ๅฏน่ฑก่ฟ›่กŒ่ฟ›็จ‹้—ด้€šไฟก๏ผˆIPC๏ผ‰ใ€‚ๅŽ็ปญ็ซ ่Š‚ไผšๅฏนๆก†ๆžถ็š„ IPC ่ฟ›่กŒ่ฏฆ็ป†่ฎฒ่งฃใ€‚ + ### Master VS Agent VS Worker ๅบ”็”จๅฏๅŠจๆ—ถ๏ผŒไผšๅŒๆ—ถๅˆ›ๅปบไธ‰็ฑป่ฟ›็จ‹ใ€‚ไธ‹่กจๆฆ‚่ฟฐไบ†ๆฏ็ง่ฟ›็จ‹็š„ๆ•ฐ้‡ใ€ไฝœ็”จใ€็จณๅฎšๆ€งไปฅๅŠๆ˜ฏๅฆ่ฟ่กŒไธšๅŠกไปฃ็ ๏ผš -| ็ฑปๅž‹ | ่ฟ›็จ‹ๆ•ฐ้‡ | ไฝœ็”จ | ็จณๅฎšๆ€ง | ๆ˜ฏๅฆ่ฟ่กŒไธšๅŠกไปฃ็  | -| ------ | ------------------ | -------------------------- | ------ | ---------------- | -| Master | 1 | ่ฟ›็จ‹็ฎก็†๏ผŒ่ฟ›็จ‹้—ดๆถˆๆฏ่ฝฌๅ‘ | ้žๅธธ้ซ˜ | ๅฆ | +| ็ฑปๅž‹ | ่ฟ›็จ‹ๆ•ฐ้‡ | ไฝœ็”จ | ็จณๅฎšๆ€ง | ๆ˜ฏๅฆ่ฟ่กŒไธšๅŠกไปฃ็  | +| ------ | ------------------- | ---------------------------- | ------ | ---------------- | +| Master | 1 | ่ฟ›็จ‹็ฎก็†๏ผŒ่ฟ›็จ‹้—ดๆถˆๆฏ่ฝฌๅ‘ | ้žๅธธ้ซ˜ | ๅฆ | | Agent | 1 | ๅŽๅฐ่ฟ่กŒๅทฅไฝœ๏ผˆ้•ฟ่ฟžๆŽฅๅฎขๆˆท็ซฏ๏ผ‰ | ้ซ˜ | ๅฐ‘้‡ | -| Worker | ้€šๅธธ่ฎพ็ฝฎไธบ CPU ๆ ธๆ•ฐ | ๆ‰ง่กŒไธšๅŠกไปฃ็  | ไธ€่ˆฌ | ๆ˜ฏ | +| Worker | ้€šๅธธ่ฎพ็ฝฎไธบ CPU ๆ ธๆ•ฐ | ๆ‰ง่กŒไธšๅŠกไปฃ็  | ไธ€่ˆฌ | ๆ˜ฏ | #### Master @@ -222,17 +224,17 @@ Worker ่ฟ›็จ‹ๅ› ่ฟ่กŒๅคๆ‚็š„ไธšๅŠกไปฃ็ ๏ผŒ็จณๅฎšๆ€ง็›ธๅฏน่พƒไฝŽใ€‚ไธ€ๆ—ฆ Wor ๅฐฝ็ฎก Worker ่ฟ›็จ‹็›ธๅฏน็‹ฌ็ซ‹๏ผŒๅฎƒไปฌ้—ดไป้œ€้€š่ฎฏใ€‚ไปฅไธ‹ๆ˜ฏ Node.js ๅฎ˜ๆ–น็š„ IPC ็คบไพ‹ไปฃ็ ๏ผš ```js -'use strict'; -const cluster = require('cluster'); +"use strict"; +const cluster = require("cluster"); if (cluster.isMaster) { const worker = cluster.fork(); - worker.send('hi there'); - worker.on('message', (msg) => { + worker.send("hi there"); + worker.on("message", (msg) => { console.log(`msg: ${msg} from worker#${worker.id}`); }); } else if (cluster.isWorker) { - process.on('message', (msg) => { + process.on("message", (msg) => { process.send(msg); }); } @@ -273,12 +275,12 @@ if (cluster.isMaster) { - `app.messenger.broadcast(action, data)`: ๅ‘ๆ‰€ๆœ‰็š„ agent / app ่ฟ›็จ‹ๅ‘้€ๆถˆๆฏ๏ผˆๅŒ…ๆ‹ฌ่‡ชๅทฑ๏ผ‰ใ€‚ - `app.messenger.sendToApp(action, data)`: ๅ‘้€่‡ณๆ‰€ๆœ‰็š„ app ่ฟ›็จ‹ใ€‚ - - app ไธŠ่ฐƒ็”จๅณๅ‘้€่‡ณ่‡ชๅทฑไธŽๅ…ถไป– app + - app ไธŠ่ฐƒ็”จๅณๅ‘้€่‡ณ่‡ชๅทฑไธŽๅ…ถไป– app - agent ไธŠ่ฐƒ็”จๅˆ™ๅ‘้€่‡ณๆ‰€ๆœ‰ app ่ฟ›็จ‹ใ€‚ - `app.messenger.sendToAgent(action, data)`: ๅ‘้€ๆถˆๆฏ่‡ณ agent ่ฟ›็จ‹ใ€‚ - app ไธŠ่ฐƒ็”จๅณๅ‘้€่‡ณ agent - agent ไธŠ่ฐƒ็”จๅณๅ‘้€่‡ณ่‡ชๅทฑใ€‚ -- `agent.messenger.sendRandom(action, data)`: +- `agent.messenger.sendRandom(action, data)`: - app ไธŠๆ— ๆญคๆ–นๆณ•๏ผˆEgg ๅฎž็ŽฐไธŽ sentToAgent ็ฑปไผผ๏ผ‰ - agent ้šๆœบๅ‘ๆŸ app ่ฟ›็จ‹ๅ‘้€ๆถˆๆฏ๏ผˆ็”ฑ master ๆŽงๅˆถ๏ผ‰ใ€‚ - `app.messenger.sendTo(pid, action, data)`: ๅ‘ๆŒ‡ๅฎš่ฟ›็จ‹ๅ‘้€ๆถˆๆฏใ€‚ @@ -287,9 +289,9 @@ if (cluster.isMaster) { // app.js module.exports = (app) => { // ๅชๆœ‰ๅœจ egg-ready ไบ‹ไปถๅŽๆ‰่ƒฝๅ‘้€ๆถˆๆฏ - app.messenger.once('egg-ready', () => { - app.messenger.sendToAgent('agent-event', { foo: 'bar' }); - app.messenger.sendToApp('app-event', { foo: 'bar' }); + app.messenger.once("egg-ready", () => { + app.messenger.sendToAgent("agent-event", { foo: "bar" }); + app.messenger.sendToApp("app-event", { foo: "bar" }); }); }; ``` @@ -348,14 +350,14 @@ class SourceService extends Service { async checkUpdate() { // check if remote data source has changed const updated = await mockCheck(); - this.ctx.logger.info('check update response %s', updated); + this.ctx.logger.info("check update response %s", updated); return updated; } async update() { // update memory cache from remote memoryCache = await mockFetch(); - this.ctx.logger.info('update memory cache from remote: %j', memoryCache); + this.ctx.logger.info("update memory cache from remote: %j", memoryCache); } } ``` @@ -365,13 +367,13 @@ class SourceService extends Service { ```js // app/schedule/force_refresh.js exports.schedule = { - interval: '10m', - type: 'all' // ๅœจๆ‰€ๆœ‰็š„ workers ไธญ่ฟ่กŒ + interval: "10m", + type: "all", // ๅœจๆ‰€ๆœ‰็š„ workers ไธญ่ฟ่กŒ }; exports.task = async (ctx) => { await ctx.service.source.update(); - ctx.app.lastUpdateBy = 'force'; + ctx.app.lastUpdateBy = "force"; }; ``` @@ -380,8 +382,8 @@ exports.task = async (ctx) => { ```js // app/schedule/pull_refresh.js exports.schedule = { - interval: '10s', - type: 'worker' // ๅชๅœจไธ€ไธช worker ไธญ่ฟ่กŒ + interval: "10s", + type: "worker", // ๅชๅœจไธ€ไธช worker ไธญ่ฟ่กŒ }; exports.task = async (ctx) => { @@ -389,7 +391,7 @@ exports.task = async (ctx) => { if (!needRefresh) return; // notify all workers to update memory cache from `file` - ctx.app.messenger.sendToApp('refresh', 'pull'); + ctx.app.messenger.sendToApp("refresh", "pull"); }; ``` @@ -398,8 +400,8 @@ exports.task = async (ctx) => { ```js // app.js module.exports = (app) => { - app.messenger.on('refresh', (by) => { - app.logger.info('start update by %s', by); + app.messenger.on("refresh", (by) => { + app.logger.info("start update by %s", by); // ๅˆ›ๅปบไธ€ไธชๅŒฟๅ context ๆฅ่ฎฟ้—ฎ service const ctx = app.createAnonymousContext(); ctx.runInBackground(async () => { @@ -415,12 +417,12 @@ module.exports = (app) => { ```js // agent.js -const Subscriber = require('./lib/subscriber'); +const Subscriber = require("./lib/subscriber"); module.exports = (agent) => { const subscriber = new Subscriber(); // ็›‘ๅฌๅ˜ๆ›ดไบ‹ไปถ๏ผŒๅนฟๆ’ญๅˆฐๆ‰€ๆœ‰ workers - subscriber.on('changed', () => agent.messenger.sendToApp('refresh', 'push')); + subscriber.on("changed", () => agent.messenger.sendToApp("refresh", "push")); }; ``` diff --git a/site/docs/core/cookie-and-session.md b/site/docs/core/cookie-and-session.md index 13bcc3a82e..40feff52ae 100644 --- a/site/docs/core/cookie-and-session.md +++ b/site/docs/core/cookie-and-session.md @@ -20,14 +20,14 @@ By using `ctx.cookies`, we can easily and safely read/set cookies in controller. class HomeController extends Controller { async add() { const ctx = this.ctx; - let count = ctx.cookies.get('count'); + let count = ctx.cookies.get("count"); count = count ? Number(count) : 0; - ctx.cookies.set('count', ++count); + ctx.cookies.set("count", ++count); ctx.body = count; } async remove() { const ctx = this.ctx; - ctx.cookies.set('count', null); + ctx.cookies.set("count", null); ctx.status = 204; } } @@ -95,7 +95,7 @@ the corresponding options also need to be used in `get` method. If you want to get the cookie set by frontend or other system, you need to specify the parameter `signed` as `false`, avoid varify the cookie and not getting the vlaue. ```js -ctx.cookies.get('frontend-cookie', { +ctx.cookies.get("frontend-cookie", { signed: false, }); ``` @@ -107,7 +107,7 @@ In `config/config.default.js`: ```js module.exports = { - keys: 'key1,key2', + keys: "key1,key2", }; ``` @@ -164,7 +164,7 @@ What you need to pay special attention to is that you need to avoid the followin ```js // โŒ Wrong way ctx.session._visited = 1; // --> property will lost -ctx.session.isNew = 'HeHe'; // --> session keyword, should not write it +ctx.session.isNew = "HeHe"; // --> session keyword, should not write it // โœ”๏ธ Right way ctx.session.visited = 1; // --> Everything is all right @@ -178,7 +178,7 @@ The default configuration of Session is: ```js exports.session = { - key: 'EGG_SESS', + key: "EGG_SESS", maxAge: 24 * 3600 * 1000, // 1 day httpOnly: true, encrypt: true, @@ -227,11 +227,11 @@ To apply it, import [egg-redis] and [egg-session-redis] plugin in your applicati // plugin.js exports.redis = { enable: true, - package: 'egg-redis', + package: "egg-redis", }; exports.sessionRedis = { enable: true, - package: 'egg-session-redis', + package: "egg-session-redis", }; ``` @@ -253,7 +253,7 @@ If it's selected, Session of this logged in user can live longer. This kind of per-user session expiration time can be set through `ctx.session.maxAge`: ```js -const ms = require('ms'); +const ms = require("ms"); class UserController extends Controller { async login() { const ctx = this.ctx; @@ -263,7 +263,7 @@ class UserController extends Controller { // set Session ctx.session.user = user; // if user selected `Remember Me`, set expiration time to 30 days - if (rememberMe) ctx.session.maxAge = ms('30d'); + if (rememberMe) ctx.session.maxAge = ms("30d"); } } ``` diff --git a/site/docs/core/cookie-and-session.zh-CN.md b/site/docs/core/cookie-and-session.zh-CN.md index 6ed1278a47..9692f5750e 100644 --- a/site/docs/core/cookie-and-session.zh-CN.md +++ b/site/docs/core/cookie-and-session.zh-CN.md @@ -13,14 +13,14 @@ HTTP ่ฏทๆฑ‚้ƒฝๆ˜ฏๆ— ็Šถๆ€็š„๏ผŒไฝ†ๆ˜ฏๆˆ‘ไปฌ็š„ Web ๅบ”็”จ้€šๅธธ้ƒฝ้œ€่ฆ็Ÿฅ้“ class HomeController extends Controller { async add() { const ctx = this.ctx; - let count = ctx.cookies.get('count'); + let count = ctx.cookies.get("count"); count = count ? Number(count) : 0; - ctx.cookies.set('count', ++count); + ctx.cookies.set("count", ++count); ctx.body = count; } async remove() { const ctx = this.ctx; - ctx.cookies.set('count', null); + ctx.cookies.set("count", null); ctx.status = 204; } } @@ -52,7 +52,7 @@ class HomeController extends Controller { ```js ctx.cookies.set(key, value, { httpOnly: false, - signed: false + signed: false, }); ``` @@ -61,7 +61,7 @@ ctx.cookies.set(key, value, { ```js ctx.cookies.set(key, value, { httpOnly: true, // ้ป˜่ฎคๅฐฑๆ˜ฏ true - encrypt: true // ๅŠ ๅฏ†ไผ ่พ“ + encrypt: true, // ๅŠ ๅฏ†ไผ ่พ“ }); ``` @@ -80,8 +80,8 @@ ctx.cookies.set(key, value, { ๅฆ‚ๆžœ่ฆ่Žทๅ–ๅ‰็ซฏๆˆ–่€…ๅ…ถไป–็ณป็ปŸ่ฎพ็ฝฎ็š„ cookie๏ผŒ้œ€่ฆๆŒ‡ๅฎšๅ‚ๆ•ฐ `signed` ไธบ `false`๏ผŒ้ฟๅ…้ชŒ็ญพๅฏผ่‡ด่Žทๅ–ไธๅˆฐ cookie ็š„ๅ€ผใ€‚ ```js -ctx.cookies.get('frontend-cookie', { - signed: false +ctx.cookies.get("frontend-cookie", { + signed: false, }); ``` @@ -91,7 +91,7 @@ ctx.cookies.get('frontend-cookie', { ```js module.exports = { - keys: 'key1,key2' + keys: "key1,key2", }; ``` @@ -101,6 +101,7 @@ keys ้…็ฝฎๆˆไธ€ไธชๅญ—็ฌฆไธฒ๏ผŒๅฏไปฅๆŒ‰็…ง้€—ๅทๅˆ†้š”้…็ฝฎๅคšไธช keyใ€‚Cooki - ่งฃๅฏ†ๅ’Œ้ชŒ็ญพๆ—ถไผš้ๅކ keys ่ฟ›่กŒ่งฃๅฏ†ใ€‚ ๅฆ‚ๆžœๆˆ‘ไปฌๆƒณ่ฆๆ›ดๆ–ฐ Cookie ็š„็ง˜้’ฅ๏ผŒไฝ†ๆ˜ฏๅˆไธๅธŒๆœ›ไน‹ๅ‰่ฎพ็ฝฎๅˆฐ็”จๆˆทๆต่งˆๅ™จไธŠ็š„ Cookie ๅคฑๆ•ˆ๏ผŒๅฏไปฅๅฐ†ๆ–ฐ็š„็ง˜้’ฅ้…็ฝฎๅˆฐ keys ๆœ€ๅ‰้ข๏ผŒ็ญ‰่ฟ‡ไธ€ๆฎตๆ—ถ้—ดไน‹ๅŽๅ†ๅˆ ้™คไธ้œ€่ฆ็š„็ง˜้’ฅๅณๅฏใ€‚ + ## Session Cookie ้€šๅธธ็”จไฝœ Web ๅบ”็”จไธญๆ ‡่ฏ†่ฏทๆฑ‚ๆ–น่บซไปฝ็š„ๅŠŸ่ƒฝ๏ผŒๅŸบไบŽๆญค๏ผŒWeb ๅบ”็”จๅฐ่ฃ…ไบ† Session ๆฆ‚ๅฟต๏ผŒไธ“็”จไบŽ็”จๆˆท่บซไปฝ่ฏ†ๅˆซใ€‚ @@ -138,7 +139,7 @@ ctx.session = null; ```js // โŒ ้”™่ฏฏ็š„็”จๆณ• ctx.session._visited = 1; // ่ฏฅๅญ—ๆฎตไผšๅœจไธ‹ไธ€ๆฌก่ฏทๆฑ‚ๆ—ถไธขๅคฑ -ctx.session.isNew = 'HeHe'; // ไธบๅ†…้ƒจๅ…ณ้”ฎๅญ—๏ผŒไธๅบ”ๆ›ดๆ”น +ctx.session.isNew = "HeHe"; // ไธบๅ†…้ƒจๅ…ณ้”ฎๅญ—๏ผŒไธๅบ”ๆ›ดๆ”น // โœ”๏ธ ๆญฃ็กฎ็š„็”จๆณ• ctx.session.visited = 1; // ๆ— ้—ฎ้ข˜ @@ -148,7 +149,7 @@ Session ้ป˜่ฎคๅŸบไบŽ Cookie ๅฎž็Žฐ๏ผŒๅ†…ๅฎนๅŠ ๅฏ†ๅŽ็›ดๆŽฅๅญ˜ๅ‚จๅœจ Cookie ็š„ ```js exports.session = { - key: 'EGG_SESS', + key: "EGG_SESS", maxAge: 24 * 3600 * 1000, // 1 ๅคฉ httpOnly: true, encrypt: true, @@ -165,7 +166,7 @@ Session ้ป˜่ฎคๅญ˜ๆ”พๅœจ Cookie ไธญๅฏ่ƒฝๅ‡บ็Žฐ้—ฎ้ข˜๏ผšๆต่งˆๅ™จๆœ‰ๆœ€ๅคง Cookie ```js // app.js -module.exports = app => { +module.exports = (app) => { app.sessionStore = { async get(key) { // ่ฟ”ๅ›žๅ€ผ @@ -186,11 +187,11 @@ module.exports = app => { // plugin.js exports.redis = { enable: true, - package: 'egg-redis', + package: "egg-redis", }; exports.sessionRedis = { enable: true, - package: 'egg-session-redis', + package: "egg-session-redis", }; ``` @@ -203,7 +204,7 @@ exports.sessionRedis = { Session ้…็ฝฎไธญ็š„ `maxAge` ๅฏๅ…จๅฑ€่ฎพ็ฝฎๆœ‰ๆ•ˆๆœŸใ€‚**่ฎฐไฝๆˆ‘** ๅŠŸ่ƒฝไธญ๏ผŒๅฏ้’ˆๅฏน็‰นๅฎš็”จๆˆท็š„ Session ่ฎพ็ฝฎไธๅŒๆœ‰ๆ•ˆๆ—ถ้—ด๏ผŒ้€š่ฟ‡ `ctx.session.maxAge=` ๅฎž็Žฐ๏ผš ```js -const ms = require('ms'); +const ms = require("ms"); class UserController extends Controller { async login() { const ctx = this.ctx; @@ -213,7 +214,7 @@ class UserController extends Controller { // ่ฎพ็ฝฎ Session ctx.session.user = user; // ๅ‹พ้€‰ `่ฎฐไฝๆˆ‘` ๆ—ถ๏ผŒ่ฎพ็ฝฎ 30 ๅคฉ่ฟ‡ๆœŸๆ—ถ้—ด - if (rememberMe) ctx.session.maxAge = ms('30d'); + if (rememberMe) ctx.session.maxAge = ms("30d"); } } ``` diff --git a/site/docs/core/deployment.md b/site/docs/core/deployment.md index a9ff392b5d..93c7d9f169 100644 --- a/site/docs/core/deployment.md +++ b/site/docs/core/deployment.md @@ -88,7 +88,7 @@ Arguments of dispatch can be configured in `config.{env}.js`. exports.cluster = { listen: { port: 7001, - hostname: '127.0.0.1', // It is not recommended to set the hostname to '0.0.0.0', which will allow connections from external networks and sources, please use it if you know the risk. + hostname: "127.0.0.1", // It is not recommended to set the hostname to '0.0.0.0', which will allow connections from external networks and sources, please use it if you know the risk. // path: '/var/run/egg.sock', }, }; diff --git a/site/docs/core/deployment.zh-CN.md b/site/docs/core/deployment.zh-CN.md index a5c7534acb..49d2e50734 100644 --- a/site/docs/core/deployment.zh-CN.md +++ b/site/docs/core/deployment.zh-CN.md @@ -89,7 +89,7 @@ $ egg-scripts start --port=7001 --daemon --title=egg-server-showcase exports.cluster = { listen: { port: 7001, - hostname: '127.0.0.1', // ไธๅปบ่ฎฎ่ฎพ็ฝฎไธบ '0.0.0.0'๏ผŒๅฏ่ƒฝๅฏผ่‡ดๅค–้ƒจ่ฟžๆŽฅ้ฃŽ้™ฉ๏ผŒ่ฏทไบ†่งฃๅŽไฝฟ็”จ + hostname: "127.0.0.1", // ไธๅปบ่ฎฎ่ฎพ็ฝฎไธบ '0.0.0.0'๏ผŒๅฏ่ƒฝๅฏผ่‡ดๅค–้ƒจ่ฟžๆŽฅ้ฃŽ้™ฉ๏ผŒ่ฏทไบ†่งฃๅŽไฝฟ็”จ // path: '/var/run/egg.sock', }, }; @@ -110,6 +110,7 @@ $ egg-scripts stop [--title=egg-server] - `--title=egg-server`๏ผšๆ€ๆญปๆŒ‡ๅฎš Egg ๅบ”็”จ๏ผŒๆœช่ฎพ็ฝฎๅˆ™็ปˆๆญขๆ‰€ๆœ‰ Egg ๅบ”็”จใ€‚ ไนŸๅฏ้€š่ฟ‡ `ps -eo "pid,command" | grep -- "--title=egg-server"` ๆŸฅๆ‰พ master ่ฟ›็จ‹๏ผŒๅนถ `kill` ๆމ๏ผŒไธ้œ€ `kill -9`ใ€‚ + ## ็›‘ๆŽง ๆˆ‘ไปฌ่ฟ˜้œ€่ฆๅฏนๆœๅŠก่ฟ›่กŒๆ€ง่ƒฝ็›‘ๆŽงใ€ๅ†…ๅญ˜ๆณ„้œฒๅˆ†ๆžใ€ๆ•…้šœๆŽ’้™ค็ญ‰ใ€‚ @@ -158,7 +159,7 @@ $ npm i egg-alinode --save // config/plugin.js exports.alinode = { enable: true, - package: 'egg-alinode', + package: "egg-alinode", }; ``` @@ -168,8 +169,8 @@ exports.alinode = { // config/config.default.js exports.alinode = { // ไปŽ `Node.js ๆ€ง่ƒฝๅนณๅฐ` ่Žทๅ–ๅฏนๅบ”็š„ๆŽฅๅ…ฅๅ‚ๆ•ฐ - appid: '', - secret: '', + appid: "", + secret: "", }; ``` diff --git a/site/docs/core/development.md b/site/docs/core/development.md index 94c21efc6c..3f3be3481d 100644 --- a/site/docs/core/development.md +++ b/site/docs/core/development.md @@ -207,13 +207,13 @@ There's a built-in [Log](./logger.md) in the egg, so you may use logger.debug() ```js // controller -this.logger.debug('current user: %j', this.user); +this.logger.debug("current user: %j", this.user); // service -this.ctx.logger.debug('debug info from service'); +this.ctx.logger.debug("debug info from service"); // app/init.js -app.logger.debug('app init'); +app.logger.debug("app init"); ``` Levels of logs can be configured via `config.logger.level` for printing into file, and `config.logger.consoleLevel` for printing into console. diff --git a/site/docs/core/development.zh-CN.md b/site/docs/core/development.zh-CN.md index 4b53e175ca..7ed06a2a10 100644 --- a/site/docs/core/development.zh-CN.md +++ b/site/docs/core/development.zh-CN.md @@ -69,6 +69,7 @@ $ npm i egg-bin --save-dev } } ``` + ## ๅ•ๅ…ƒๆต‹่ฏ• ่ฟ™้‡Œไธป่ฆ่ฎฒ่งฃๅทฅๅ…ท้ƒจๅˆ†็š„ไฝฟ็”จ๏ผŒๆ›ดๅคšๅ…ณไบŽๅ•ๅ…ƒๆต‹่ฏ•็š„ๅ†…ๅฎน่ฏทๅ‚่€ƒ[่ฟ™้‡Œ](./unittest.md)ใ€‚ @@ -141,7 +142,6 @@ $ # ๆ”ฏๆŒ mocha ๅ‚ๆ•ฐ๏ผŒๅฆ‚ grepใ€require ็ญ‰ $ npm test -- -t 30000 --grep="should GET" ``` - ## ไปฃ็ ่ฆ†็›–็އ egg-bin ๅทฒๅ†…็ฝฎ [nyc](https://github.com/istanbuljs/nyc) ๆ”ฏๆŒๅ•ๅ…ƒๆต‹่ฏ•็”Ÿๆˆไปฃ็ ่ฆ†็›–็އๆŠฅๅ‘Šใ€‚ @@ -196,6 +196,7 @@ $ COV_EXCLUDES=app/plugins/c* npm run cov $ # ๆˆ–่€…ไฝฟ็”จไผ ๅ‚ๆ–นๅผ $ npm run cov -- --x=app/plugins/c* ``` + ## ่ฐƒ่ฏ• ### ๆ—ฅๅฟ—่พ“ๅ‡บ @@ -206,13 +207,13 @@ $ npm run cov -- --x=app/plugins/c* ```js // controller -this.logger.debug('current user: %j', this.user); +this.logger.debug("current user: %j", this.user); // service -this.ctx.logger.debug('debug info from service'); +this.ctx.logger.debug("debug info from service"); // app/init.js -app.logger.debug('app init'); +app.logger.debug("app init"); ``` ้€š่ฟ‡ `config.logger.level` ๆฅ้…็ฝฎๆ‰“ๅฐๅˆฐๆ–‡ไปถ็š„ๆ—ฅๅฟ—็บงๅˆซ๏ผŒ้€š่ฟ‡ `config.logger.consoleLevel` ้…็ฝฎๆ‰“ๅฐๅˆฐ็ปˆ็ซฏ็š„ๆ—ฅๅฟ—็บงๅˆซใ€‚ @@ -238,6 +239,7 @@ $ DEBUG=egg* npm run dev ``` ๅ•ๅ…ƒๆต‹่ฏ•ไนŸๅฏไปฅไฝฟ็”จ `DEBUG=* npm test` ๆฅๆŸฅ็œ‹ๆต‹่ฏ•็”จไพ‹่ฟ่กŒ็š„่ฏฆ็ป†ๆ—ฅๅฟ—ใ€‚ + ### ไฝฟ็”จ egg-bin ่ฐƒ่ฏ• #### ๆทปๅŠ ๅ‘ฝไปค @@ -331,7 +333,7 @@ DevTools โ†’ chrome-devtools://devtools/bundled/inspector.html?experiments=true& "cwd": "${workspaceRoot}", "runtimeExecutable": "npm", "windows": { "runtimeExecutable": "npm.cmd" }, - "runtimeArgs": [ "run", "debug" ], + "runtimeArgs": ["run", "debug"], "console": "integratedTerminal", "protocol": "auto", "restart": true, diff --git a/site/docs/core/error-handling.md b/site/docs/core/error-handling.md index 490ec444a1..a92e3bce60 100644 --- a/site/docs/core/error-handling.md +++ b/site/docs/core/error-handling.md @@ -12,10 +12,10 @@ With those features, you can take following implementation as reference: ```js // app/service/test.js try { - const res = await this.ctx.curl('http://eggjs.com/api/echo', { - dataType: 'json', + const res = await this.ctx.curl("http://eggjs.com/api/echo", { + dataType: "json", }); - if (res.status !== 200) throw new Error('response status is not 200'); + if (res.status !== 200) throw new Error("response status is not 200"); return res.data; } catch (err) { this.logger.error(err); @@ -80,7 +80,7 @@ Redirecting to your customized error page by setting `errorPageUrl` in `onerror` ```js module.exports = { onerror: { - errorPageUrl: '/50x.html', + errorPageUrl: "/50x.html", }, }; ``` @@ -140,7 +140,7 @@ Overriding default 404 page to the one you want: // config/config.default.js module.exports = { notfound: { - pageUrl: '/404.html', + pageUrl: "/404.html", }, }; ``` @@ -156,9 +156,9 @@ module.exports = () => { await next(); if (ctx.status === 404 && !ctx.body) { if (ctx.acceptJSON) { - ctx.body = { error: 'Not Found' }; + ctx.body = { error: "Not Found" }; } else { - ctx.body = '

Page Not Found

'; + ctx.body = "

Page Not Found

"; } } }; @@ -170,6 +170,6 @@ Adding yours to `middleware` in config: ```js // config/config.default.js module.exports = { - middleware: ['notfoundHandler'], + middleware: ["notfoundHandler"], }; ``` diff --git a/site/docs/core/error-handling.zh-CN.md b/site/docs/core/error-handling.zh-CN.md index 512af4c547..092584defd 100644 --- a/site/docs/core/error-handling.zh-CN.md +++ b/site/docs/core/error-handling.zh-CN.md @@ -10,10 +10,10 @@ order: 9 ```js // app/service/test.js try { - const res = await this.ctx.curl('http://eggjs.com/api/echo', { - dataType: 'json' + const res = await this.ctx.curl("http://eggjs.com/api/echo", { + dataType: "json", }); - if (res.status !== 200) throw new Error('response status is not 200'); + if (res.status !== 200) throw new Error("response status is not 200"); return res.data; } catch (err) { this.logger.error(err); @@ -31,7 +31,7 @@ class HomeController extends Controller { const config = await this.ctx.service.trade.buy(request); // ไธ‹ๅ•ๅŽ้œ€่ฆ่ฟ›่กŒไธ€ๆฌกๆ ธๅฏน๏ผŒไธ”ไธ้˜ปๅกžๅฝ“ๅ‰่ฏทๆฑ‚ setImmediate(() => { - this.ctx.service.trade.check(request).catch(err => this.ctx.logger.error(err)); + this.ctx.service.trade.check(request).catch((err) => this.ctx.logger.error(err)); }); } } @@ -61,13 +61,13 @@ class HomeController extends Controller { ๆก†ๆžถ้€š่ฟ‡ [onerror](https://github.com/eggjs/egg-onerror) ๆ’ไปถๆไพ›็ปŸไธ€็š„้”™่ฏฏๅค„็†ๆœบๅˆถใ€‚ๆญคๆœบๅˆถๅฐ†ๆ•่Žทๆ‰€ๆœ‰ๅค„็†ๆ–นๆณ•๏ผˆMiddlewareใ€Controllerใ€Service๏ผ‰ไธญๆŠ›ๅ‡บ็š„ไปปไฝ•ๅผ‚ๅธธ๏ผŒๅนถๆ นๆฎ่ฏทๆฑ‚้ข„ๆœŸ็š„ๅ“ๅบ”็ฑปๅž‹่ฟ”ๅ›žไธๅŒ็š„้”™่ฏฏๅ†…ๅฎนใ€‚ -| ่ฏทๆฑ‚ๆ ผๅผ้œ€ๆฑ‚ | ็Žฏๅขƒ | `errorPageUrl` ้…็ฝฎ | ่ฟ”ๅ›žๅ†…ๅฎน | -| ------------ | ---- | ------------------- | -------- | -| HTML & TEXT | local & unittest | - | onerror ๆไพ›็š„่ฏฆ็ป†้”™่ฏฏ้กต้ข | -| HTML & TEXT | ๅ…ถไป– | ๆ˜ฏ | ้‡ๅฎšๅ‘่‡ณ `errorPageUrl` | -| HTML & TEXT | ๅ…ถไป– | ๅฆ | ็ฎ€ๆ˜“้”™่ฏฏ้กต๏ผˆไธๅซ้”™่ฏฏไฟกๆฏ๏ผ‰ | -| JSON & JSONP | local & unittest | - | ่ฏฆ็ป†้”™่ฏฏไฟกๆฏ็š„ JSON ๆˆ– JSONP ๅ“ๅบ” | -| JSON & JSONP | ๅ…ถไป– | - | ไธๅซ่ฏฆ็ป†้”™่ฏฏไฟกๆฏ็š„ JSON ๆˆ– JSONP ๅ“ๅบ” | +| ่ฏทๆฑ‚ๆ ผๅผ้œ€ๆฑ‚ | ็Žฏๅขƒ | `errorPageUrl` ้…็ฝฎ | ่ฟ”ๅ›žๅ†…ๅฎน | +| ------------ | ---------------- | ------------------- | ------------------------------------- | +| HTML & TEXT | local & unittest | - | onerror ๆไพ›็š„่ฏฆ็ป†้”™่ฏฏ้กต้ข | +| HTML & TEXT | ๅ…ถไป– | ๆ˜ฏ | ้‡ๅฎšๅ‘่‡ณ `errorPageUrl` | +| HTML & TEXT | ๅ…ถไป– | ๅฆ | ็ฎ€ๆ˜“้”™่ฏฏ้กต๏ผˆไธๅซ้”™่ฏฏไฟกๆฏ๏ผ‰ | +| JSON & JSONP | local & unittest | - | ่ฏฆ็ป†้”™่ฏฏไฟกๆฏ็š„ JSON ๆˆ– JSONP ๅ“ๅบ” | +| JSON & JSONP | ๅ…ถไป– | - | ไธๅซ่ฏฆ็ป†้”™่ฏฏไฟกๆฏ็š„ JSON ๆˆ– JSONP ๅ“ๅบ” | ### errorPageUrl @@ -78,8 +78,8 @@ class HomeController extends Controller { module.exports = { onerror: { // ็บฟไธŠๅ‘็”Ÿๅผ‚ๅธธๆ—ถ๏ผŒ้‡ๅฎšๅ‘ๅˆฐๆญค้กต้ข - errorPageUrl: '/50x.html' - } + errorPageUrl: "/50x.html", + }, }; ``` @@ -94,25 +94,26 @@ module.exports = { all(err, ctx) { // ๅฎšไน‰ๆ‰€ๆœ‰ๅ“ๅบ”็ฑปๅž‹็š„้”™่ฏฏๅค„็†ๆ–นๆณ• // ๅฎšไน‰ไบ† config.all ๅŽ๏ผŒๅ…ถไป–้”™่ฏฏๅค„็†ไธๅ†็”Ÿๆ•ˆ - ctx.body = 'error'; + ctx.body = "error"; ctx.status = 500; }, html(err, ctx) { // HTML ้”™่ฏฏๅค„็† - ctx.body = '

error

'; + ctx.body = "

error

"; ctx.status = 500; }, json(err, ctx) { // JSON ้”™่ฏฏๅค„็† - ctx.body = { message: 'error' }; + ctx.body = { message: "error" }; ctx.status = 500; }, jsonp(err, ctx) { // JSONP ้”™่ฏฏไธ€่ˆฌไธ้œ€็‰นๆฎŠๅค„็†๏ผŒ่‡ชๅŠจ่ฐƒ็”จ JSON ๆ–นๆณ• - } - } + }, + }, }; ``` + ๆก†ๆžถๅนถไธไผšๅฐ†ๆœๅŠก็ซฏ่ฟ”ๅ›ž็š„ 404 ็Šถๆ€ๅฝ“ๅšๅผ‚ๅธธๆฅๅค„็†๏ผŒไฝ†ๆ˜ฏๆก†ๆžถๆไพ›ไบ†ๅฝ“ๅ“ๅบ”ไธบ 404 ไธ”ๆฒกๆœ‰่ฟ”ๅ›ž body ๆ—ถ็š„้ป˜่ฎคๅ“ๅบ”ใ€‚ - ๅฝ“่ฏทๆฑ‚่ขซๆก†ๆžถๅˆคๅฎšไธบ้œ€่ฆ JSON ๆ ผๅผ็š„ๅ“ๅบ”ๆ—ถ๏ผŒไผš่ฟ”ๅ›žไธ€ๆฎต JSON๏ผš @@ -132,9 +133,9 @@ module.exports = { ```js // config/config.default.js module.exports = { - notfound: { - pageUrl: '/404.html', - }, + notfound: { + pageUrl: "/404.html", + }, }; ``` @@ -145,16 +146,16 @@ module.exports = { ```js // app/middleware/notfound_handler.js module.exports = () => { - return async function notFoundHandler(ctx, next) { - await next(); - if (ctx.status === 404 && !ctx.body) { - if (ctx.acceptJSON) { - ctx.body = { error: 'Not Found' }; - } else { - ctx.body = '

Page Not Found

'; - } - } - }; + return async function notFoundHandler(ctx, next) { + await next(); + if (ctx.status === 404 && !ctx.body) { + if (ctx.acceptJSON) { + ctx.body = { error: "Not Found" }; + } else { + ctx.body = "

Page Not Found

"; + } + } + }; }; ``` @@ -163,6 +164,6 @@ module.exports = () => { ```js // config/config.default.js module.exports = { - middleware: ['notfoundHandler'], + middleware: ["notfoundHandler"], }; ``` diff --git a/site/docs/core/httpclient.md b/site/docs/core/httpclient.md index 184a4690f6..7f58403a6e 100644 --- a/site/docs/core/httpclient.md +++ b/site/docs/core/httpclient.md @@ -19,10 +19,10 @@ So you can easily use `app.curl` to complete a HTTP request. module.exports = (app) => { app.beforeStart(async () => { // example: read the version info on https://registry.npmmirror.com/egg/latest when it starts - const result = await app.curl('https://registry.npmmirror.com/egg/latest', { - dataType: 'json', + const result = await app.curl("https://registry.npmmirror.com/egg/latest", { + dataType: "json", }); - app.logger.info('Egg latest version: %s', result.data.version); + app.logger.info("Egg latest version: %s", result.data.version); }); }; ``` @@ -39,9 +39,9 @@ class NpmController extends Controller { const ctx = this.ctx; // example: request a npm module's info - const result = await ctx.curl('https://registry.npmmirror.com/egg/latest', { + const result = await ctx.curl("https://registry.npmmirror.com/egg/latest", { // parse JSON response - dataType: 'json', + dataType: "json", // timeout of 3s timeout: 3000, }); @@ -70,7 +70,7 @@ Reading data almost uses GET request. It is the most common type and widely used class NpmController extends Controller { async get() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/get?foo=bar'); + const result = await ctx.curl("https://httpbin.org/get?foo=bar"); ctx.status = result.status; ctx.set(result.headers); ctx.body = result.data; @@ -98,17 +98,17 @@ Take sending JSON boy as example: class NpmController extends Controller { async post() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/post', { + const result = await ctx.curl("https://httpbin.org/post", { // method is required - method: 'POST', + method: "POST", // telling HttpClient to send data as JSON by contentType - contentType: 'json', + contentType: "json", data: { - hello: 'world', + hello: "world", now: Date.now(), }, // telling HttpClient to process the return body as JSON format explicitly - dataType: 'json', + dataType: "json", }); ctx.body = result.data; } @@ -126,16 +126,16 @@ Similar to POST, but PUT is better for data updating and replacement. Almost the class NpmController extends Controller { async put() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/put', { + const result = await ctx.curl("https://httpbin.org/put", { // method is required - method: 'PUT', + method: "PUT", // telling HttpClient to send data as JSON by contentType - contentType: 'json', + contentType: "json", data: { - update: 'foo bar', + update: "foo bar", }, // telling HttpClient to process the return body as JSON format explicitly - dataType: 'json', + dataType: "json", }); ctx.body = result.data; } @@ -151,11 +151,11 @@ DELETE request is to delete the data, request body don't need to add request bod class NpmController extends Controller { async del() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/delete', { + const result = await ctx.curl("https://httpbin.org/delete", { // method is required - method: 'DELETE', + method: "DELETE", // telling HttpClient to process the return body as JSON format explicitly - dataType: 'json', + dataType: "json", }); ctx.body = result.data; } @@ -175,16 +175,16 @@ Interfaces of Browser-Oriented Form Submission (without files), usually require class NpmController extends Controller { async submit() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/post', { + const result = await ctx.curl("https://httpbin.org/post", { // method is required, supports POST๏ผŒPUT and DELETE - method: 'POST', + method: "POST", // contentType is not needed, by default HttpClient will send request in application/x-www-form-urlencoded data: { now: Date.now(), - foo: 'bar', + foo: "bar", }, // telling HttpClient to process the return body as JSON format explicitly - dataType: 'json', + dataType: "json", }); ctx.body = result.data.form; // final response will similar as below: @@ -207,11 +207,11 @@ class HttpController extends Controller { async upload() { const { ctx } = this; - const result = await ctx.curl('https://httpbin.org/post', { - method: 'POST', - dataType: 'json', + const result = await ctx.curl("https://httpbin.org/post", { + method: "POST", + dataType: "json", data: { - foo: 'bar', + foo: "bar", }, // one file @@ -241,8 +241,8 @@ If the server supports streaming, the most friendly way is to send the Stream di ```js // app/controller/npm.js -const fs = require('fs'); -const FormStream = require('formstream'); +const fs = require("fs"); +const FormStream = require("formstream"); class NpmController extends Controller { async uploadByStream() { const ctx = this.ctx; @@ -252,7 +252,7 @@ class NpmController extends Controller { const url = `${ctx.protocol}://${ctx.host}/stream`; const result = await ctx.curl(url, { // method is required, supports POST๏ผŒPUT - method: 'POST', + method: "POST", // submitted by stream mode stream: fileStream, }); @@ -330,20 +330,20 @@ The request data will select the correct processing method automatically based o ```js // GET + data ctx.curl(url, { - data: { foo: 'bar' }, + data: { foo: "bar" }, }); // POST + data ctx.curl(url, { - method: 'POST', - data: { foo: 'bar' }, + method: "POST", + data: { foo: "bar" }, }); // POST + JSON + data ctx.curl(url, { - method: 'POST', - contentType: 'json', - data: { foo: 'bar' }, + method: "POST", + contentType: "json", + data: { foo: "bar" }, }); ``` @@ -355,11 +355,11 @@ The application scenarios that sending data using `stream` and pass additional r ```js ctx.curl(url, { - method: 'POST', + method: "POST", dataAsQueryString: true, data: { // generally it would be some validation parameters such as access token, etc. - accessToken: 'some access token value', + accessToken: "some access token value", }, stream: myFileStream, }); @@ -371,11 +371,11 @@ Set request Context, if the parameter is set, it will ignore the `data` paramete ```js ctx.curl(url, { - method: 'POST', + method: "POST", // Sending the raw xml data without HttpClient's to do processing - content: 'world', + content: "world", headers: { - 'content-type': 'text/html', + "content-type": "text/html", }, }); ``` @@ -386,10 +386,10 @@ File upload, support: `String | ReadStream | Buffer | Array | Object`. ```js ctx.curl(url, { - method: 'POST', - files: '/path/to/read', + method: "POST", + files: "/path/to/read", data: { - foo: 'other fields', + foo: "other fields", }, }); ``` @@ -398,14 +398,14 @@ upload multiple files: ```js ctx.curl(url, { - method: 'POST', + method: "POST", files: { - file1: '/path/to/read', + file1: "/path/to/read", file2: fs.createReadStream(__filename), - file3: Buffer.from('mock file content'), + file3: Buffer.from("mock file content"), }, data: { - foo: 'other fields', + foo: "other fields", }, }); ``` @@ -417,8 +417,8 @@ If the parameter is set , HttpClient will ignore `data` and `content` ```js ctx.curl(url, { - method: 'POST', - stream: fs.createReadStream('/path/to/read'), + method: "POST", + stream: fs.createReadStream("/path/to/read"), }); ``` @@ -429,7 +429,7 @@ Once the parameter is set, response `result.data` is set to `null` because all d ```js ctx.curl(url, { - writeStream: fs.createWriteStream('/path/to/store'), + writeStream: fs.createWriteStream("/path/to/store"), }); ``` @@ -451,12 +451,12 @@ If need to send `data` by JSON ```js ctx.curl(url, { - method: 'POST', + method: "POST", data: { - foo: 'bar', + foo: "bar", now: Date.now(), }, - contentType: 'json', + contentType: "json", }); ``` @@ -468,12 +468,12 @@ Set the response data format, default return the raw buffer formatted data witho ```js const jsonResult = await ctx.curl(url, { - dataType: 'json', + dataType: "json", }); console.log(jsonResult.data); const htmlResult = await ctx.curl(url, { - dataType: 'text', + dataType: "text", }); console.log(htmlResult.data); ``` @@ -486,7 +486,7 @@ Typically, the JSON data returned by some CGI system might contains such special ```js ctx.curl(url, { fixJSONCtlChars: true, - dataType: 'json', + dataType: "json", }); ``` @@ -497,7 +497,7 @@ Custom request headers ```js ctx.curl(url, { headers: { - 'x-foo': 'bar', + "x-foo": "bar", }, }); ``` @@ -545,7 +545,7 @@ Parameter of Simple login authorization (Basic Authentication), will send the lo ```js ctx.curl(url, { // parameter must follow the format of `user:password` - auth: 'foo:bar', + auth: "foo:bar", }); ``` @@ -556,7 +556,7 @@ Parameter of the Digest Authentication. If the parameter is set, it will attempt ```js ctx.curl(url, { // parameter must follow the format of `user:password` - digestAuth: 'foo:bar', + digestAuth: "foo:bar", }); ``` @@ -591,8 +591,8 @@ ctx.curl(url, { ctx.curl(url, { formatRedirectUrl: (from, to) => { // for example you can correct the redirection of wrong url here - if (to === '//foo/') { - to = '/foo'; + if (to === "//foo/") { + to = "/foo"; } return url.resolve(from, to); }, @@ -607,7 +607,7 @@ HttpClient will attempt to invoke the `beforeRequest` hook before requesting off ctx.curl(url, { beforeRequest: (options) => { // For example, we can set the global request ID to facilitate log tracking - options.headers['x-request-id'] = uuid.v1(); + options.headers["x-request-id"] = uuid.v1(); }, }); ``` @@ -773,7 +773,7 @@ To facilitate monitoring HttpClient requests and responses on the app level, we A `request` event is triggered before the request is sent, allowing blocking of the request. ```js -app.httpclient.on('request', (req) => { +app.httpclient.on("request", (req) => { req.url; //request url req.ctx; //context of the request @@ -786,7 +786,7 @@ app.httpclient.on('request', (req) => { After the end of request, a `response` event is triggered, so that the external event can be subscribed to the log printing. ```js -app.httpclient.on('response', (result) => { +app.httpclient.on("response", (result) => { result.res.status; result.ctx; //context of the request result.req; //the corresponding req object, which the req in the request event @@ -797,8 +797,8 @@ app.httpclient.on('response', (result) => { Full examples can be found on [eggjs/examples/httpclient](https://github.com/eggjs/examples/blob/master/httpclient) . - Other Reference Links + - [urllib](https://github.com/node-modules/urllib) - [httpclient](https://github.com/eggjs/egg/blob/master/lib/core/httpclient.js) - [formstream](https://github.com/node-modules/formstream) diff --git a/site/docs/core/httpclient.zh-CN.md b/site/docs/core/httpclient.zh-CN.md index 6e3065755e..f4f3c97741 100644 --- a/site/docs/core/httpclient.zh-CN.md +++ b/site/docs/core/httpclient.zh-CN.md @@ -15,13 +15,13 @@ order: 5 ```js // app.js -module.exports = app => { +module.exports = (app) => { app.beforeStart(async () => { // ็คบไพ‹๏ผšๅฏๅŠจๆ—ถๅŽป่ฏปๅ– https://registry.npmmirror.com/egg/latest ็š„็‰ˆๆœฌไฟกๆฏ - const result = await app.curl('https://registry.npmmirror.com/egg/latest', { - dataType: 'json', + const result = await app.curl("https://registry.npmmirror.com/egg/latest", { + dataType: "json", }); - app.logger.info('Egg ๆœ€ๆ–ฐ็‰ˆๆœฌ๏ผš%s', result.data.version); + app.logger.info("Egg ๆœ€ๆ–ฐ็‰ˆๆœฌ๏ผš%s", result.data.version); }); }; ``` @@ -37,9 +37,9 @@ class NpmController extends Controller { const ctx = this.ctx; // ็คบไพ‹๏ผš่ฏทๆฑ‚ไธ€ไธช npm ๆจกๅ—ไฟกๆฏ - const result = await ctx.curl('https://registry.npmmirror.com/egg/latest', { + const result = await ctx.curl("https://registry.npmmirror.com/egg/latest", { // ่‡ชๅŠจ่งฃๆž JSON ๅ“ๅบ” - dataType: 'json', + dataType: "json", // 3 ็ง’่ถ…ๆ—ถ timeout: 3000, }); @@ -52,6 +52,7 @@ class NpmController extends Controller { } } ``` + ## ๅŸบๆœฌ HTTP ่ฏทๆฑ‚ HTTP ๅทฒ็ป่ขซๅนฟๆณ›ๅคง้‡ไฝฟ็”จใ€‚ๅฐฝ็ฎก HTTP ๆœ‰ๅคš็ง่ฏทๆฑ‚ๆ–นๅผ๏ผŒไฝ†ๆ˜ฏไธ‡ๅ˜ไธ็ฆปๅ…ถๅฎ—ใ€‚ๆˆ‘ไปฌๅ…ˆไปฅๅŸบๆœฌ็š„ๅ››ไธช่ฏทๆฑ‚ๆ–นๆณ•ไธบไพ‹ๅญ๏ผŒ้€ๆญฅ่ฎฒ่งฃไธ€ไธ‹ๆ›ดๅคš็š„ๅคๆ‚ๅบ”็”จๅœบๆ™ฏใ€‚ @@ -67,13 +68,12 @@ HTTP ๅทฒ็ป่ขซๅนฟๆณ›ๅคง้‡ไฝฟ็”จใ€‚ๅฐฝ็ฎก HTTP ๆœ‰ๅคš็ง่ฏทๆฑ‚ๆ–นๅผ๏ผŒไฝ†ๆ˜ฏไธ‡ class NpmController extends Controller { async get() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/get?foo=bar'); + const result = await ctx.curl("https://httpbin.org/get?foo=bar"); ctx.status = result.status; ctx.set(result.headers); ctx.body = result.data; } } - ``` - GET ่ฏทๆฑ‚ๅฏไปฅไธ็”จ่ฎพ็ฝฎ `options.method` ๅ‚ๆ•ฐ๏ผŒ`HttpClient` ็š„้ป˜่ฎค `method` ไผš่ฎพ็ฝฎไธบ `GET`ใ€‚ @@ -96,22 +96,21 @@ class NpmController extends Controller { class NpmController extends Controller { async post() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/post', { + const result = await ctx.curl("https://httpbin.org/post", { // ๅฟ…้กปๆŒ‡ๅฎš method - method: 'POST', + method: "POST", // ้€š่ฟ‡ contentType ๅ‘Š่ฏ‰ HttpClient ไปฅ JSON ๆ ผๅผๅ‘้€ - contentType: 'json', + contentType: "json", data: { - hello: 'world', + hello: "world", now: Date.now(), }, // ๆ˜Ž็กฎๅ‘Š่ฏ‰ HttpClient ไปฅ JSON ๆ ผๅผๅค„็†่ฟ”ๅ›ž็š„ๅ“ๅบ” body - dataType: 'json', + dataType: "json", }); ctx.body = result.data; } } - ``` ไธ‹ๆ–‡่ฟ˜ไผš่ฏฆ็ป†่ฎฒ่งฃไปฅ POST ๅฎž็Žฐ่กจๅ•ๆไบคๅ’Œๆ–‡ไปถไธŠไผ ็š„ๅŠŸ่ƒฝใ€‚ @@ -126,21 +125,20 @@ PUT ไธŽ POST ็ฑปไผผ๏ผŒๅฎƒๆ›ดๅŠ ้€‚ๅˆๆ›ดๆ–ฐๆ•ฐๆฎๅ’Œๆ›ฟๆขๆ•ฐๆฎ็š„่ฏญไน‰ใ€‚ class NpmController extends Controller { async put() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/put', { + const result = await ctx.curl("https://httpbin.org/put", { // ๅฟ…้กปๆŒ‡ๅฎš method - method: 'PUT', + method: "PUT", // ้€š่ฟ‡ contentType ๅ‘Š่ฏ‰ HttpClient ไปฅ JSON ๆ ผๅผๅ‘้€ - contentType: 'json', + contentType: "json", data: { - update: 'foo bar', + update: "foo bar", }, // ๆ˜Ž็กฎๅ‘Š่ฏ‰ HttpClient ไปฅ JSON ๆ ผๅผๅค„็†ๅ“ๅบ” body - dataType: 'json', + dataType: "json", }); ctx.body = result.data; } } - ``` ### DELETE @@ -152,17 +150,17 @@ class NpmController extends Controller { class NpmController extends Controller { async del() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/delete', { + const result = await ctx.curl("https://httpbin.org/delete", { // ๅฟ…้กปๆŒ‡ๅฎš method - method: 'DELETE', + method: "DELETE", // ๆ˜Ž็กฎๅ‘Š่ฏ‰ HttpClient ไปฅ JSON ๆ ผๅผๅค„็†ๅ“ๅบ” body - dataType: 'json', + dataType: "json", }); ctx.body = result.data; } } - ``` + ## ้ซ˜็บง HTTP ่ฏทๆฑ‚ ๅœจ็œŸๅฎž็š„ๅบ”็”จๅœบๆ™ฏไธ‹๏ผŒ่ฟ˜ไผšๅŒ…ๅซไธ€ไบ›่พƒไธบๅคๆ‚็š„ HTTP ่ฏทๆฑ‚ใ€‚ @@ -176,16 +174,16 @@ class NpmController extends Controller { class NpmController extends Controller { async submit() { const ctx = this.ctx; - const result = await ctx.curl('https://httpbin.org/post', { + const result = await ctx.curl("https://httpbin.org/post", { // ๅฟ…้กปๆŒ‡ๅฎš method๏ผŒๆ”ฏๆŒ POST๏ผŒPUT ๅ’Œ DELETE - method: 'POST', + method: "POST", // ไธ้œ€่ฆ่ฎพ็ฝฎ contentType๏ผŒHttpClient ไผš้ป˜่ฎคไปฅ application/x-www-form-urlencoded ๆ ผๅผๅ‘้€่ฏทๆฑ‚ data: { now: Date.now(), - foo: 'bar', + foo: "bar", }, // ๆ˜Ž็กฎๅ‘Š่ฏ‰ HttpClient ไปฅ JSON ๆ ผๅผๅค„็†ๅ“ๅบ” body - dataType: 'json', + dataType: "json", }); ctx.body = result.data.form; // ๅ“ๅบ”ๆœ€็ปˆไผšๆ˜ฏ็ฑปไผผไปฅไธ‹็š„็ป“ๆžœ๏ผš @@ -209,16 +207,16 @@ class HttpController extends Controller { async upload() { const { ctx } = this; - const result = await ctx.curl('https://httpbin.org/post', { - method: 'POST', - dataType: 'json', + const result = await ctx.curl("https://httpbin.org/post", { + method: "POST", + dataType: "json", data: { - foo: 'bar', + foo: "bar", }, - + // ๅ•ๆ–‡ไปถไธŠไผ  files: __filename, - + // ๅคšๆ–‡ไปถไธŠไผ  // files: { // file1: __filename, @@ -242,8 +240,8 @@ class HttpController extends Controller { ```js // app/controller/npm.js -const fs = require('fs'); -const FormStream = require('formstream'); +const fs = require("fs"); +const FormStream = require("formstream"); class NpmController extends Controller { async uploadByStream() { const ctx = this.ctx; @@ -253,7 +251,7 @@ class NpmController extends Controller { const url = `${ctx.protocol}://${ctx.host}/stream`; const result = await ctx.curl(url, { // ๅฟ…้กปๆŒ‡ๅฎš method๏ผŒๆ”ฏๆŒ POST๏ผŒPUT - method: 'POST', + method: "POST", // ไปฅ stream ๆจกๅผๆไบค stream: fileStream, }); @@ -265,6 +263,7 @@ class NpmController extends Controller { } } ``` + ## options ๅ‚ๆ•ฐ่ฏฆ่งฃ ็”ฑไบŽ HTTP ่ฏทๆฑ‚็š„ๅคๆ‚ๆ€ง๏ผŒๅฏผ่‡ด `httpclient.request(url, options)` ็š„ options ๅ‚ๆ•ฐไผš้žๅธธๅคšใ€‚ @@ -286,7 +285,7 @@ exports.httpclient = { request: { // ้ป˜่ฎค request ่ถ…ๆ—ถๆ—ถ้—ด - timeout: 3000 + timeout: 3000, }, httpAgent: { @@ -299,7 +298,7 @@ exports.httpclient = { // ๅ…่ฎธๅˆ›ๅปบ็š„ๆœ€ๅคง socket ๆ•ฐ maxSockets: Number.MAX_SAFE_INTEGER, // ๆœ€ๅคง็ฉบ้—ฒ socket ๆ•ฐ - maxFreeSockets: 256 + maxFreeSockets: 256, }, httpsAgent: { @@ -312,8 +311,8 @@ exports.httpclient = { // ๅ…่ฎธๅˆ›ๅปบ็š„ๆœ€ๅคง socket ๆ•ฐ maxSockets: Number.MAX_SAFE_INTEGER, // ๆœ€ๅคง็ฉบ้—ฒ socket ๆ•ฐ - maxFreeSockets: 256 - } + maxFreeSockets: 256, + }, }; ``` @@ -331,20 +330,20 @@ exports.httpclient = { ```javascript // GET + data ctx.curl(url, { - data: { foo: 'bar' } + data: { foo: "bar" }, }); // POST + data ctx.curl(url, { - method: 'POST', - data: { foo: 'bar' } + method: "POST", + data: { foo: "bar" }, }); // POST + JSON + data ctx.curl(url, { - method: 'POST', - contentType: 'json', - data: { foo: 'bar' } + method: "POST", + contentType: "json", + data: { foo: "bar" }, }); ``` @@ -357,13 +356,13 @@ ctx.curl(url, { ```javascript ctx.curl(url, { - method: 'POST', + method: "POST", dataAsQueryString: true, data: { // ้€šๅธธๆ˜ฏๆƒ้™้ชŒ่ฏๅ‚ๆ•ฐ๏ผŒๅฆ‚ access token - accessToken: 'some access token value' + accessToken: "some access token value", }, - stream: myFileStream + stream: myFileStream, }); ``` @@ -373,24 +372,25 @@ ctx.curl(url, { ```javascript ctx.curl(url, { - method: 'POST', + method: "POST", // ็›ดๆŽฅๅ‘้€ๅŽŸๅง‹ XML ๆ•ฐๆฎ๏ผŒไธ้œ€ HttpClient ็ป่กŒ็‰นๆฎŠๅค„็† - content: 'world', + content: "world", headers: { - 'content-type': 'text/html' - } + "content-type": "text/html", + }, }); ``` + ### `files: Mixed` ๆ–‡ไปถไธŠไผ ๏ผŒๆ”ฏๆŒไปฅไธ‹ๆ ผๅผ๏ผš`String | ReadStream | Buffer | Array | Object`ใ€‚ ```js ctx.curl(url, { - method: 'POST', - files: '/path/to/read', + method: "POST", + files: "/path/to/read", data: { - foo: 'other fields', + foo: "other fields", }, }); ``` @@ -399,14 +399,14 @@ ctx.curl(url, { ```js ctx.curl(url, { - method: 'POST', + method: "POST", files: { - file1: '/path/to/read', + file1: "/path/to/read", file2: fs.createReadStream(__filename), - file3: Buffer.from('mock file content'), + file3: Buffer.from("mock file content"), }, data: { - foo: 'other fields', + foo: "other fields", }, }); ``` @@ -417,8 +417,8 @@ ctx.curl(url, { ```js ctx.curl(url, { - method: 'POST', - stream: fs.createReadStream('/path/to/read'), + method: "POST", + stream: fs.createReadStream("/path/to/read"), }); ``` @@ -428,7 +428,7 @@ ctx.curl(url, { ```js ctx.curl(url, { - writeStream: fs.createWriteStream('/path/to/store'), + writeStream: fs.createWriteStream("/path/to/store"), }); ``` @@ -448,12 +448,12 @@ ctx.curl(url, { ```js ctx.curl(url, { - method: 'POST', + method: "POST", data: { - foo: 'bar', + foo: "bar", now: Date.now(), }, - contentType: 'json', + contentType: "json", }); ``` @@ -465,12 +465,12 @@ ctx.curl(url, { ```js const jsonResult = await ctx.curl(url, { - dataType: 'json', + dataType: "json", }); console.log(jsonResult.data); const htmlResult = await ctx.curl(url, { - dataType: 'text', + dataType: "text", }); console.log(htmlResult.data); ``` @@ -482,7 +482,7 @@ console.log(htmlResult.data); ```js ctx.curl(url, { fixJSONCtlChars: true, - dataType: 'json', + dataType: "json", }); ``` @@ -493,10 +493,11 @@ ctx.curl(url, { ```js ctx.curl(url, { headers: { - 'x-foo': 'bar', + "x-foo": "bar", }, }); ``` + ### `timeout: Number|Array` ่ฏทๆฑ‚่ถ…ๆ—ถๆ—ถ้—ด๏ผŒ้ป˜่ฎคๆ˜ฏ `[5000, 5000]`๏ผŒๅณๅˆ›ๅปบ่ฟžๆŽฅ่ถ…ๆ—ถๆ˜ฏ 5 ็ง’๏ผŒๆŽฅๆ”ถๅ“ๅบ”่ถ…ๆ—ถๆ˜ฏ 5 ็ง’ใ€‚ @@ -504,12 +505,12 @@ ctx.curl(url, { ```js ctx.curl(url, { // ๅˆ›ๅปบ่ฟžๆŽฅ่ถ…ๆ—ถ 3 ็ง’๏ผŒๆŽฅๆ”ถๅ“ๅบ”่ถ…ๆ—ถ 3 ็ง’ - timeout: 3000 + timeout: 3000, }); ctx.curl(url, { // ๅˆ›ๅปบ่ฟžๆŽฅ่ถ…ๆ—ถ 1 ็ง’๏ผŒๆŽฅๆ”ถๅ“ๅบ”่ถ…ๆ—ถ 30 ็ง’๏ผŒ็”จไบŽๅ“ๅบ”ๆฏ”่พƒๅคง็š„ๅœบๆ™ฏ - timeout: [1000, 30000] + timeout: [1000, 30000], }); ``` @@ -519,7 +520,7 @@ ctx.curl(url, { ```js ctx.curl(url, { - agent: false + agent: false, }); ``` @@ -529,7 +530,7 @@ ctx.curl(url, { ```js ctx.curl(url, { - httpsAgent: false + httpsAgent: false, }); ``` @@ -540,7 +541,7 @@ ctx.curl(url, { ```js ctx.curl(url, { // ๅ‚ๆ•ฐๅฟ…้กปๆŒ‰็…ง `user:password` ๆ ผๅผ่ฎพ็ฝฎ - auth: 'foo:bar' + auth: "foo:bar", }); ``` @@ -551,7 +552,7 @@ ctx.curl(url, { ```js ctx.curl(url, { // ๅ‚ๆ•ฐๅฟ…้กปๆŒ‰็…ง `user:password` ๆ ผๅผ่ฎพ็ฝฎ - digestAuth: 'foo:bar' + digestAuth: "foo:bar", }); ``` @@ -561,7 +562,7 @@ ctx.curl(url, { ```js ctx.curl(url, { - followRedirect: true + followRedirect: true, }); ``` @@ -573,7 +574,7 @@ ctx.curl(url, { ctx.curl(url, { followRedirect: true, // ๆœ€ๅคš่‡ชๅŠจ่ทณ่ฝฌ 5 ๆฌก - maxRedirects: 5 + maxRedirects: 5, }); ``` @@ -585,11 +586,11 @@ ctx.curl(url, { ctx.curl(url, { formatRedirectUrl: (from, to) => { // ๆฏ”ๅฆ‚ๅฏไปฅๅœจ่ฟ™้‡Œไฟฎๆญฃ่ทณ่ฝฌไธๆญฃ็กฎ็š„ URL - if (to === '//foo/') { - to = '/foo'; + if (to === "//foo/") { + to = "/foo"; } return url.resolve(from, to); - } + }, }); ``` @@ -601,8 +602,8 @@ HttpClient ๅœจ่ฏทๆฑ‚ๆญฃๅผๅ‘้€ไน‹ๅ‰๏ผŒไผšๅฐ่ฏ•่ฐƒ็”จ `beforeRequest` ้’ฉๅญ ctx.curl(url, { beforeRequest: (options) => { // ๆฏ”ๅฆ‚ๅฏไปฅๅœจ่ฟ™้‡Œ่ฎพ็ฝฎๅ…จๅฑ€่ฏทๆฑ‚ ID๏ผŒไพฟไบŽๆ—ฅๅฟ—่ทŸ่ธช - options.headers['x-request-id'] = uuid.v1(); - } + options.headers["x-request-id"] = uuid.v1(); + }, }); ``` @@ -612,7 +613,7 @@ ctx.curl(url, { ```js const result = await ctx.curl(url, { - streaming: true + streaming: true, }); console.log(result.status, result.data); @@ -621,6 +622,7 @@ ctx.body = result.res; ``` **ๆณจๆ„**๏ผšๅฆ‚ๆžœ res ไธๆ˜ฏ็›ดๆŽฅไผ ้€’็ป™ body๏ผŒ้‚ฃไนˆๆˆ‘ไปฌๅฟ…้กปๆถˆ่ดน่ฟ™ไธช stream ๅนถไธ”ๅšๅฅฝ `error` ไบ‹ไปถ็š„ๅค„็†ใ€‚ + ### `gzip: Boolean` ๆ˜ฏๅฆๆ”ฏๆŒ gzip ๅ“ๅบ”ๆ ผๅผ๏ผŒ้ป˜่ฎคไธบ `false`ใ€‚ๅผ€ๅฏ gzip ไน‹ๅŽ๏ผŒHttpClient ๅฐ†่‡ชๅŠจ่ฎพ็ฝฎ `Accept-Encoding: gzip` ่ฏทๆฑ‚ๅคด๏ผŒๅนถไธ”ไผš่‡ชๅŠจ่งฃๅŽ‹ๅธฆๆœ‰ `Content-Encoding: gzip` ๅ“ๅบ”ๅคด็š„ๆ•ฐๆฎใ€‚ @@ -636,6 +638,7 @@ ctx.curl(url, { ๆ˜ฏๅฆๅผ€ๅฏ่ฏทๆฑ‚ๅ„้˜ถๆฎต็š„ๆ—ถ้—ดๆต‹้‡๏ผŒ้ป˜่ฎคไธบ `false`ใ€‚ๅผ€ๅฏ timing ไน‹ๅŽ๏ผŒๅฏไปฅ้€š่ฟ‡ `result.res.timing` ๆ‹ฟๅˆฐ่ฟ™ๆฌก HTTP ่ฏทๆฑ‚ๅ„้˜ถๆฎต็š„ๆ—ถ้—ดๆต‹้‡ๅ€ผ๏ผˆๅ•ไฝๆ˜ฏๆฏซ็ง’๏ผ‰ใ€‚้€š่ฟ‡่ฟ™ไบ›ๆต‹้‡ๅ€ผ๏ผŒๆˆ‘ไปฌๅฏไปฅ้žๅธธๆ–นไพฟๅœฐๅฎšไฝๅˆฐ่ฟ™ๆฌก่ฏทๆฑ‚ๆœ€ๆ…ข็š„็Žฏ่Š‚ๅ‘็”Ÿๅœจๅ“ชไธช้˜ถๆฎตใ€‚ๆ•ˆๆžœ็ฑปไผผไบŽChrome network timingใ€‚ timing ๅ„้˜ถๆฎตๆต‹้‡ๅ€ผ่งฃๆž๏ผš + - queuing๏ผšๅˆ†้… socket ็š„่€—ๆ—ถ - dnslookup๏ผšDNS ๆŸฅ่ฏข่€—ๆ—ถ - connected๏ผšsocket ไธ‰ๆฌกๆกๆ‰‹่ฟžๆŽฅๆˆๅŠŸ่€—ๆ—ถ @@ -697,34 +700,41 @@ $ http_proxy=http://127.0.0.1:8888 npm run dev ## ๅธธ่ง้”™่ฏฏ ### ๅˆ›ๅปบ่ฟžๆŽฅ่ถ…ๆ—ถ + - ๅผ‚ๅธธๅ็งฐ๏ผš`ConnectionTimeoutError` - ๅ‡บ็Žฐๅœบๆ™ฏ๏ผš้€šๅธธๆ˜ฏ DNS ๆŸฅ่ฏข่พƒๆ…ขๆˆ–่€…ๅฎขๆˆท็ซฏไธŽๆœๅŠก็ซฏ็ฝ‘็ปœ่พƒๆ…ขๅฏผ่‡ดใ€‚ - ๆŽ’ๆŸฅๅปบ่ฎฎ๏ผš้€‚ๅฝ“ๅขžๅคง `timeout` ๅ‚ๆ•ฐใ€‚ ### ๆœๅŠกๅ“ๅบ”่ถ…ๆ—ถ + - ๅผ‚ๅธธๅ็งฐ๏ผš`ResponseTimeoutError` - ๅ‡บ็Žฐๅœบๆ™ฏ๏ผšๅฎขๆˆท็ซฏไธŽๆœๅŠก็ซฏ็ฝ‘็ปœ่พƒๆ…ข๏ผŒๅ“ๅบ”ๆ•ฐๆฎ่พƒๅคงๆ—ถๅ‘็”Ÿใ€‚ - ๆŽ’ๆŸฅๅปบ่ฎฎ๏ผš้€‚ๅฝ“ๅขžๅคง `timeout` ๅ‚ๆ•ฐใ€‚ ### ๆœๅŠกไธปๅŠจๆ–ญๅผ€่ฟžๆŽฅ + - ๅผ‚ๅธธๅ็งฐ๏ผš`ResponseError, code: ECONNRESET` - ๅ‡บ็Žฐๅœบๆ™ฏ๏ผšๆœๅŠก็ซฏไธปๅŠจๆ–ญๅผ€ socket ่ฟžๆŽฅ๏ผŒๅฏผ่‡ด HTTP ่ฏทๆฑ‚้“พ่ทฏๅผ‚ๅธธใ€‚ - ๆŽ’ๆŸฅๅปบ่ฎฎ๏ผšๆฃ€ๆŸฅๆœๅŠก็ซฏๆ˜ฏๅฆๅ‘็”Ÿ็ฝ‘็ปœๅผ‚ๅธธใ€‚ ### ๆœๅŠกไธๅฏ่พพ + - ๅผ‚ๅธธๅ็งฐ๏ผš`RequestError, code: ECONNREFUSED, status: -1` - ๅ‡บ็Žฐๅœบๆ™ฏ๏ผš่ฏทๆฑ‚็š„ URL ๆ‰€ๅฑž IP ๆˆ–็ซฏๅฃๆ— ๆณ•่ฟžๆŽฅใ€‚ - ๆŽ’ๆŸฅๅปบ่ฎฎ๏ผš็กฎไฟ IP ๆˆ–็ซฏๅฃ่ฎพ็ฝฎๆญฃ็กฎใ€‚ ### ๅŸŸๅไธๅญ˜ๅœจ + - ๅผ‚ๅธธๅ็งฐ๏ผš`RequestError, code: ENOTFOUND, status: -1` - ๅ‡บ็Žฐๅœบๆ™ฏ๏ผš่ฏทๆฑ‚็š„ URL ๅŸŸๅๆ— ๆณ•้€š่ฟ‡ DNS ่งฃๆžใ€‚ - ๆŽ’ๆŸฅๅปบ่ฎฎ๏ผš็กฎไฟๅŸŸๅๅญ˜ๅœจ๏ผŒๆฃ€ๆŸฅ DNS ๆœๅŠก้…็ฝฎใ€‚ ### JSON ๅ“ๅบ”ๆ•ฐๆฎๆ ผๅผ้”™่ฏฏ + - ๅผ‚ๅธธๅ็งฐ๏ผš`JSONResponseFormatError` - ๅ‡บ็Žฐๅœบๆ™ฏ๏ผš่ฎพ็ฝฎ `dataType=json` ไฝ†ๅ“ๅบ”ๆ•ฐๆฎไธๆ˜ฏ JSON ๆ ผๅผๆ—ถๆŠ›ๅ‡บใ€‚ - ๆŽ’ๆŸฅๅปบ่ฎฎ๏ผš็กฎไฟๆœๅŠก็ซฏ่ฟ”ๅ›žๆญฃ็กฎ็š„ JSON ๆ ผๅผๆ•ฐๆฎใ€‚ + ## ๅ…จๅฑ€ `request` ๅ’Œ `response` ไบ‹ไปถ ๅœจไผไธšๅบ”็”จๅœบๆ™ฏไธญ๏ผŒๅธธๅธธไผšๆœ‰็ปŸไธ€ tracer ๆ—ฅๅฟ—็š„้œ€ๆฑ‚ใ€‚ @@ -751,7 +761,7 @@ $ http_proxy=http://127.0.0.1:8888 npm run dev ่ฏทๆฑ‚ๅ‘้€ไน‹ๅ‰๏ผŒไผš่งฆๅ‘ไธ€ไธช `request` ไบ‹ไปถ๏ผŒๅ…่ฎธๅฏน่ฏทๆฑ‚ๅšๆ‹ฆๆˆชใ€‚ ```js -app.httpclient.on('request', (req) => { +app.httpclient.on("request", (req) => { req.url; // ่ฏทๆฑ‚ URL req.ctx; // ๅ‘่ตท่ฟ™ๆฌก่ฏทๆฑ‚็š„ๅฝ“ๅ‰ไธŠไธ‹ๆ–‡ @@ -764,7 +774,7 @@ app.httpclient.on('request', (req) => { ่ฏทๆฑ‚็ป“ๆŸไน‹ๅŽไผš่งฆๅ‘ไธ€ไธช `response` ไบ‹ไปถ๏ผŒ่ฟ™ๆ ทๅค–้ƒจๅฐฑๅฏไปฅ่ฎข้˜…่ฟ™ไธชไบ‹ไปถๆฅๆ‰“ๅฐๆ—ฅๅฟ—ใ€‚ ```js -app.httpclient.on('response', (result) => { +app.httpclient.on("response", (result) => { result.res.status; // ๅ“ๅบ”็Šถๆ€็  result.ctx; // ๅ‘่ตท่ฟ™ๆฌก่ฏทๆฑ‚็š„ๅฝ“ๅ‰ไธŠไธ‹ๆ–‡ result.req; // ๅฏนๅบ”็š„ req ๅฏน่ฑก๏ผŒๅณ request ไบ‹ไปถ้‡Œ็š„้‚ฃไธช req @@ -776,6 +786,7 @@ app.httpclient.on('response', (result) => { ๅฎŒๆ•ด็คบไพ‹ไปฃ็ ๅฏไปฅๅœจ [eggjs/examples/httpclient](https://github.com/eggjs/examples/blob/master/httpclient) ๆ‰พๅˆฐใ€‚ ๅ…ถไป–ๅ‚่€ƒ้“พๆŽฅ๏ผš + - [urllib](https://github.com/node-modules/urllib) - [httpclient](https://github.com/eggjs/egg/blob/master/lib/core/httpclient.js) - [formstream](https://github.com/node-modules/formstream) diff --git a/site/docs/core/i18n.md b/site/docs/core/i18n.md index ba3f952381..338974de3a 100644 --- a/site/docs/core/i18n.md +++ b/site/docs/core/i18n.md @@ -12,7 +12,7 @@ Default `en-US`. Assume that we want to switch the default language to Simplifie ```js // config/config.default.js exports.i18n = { - defaultLocale: 'zh-CN', + defaultLocale: "zh-CN", }; ``` @@ -31,10 +31,10 @@ If want to modify parameter name of query or cookie ```js // config/config.default.js exports.i18n = { - queryField: 'locale', - cookieField: 'locale', + queryField: "locale", + cookieField: "locale", // Cookie default expired after one year, the unit is ms if set as Number - cookieMaxAge: '1y', + cookieMaxAge: "1y", }; ``` @@ -58,7 +58,7 @@ Example: ```js // config/locale/zh-CN.js module.exports = { - Email: '้‚ฎ็ฎฑ', + Email: "้‚ฎ็ฎฑ", }; ``` @@ -80,7 +80,7 @@ Use `__` (Alias: `gettext`) function to get the multi-language texts under local Take above multi-language configuration as example: ```js -ctx.__('Email'); +ctx.__("Email"); // zh-CN => ้‚ฎ็ฎฑ // en-US => Email ``` @@ -90,10 +90,10 @@ If texts contain format function like `%s`๏ผŒ`%j`, we can call by the way simila ```js // config/locale/zh-CN.js module.exports = { - 'Welcome back, %s!': 'ๆฌข่ฟŽๅ›žๆฅ๏ผŒ%s!', + "Welcome back, %s!": "ๆฌข่ฟŽๅ›žๆฅ๏ผŒ%s!", }; -ctx.__('Welcome back, %s!', 'Shawn'); +ctx.__("Welcome back, %s!", "Shawn"); // zh-CN => ๆฌข่ฟŽๅ›žๆฅ๏ผŒShawn! // en-US => Welcome back, Shawn! ``` @@ -103,10 +103,10 @@ Support array, subscript and placeholder, such as ```js // config/locale/zh-CN.js module.exports = { - 'Hello {0}! My name is {1}.': 'ไฝ ๅฅฝ {0}! ๆˆ‘็š„ๅๅญ—ๅซ {1}ใ€‚', + "Hello {0}! My name is {1}.": "ไฝ ๅฅฝ {0}! ๆˆ‘็š„ๅๅญ—ๅซ {1}ใ€‚", }; -ctx.__('Hello {0}! My name is {1}.', ['foo', 'bar']); +ctx.__("Hello {0}! My name is {1}.", ["foo", "bar"]); // zh-CN => ไฝ ๅฅฝ foo๏ผๆˆ‘็š„ๅๅญ—ๅซ barใ€‚ // en-US => Hello foo! My name is bar. ``` diff --git a/site/docs/core/i18n.zh-CN.md b/site/docs/core/i18n.zh-CN.md index e99cee3fc8..be7abbfe6f 100644 --- a/site/docs/core/i18n.zh-CN.md +++ b/site/docs/core/i18n.zh-CN.md @@ -12,7 +12,7 @@ order: 11 ```js // config/config.default.js exports.i18n = { - defaultLocale: 'zh-CN', + defaultLocale: "zh-CN", }; ``` @@ -29,10 +29,10 @@ exports.i18n = { ```js // config/config.default.js exports.i18n = { - queryField: 'locale', - cookieField: 'locale', + queryField: "locale", + cookieField: "locale", // Cookie ้ป˜่ฎคไธ€ๅนดๅŽ่ฟ‡ๆœŸ, ๅฆ‚ๆžœ่ฎพ็ฝฎไธบ Number๏ผŒๅˆ™ๅ•ไฝไธบ ms - cookieMaxAge: '1y', + cookieMaxAge: "1y", }; ``` @@ -54,7 +54,7 @@ exports.i18n = { ```js // config/locale/zh-CN.js module.exports = { - Email: '้‚ฎ็ฎฑ', + Email: "้‚ฎ็ฎฑ", }; ``` @@ -66,6 +66,7 @@ module.exports = { "Email": "้‚ฎ็ฎฑ" } ``` + ## ่Žทๅ–ๅคš่ฏญ่จ€ๆ–‡ๆœฌ ๆˆ‘ไปฌๅฏไปฅไฝฟ็”จ `__`๏ผˆๅˆซๅ๏ผš`gettext`๏ผ‰ๅ‡ฝๆ•ฐ่Žทๅ– locale ๆ–‡ไปถๅคนไธ‹้ข็š„ๅคš่ฏญ่จ€ๆ–‡ๆœฌใ€‚ @@ -75,7 +76,7 @@ module.exports = { ไปฅไธŠ้ข้…็ฝฎ่ฟ‡็š„ๅคš่ฏญ่จ€ไธบไพ‹๏ผš ```js -ctx.__('Email'); +ctx.__("Email"); // zh-CN => ้‚ฎ็ฎฑ // en-US => Email ``` @@ -85,10 +86,10 @@ ctx.__('Email'); ```js // config/locale/zh-CN.js module.exports = { - 'Welcome back, %s!': 'ๆฌข่ฟŽๅ›žๆฅ๏ผŒ%s๏ผ', + "Welcome back, %s!": "ๆฌข่ฟŽๅ›žๆฅ๏ผŒ%s๏ผ", }; -ctx.__('Welcome back, %s!', 'Shawn'); +ctx.__("Welcome back, %s!", "Shawn"); // zh-CN => ๆฌข่ฟŽๅ›žๆฅ๏ผŒShawn๏ผ // en-US => Welcome back, Shawn! ``` @@ -98,10 +99,10 @@ ctx.__('Welcome back, %s!', 'Shawn'); ```js // config/locale/zh-CN.js module.exports = { - 'Hello {0}! My name is {1}.': 'ไฝ ๅฅฝ {0}๏ผๆˆ‘็š„ๅๅญ—ๅซ {1}ใ€‚', + "Hello {0}! My name is {1}.": "ไฝ ๅฅฝ {0}๏ผๆˆ‘็š„ๅๅญ—ๅซ {1}ใ€‚", }; -ctx.__('Hello {0}! My name is {1}.', ['foo', 'bar']); +ctx.__("Hello {0}! My name is {1}.", ["foo", "bar"]); // zh-CN => ไฝ ๅฅฝ foo๏ผๆˆ‘็š„ๅๅญ—ๅซ barใ€‚ // en-US => Hello foo! My name is bar. ``` @@ -113,10 +114,10 @@ class HomeController extends Controller { async index() { const ctx = this.ctx; ctx.body = { - message: ctx.__('Welcome back, %s!', ctx.user.name), + message: ctx.__("Welcome back, %s!", ctx.user.name), // ๆˆ–่€…ไฝฟ็”จ gettext๏ผŒgettext ๆ˜ฏ `__` ๅ‡ฝๆ•ฐ็š„ๅˆซๅ // message: ctx.gettext('Welcome back', ctx.user.name) - user: ctx.user + user: ctx.user, }; } } diff --git a/site/docs/core/logger.md b/site/docs/core/logger.md index 492c3fba7e..f773f7ab12 100644 --- a/site/docs/core/logger.md +++ b/site/docs/core/logger.md @@ -27,7 +27,7 @@ Change `dir` in logger: ```js // config/config.${env}.js exports.logger = { - dir: '/path/to/your/custom/log/dir', + dir: "/path/to/your/custom/log/dir", }; ``` @@ -48,9 +48,9 @@ module.exports = (appInfo) => { return { logger: { appLogName: `${appInfo.name}-web.log`, - coreLogName: 'egg-web.log', - agentLogName: 'egg-agent.log', - errorLogName: 'common-error.log', + coreLogName: "egg-web.log", + agentLogName: "egg-agent.log", + errorLogName: "common-error.log", }, }; }; @@ -63,19 +63,19 @@ module.exports = (appInfo) => { It's proper to log details in requests with context logger. The logger will append basics about requests to each log. For example, `[$userId/$ip/$traceId/${cost}ms $method $url]`. ```js -ctx.logger.debug('debug info'); -ctx.logger.info('some request data: %j', ctx.request.body); -ctx.logger.warn('WARNING!!!!'); +ctx.logger.debug("debug info"); +ctx.logger.info("some request data: %j", ctx.request.body); +ctx.logger.warn("WARNING!!!!"); // .error will save information in call stack into errorLog file. // Exceptions must be guaranteed to be Error or object extended from Error, which offers a trace of what functions were called. -ctx.logger.error(new Error('whoops')); +ctx.logger.error(new Error("whoops")); ``` For developers who create frameworks or plugins, `ctx.coreLogger` is another option in Context Logger. ```js -ctx.coreLogger.info('info'); +ctx.coreLogger.info("info"); ``` ### App Logger @@ -85,9 +85,9 @@ For developers who want to know more details about dispatch in Egg, they can eas ```js // app.js module.exports = (app) => { - app.logger.debug('debug info'); - app.logger.info('Latency: %d ms', Date.now() - start); - app.logger.warn('warning!'); + app.logger.debug("debug info"); + app.logger.info("Latency: %d ms", Date.now() - start); + app.logger.warn("warning!"); app.logger.error(someErrorObj); }; @@ -98,7 +98,7 @@ module.exports = (app) => { ```js // app.js module.exports = (app) => { - app.coreLogger.info('Latency: %d ms', Date.now() - start); + app.coreLogger.info("Latency: %d ms", Date.now() - start); }; ``` @@ -109,9 +109,9 @@ Agent also supports `agent.coreLogger` as the same feature to context and app ab ```js // agent.js module.exports = (agent) => { - agent.logger.debug('debug info'); - agent.logger.info('Latency: %d ms', Date.now() - start); - agent.logger.warn('warning!'); + agent.logger.debug("debug info"); + agent.logger.info("Latency: %d ms", Date.now() - start); + agent.logger.warn("warning!"); agent.logger.error(someErrorObj); }; @@ -126,7 +126,7 @@ The default encoding setting(`utf-8`) can be changed via `encoding` in config: ```js // config/config.${env}.js exports.logger = { - encoding: 'gbk', + encoding: "gbk", }; ``` @@ -154,7 +154,7 @@ If you want to change logger's default output level, modify in the config as fol ```js // config/config.${env}.js exports.logger = { - level: 'DEBUG', // logs in all level will be written into files + level: "DEBUG", // logs in all level will be written into files }; ``` @@ -163,7 +163,7 @@ Stop writing logs in all levels: ```js // config/config.${env}.js exports.logger = { - level: 'NONE', + level: "NONE", }; ``` @@ -174,7 +174,7 @@ To avoid some plugin's DEBUG logs printing in the production environment causing ```js // config/config.prod.js exports.logger = { - level: 'DEBUG', + level: "DEBUG", allowDebugAtProd: true, }; ``` @@ -192,7 +192,7 @@ Print logs in all levels: ```js // config/config.${env}.js exports.logger = { - consoleLevel: 'DEBUG', + consoleLevel: "DEBUG", }; ``` @@ -201,7 +201,7 @@ Stop printing logs in all levels: ```js // config/config.${env}.js exports.logger = { - consoleLevel: 'NONE', + consoleLevel: "NONE", }; ``` @@ -224,13 +224,13 @@ The logger you create can be declared in config: ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { customLogger: { xxLogger: { - file: path.join(appInfo.root, 'logs/xx.log'), + file: path.join(appInfo.root, "logs/xx.log"), }, }, }; @@ -243,13 +243,13 @@ Now, you can get loggers via `app.getLogger('xxLogger')` or `ctx.getLogger('xxLo ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { customLogger: { xxLogger: { - file: path.join(appInfo.root, 'logs/xx.log'), + file: path.join(appInfo.root, "logs/xx.log"), formatter(meta) { return `[${meta.date}] ${meta.message}`; }, @@ -272,9 +272,9 @@ Transport can be considered as a tunnel to transfer data in Egg. A logger contai For concrete scenario, we take `common-error.log` as an example, which not only printed into files, but also sent to another remote service. At first, we can create a new transport for sending logs to remote: ```js -const co = require('co'); -const util = require('util'); -const Transport = require('egg-logger').Transport; +const co = require("co"); +const util = require("util"); +const Transport = require("egg-logger").Transport; class RemoteErrorTransport extends Transport { // Create log() to upload logs @@ -282,30 +282,22 @@ class RemoteErrorTransport extends Transport { let log; if (args[0] instanceof Error) { const err = args[0]; - log = util.format( - '%s: %s\n%s\npid: %s\n', - err.name, - err.message, - err.stack, - process.pid, - ); + log = util.format("%s: %s\n%s\npid: %s\n", err.name, err.message, err.stack, process.pid); } else { log = util.format(...args); } this.options.app - .curl('http://url/to/remote/error/log/service/logs', { + .curl("http://url/to/remote/error/log/service/logs", { data: log, - method: 'POST', + method: "POST", }) .catch(console.error); } } // Transport attached to errorLogger in app.js, makes logs sync to it once those are created. -app - .getLogger('errorLogger') - .set('remote', new RemoteErrorTransport({ level: 'ERROR', app })); +app.getLogger("errorLogger").set("remote", new RemoteErrorTransport({ level: "ERROR", app })); ``` Performance is what we always consider as important part in our services so that logs will firstly be written into memory and transferred to remote later. @@ -324,14 +316,12 @@ The log file also can be cut into ones by size. For example, Egg will process `e ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { logrotator: { - filesRotateBySize: [ - path.join(appInfo.root, 'logs', appInfo.name, 'egg-web.log'), - ], + filesRotateBySize: [path.join(appInfo.root, "logs", appInfo.name, "egg-web.log")], maxFileSize: 2 * 1024 * 1024 * 1024, }, }; @@ -348,14 +338,12 @@ For example, we need to cut `common-error.log` by hour just like following imple ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { logrotator: { - filesRotateByHour: [ - path.join(appInfo.root, 'logs', appInfo.name, 'common-error.log'), - ], + filesRotateByHour: [path.join(appInfo.root, "logs", appInfo.name, "common-error.log")], }, }; }; diff --git a/site/docs/core/logger.zh-CN.md b/site/docs/core/logger.zh-CN.md index ecd68e4084..23c28163b7 100644 --- a/site/docs/core/logger.zh-CN.md +++ b/site/docs/core/logger.zh-CN.md @@ -27,7 +27,7 @@ order: 4 ```js // config/config.${env}.js exports.logger = { - dir: '/path/to/your/custom/log/dir', + dir: "/path/to/your/custom/log/dir", }; ``` @@ -44,13 +44,13 @@ exports.logger = { ```js // config/config.${env}.js -module.exports = appInfo => { +module.exports = (appInfo) => { return { logger: { appLogName: `${appInfo.name}-web.log`, - coreLogName: 'egg-web.log', - agentLogName: 'egg-agent.log', - errorLogName: 'common-error.log', + coreLogName: "egg-web.log", + agentLogName: "egg-agent.log", + errorLogName: "common-error.log", }, }; }; @@ -65,13 +65,13 @@ module.exports = appInfo => { ๆฏ่กŒๆ—ฅๅฟ—ไผš่‡ชๅŠจ่ฎฐๅฝ•ๅฝ“ๅ‰่ฏทๆฑ‚็š„ไธ€ไบ›ๅŸบๆœฌไฟกๆฏ๏ผŒๅฆ‚ `[$userId/$ip/$traceId/${cost}ms $method $url]`ใ€‚ ```js -ctx.logger.debug('debug info'); -ctx.logger.info('some request data: %j', ctx.request.body); -ctx.logger.warn('่ญฆๅ‘Š๏ผ'); +ctx.logger.debug("debug info"); +ctx.logger.info("some request data: %j", ctx.request.body); +ctx.logger.warn("่ญฆๅ‘Š๏ผ"); // ้”™่ฏฏๆ—ฅๅฟ—่ฎฐๅฝ•๏ผŒ็›ดๆŽฅไผšๅฐ†้”™่ฏฏๆ—ฅๅฟ—็š„ๅฎŒๆ•ดๅ †ๆ ˆไฟกๆฏ่ฎฐๅฝ•ไธ‹ๆฅ๏ผŒๅนถไธ”่พ“ๅ‡บๅˆฐ errorLog ไธญ // ไธบไบ†ไฟ่ฏๅผ‚ๅธธๅฏ่ฟฝ่ธช๏ผŒๅฟ…้กปไฟ่ฏๆ‰€ๆœ‰ๆŠ›ๅ‡บ็š„ๅผ‚ๅธธ้ƒฝๆ˜ฏ Error ็ฑปๅž‹๏ผŒๅ› ไธบๅชๆœ‰ Error ็ฑปๅž‹ๆ‰ไผšๅธฆไธŠๅ †ๆ ˆไฟกๆฏ๏ผŒๅฎšไฝๅˆฐ้—ฎ้ข˜ใ€‚ -ctx.logger.error(new Error('whoops')); +ctx.logger.error(new Error("whoops")); ``` ๅฏนไบŽๆก†ๆžถๅผ€ๅ‘่€…ๅ’Œๆ’ไปถๅผ€ๅ‘่€…๏ผŒ่ฟ˜ๅฏไปฅไฝฟ็”จ `ctx.coreLogger`ใ€‚ @@ -79,7 +79,7 @@ ctx.logger.error(new Error('whoops')); ไพ‹ๅฆ‚๏ผš ```js -ctx.coreLogger.info('info'); +ctx.coreLogger.info("info"); ``` ### App Logger @@ -88,10 +88,10 @@ ctx.coreLogger.info('info'); ```js // app.js -module.exports = app => { - app.logger.debug('debug info'); - app.logger.info('ๅฏๅŠจ่€—ๆ—ถ %d ms', Date.now() - start); - app.logger.warn('่ญฆๅ‘Š๏ผ'); +module.exports = (app) => { + app.logger.debug("debug info"); + app.logger.info("ๅฏๅŠจ่€—ๆ—ถ %d ms", Date.now() - start); + app.logger.warn("่ญฆๅ‘Š๏ผ"); app.logger.error(someErrorObj); }; @@ -101,8 +101,8 @@ module.exports = app => { ```js // app.js -module.exports = app => { - app.coreLogger.info('ๅฏๅŠจ่€—ๆ—ถ %d ms', Date.now() - start); +module.exports = (app) => { + app.coreLogger.info("ๅฏๅŠจ่€—ๆ—ถ %d ms", Date.now() - start); }; ``` @@ -112,16 +112,17 @@ module.exports = app => { ```js // agent.js -module.exports = agent => { - agent.logger.debug('debug info'); - agent.logger.info('ๅฏๅŠจ่€—ๆ—ถ %d ms', Date.now() - start); - agent.logger.warn('่ญฆๅ‘Š๏ผ'); +module.exports = (agent) => { + agent.logger.debug("debug info"); + agent.logger.info("ๅฏๅŠจ่€—ๆ—ถ %d ms", Date.now() - start); + agent.logger.warn("่ญฆๅ‘Š๏ผ"); agent.logger.error(someErrorObj); }; ``` ๅฆ‚้œ€่ฏฆ็ป†ไบ†่งฃ Agent ่ฟ›็จ‹๏ผŒ่ฏทๅ‚่€ƒ[ๅคš่ฟ›็จ‹ๆจกๅž‹](./cluster-and-ipc.md)ใ€‚ + ## ๆ—ฅๅฟ—ๆ–‡ไปถ็ผ–็  ้ป˜่ฎค็ผ–็ ไธบ `utf-8`๏ผŒๅฏ้€š่ฟ‡ไธ‹้ข็š„ๆ–นๅผ่ฟ›่กŒ่ฆ†็›–๏ผš @@ -129,7 +130,7 @@ module.exports = agent => { ```js // config/config.${env}.js exports.logger = { - encoding: 'gbk', + encoding: "gbk", }; ``` @@ -161,7 +162,7 @@ exports.logger = { ```js // config/config.${env}.js exports.logger = { - level: 'DEBUG', + level: "DEBUG", }; ``` @@ -170,7 +171,7 @@ exports.logger = { ```js // config/config.${env}.js exports.logger = { - level: 'NONE', + level: "NONE", }; ``` @@ -181,7 +182,7 @@ exports.logger = { ```js // config/config.prod.js exports.logger = { - level: 'DEBUG', + level: "DEBUG", allowDebugAtProd: true, }; ``` @@ -197,7 +198,7 @@ exports.logger = { ```js // config/config.${env}.js exports.logger = { - consoleLevel: 'DEBUG', + consoleLevel: "DEBUG", }; ``` @@ -206,7 +207,7 @@ exports.logger = { ```js // config/config.${env}.js exports.logger = { - consoleLevel: 'NONE', + consoleLevel: "NONE", }; ``` @@ -218,6 +219,7 @@ exports.logger = { disableConsoleAfterReady: false, }; ``` + ## ่‡ชๅฎšไน‰ๆ—ฅๅฟ— ### ๅขžๅŠ ่‡ชๅฎšไน‰ๆ—ฅๅฟ— @@ -228,15 +230,15 @@ exports.logger = { ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); -module.exports = appInfo => { +module.exports = (appInfo) => { return { customLogger: { xxLogger: { - file: path.join(appInfo.root, 'logs/xx.log') - } - } + file: path.join(appInfo.root, "logs/xx.log"), + }, + }, }; }; ``` @@ -247,21 +249,21 @@ module.exports = appInfo => { ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); -module.exports = appInfo => { +module.exports = (appInfo) => { return { customLogger: { xxLogger: { - file: path.join(appInfo.root, 'logs/xx.log'), + file: path.join(appInfo.root, "logs/xx.log"), formatter(meta) { return `[${meta.date}] ${meta.message}`; }, contextFormatter(meta) { return `[${meta.date}] [${meta.ctx.method} ${meta.ctx.url}] ${meta.message}`; - } - } - } + }, + }, + }, }; }; ``` @@ -273,8 +275,8 @@ module.exports = appInfo => { ้ฆ–ๅ…ˆ๏ผŒๆˆ‘ไปฌๅฎšไน‰ไธ€ไธชๆ—ฅๅฟ—็š„ไผ ่พ“้€š้“๏ผˆtransport๏ผ‰๏ผŒ่ฏฅ้€š้“ไปฃ่กจ็ฌฌไธ‰ๆ–นๆ—ฅๅฟ—ๆœๅŠกใ€‚ ```js -const util = require('util'); -const Transport = require('egg-logger').Transport; +const util = require("util"); +const Transport = require("egg-logger").Transport; class RemoteErrorTransport extends Transport { // ๅฎšไน‰ log ๆ–นๆณ•ใ€‚ๅœจๆญคๆ–นๆณ•ไธญ๏ผŒๅฐ†ๆ—ฅๅฟ—ไธŠๆŠฅ็ป™่ฟœ็ซฏๆœๅŠกใ€‚ @@ -282,30 +284,26 @@ class RemoteErrorTransport extends Transport { let log; if (args[0] instanceof Error) { const err = args[0]; - log = util.format( - '%s: %s\n%s\npid: %s\n', - err.name, - err.message, - err.stack, - process.pid - ); + log = util.format("%s: %s\n%s\npid: %s\n", err.name, err.message, err.stack, process.pid); } else { log = util.format(...args); } - this.options.app.curl('http://url/to/remote/error/log/service/logs', { - data: log, - method: 'POST' - }) - .catch(console.error); + this.options.app + .curl("http://url/to/remote/error/log/service/logs", { + data: log, + method: "POST", + }) + .catch(console.error); } } // ๅœจ app.js ไธญ็ป™ errorLogger ๆทปๅŠ  transport๏ผŒ่ฟ™ๆ ทๆฏๆกๆ—ฅๅฟ—ๅฐฑไผšๅŒๆ—ถๆ‰“ๅฐๅˆฐ่ฟ™ไธช transportใ€‚ -app.getLogger('errorLogger').set('remote', new RemoteErrorTransport({ level: 'ERROR', app })); +app.getLogger("errorLogger").set("remote", new RemoteErrorTransport({ level: "ERROR", app })); ``` ไธŠ่ฟฐไปฃ็ ็คบไพ‹ไธญ๏ผŒ่™ฝ็„ถๆฏ”่พƒ็ฎ€ๅ•๏ผŒไฝ†ๆ˜ฏๅœจๅฎž้™…ไฝฟ็”จๆ—ถ้œ€่ฆ่€ƒ่™‘ๆ€ง่ƒฝ้—ฎ้ข˜ใ€‚้€šๅธธ้‡‡ๅ–ๅ…ˆๆš‚ๅญ˜่‡ณๅ†…ๅญ˜๏ผŒๅ†ๅฎšๆ—ถไธŠไผ ็š„็ญ–็•ฅ๏ผŒไปฅๆญคไผ˜ๅŒ–ๆ€ง่ƒฝใ€‚ + ## ๆ—ฅๅฟ—ๅˆ‡ๅ‰ฒ ไผไธš็บงๆ—ฅๅฟ—ไธ€ไธชๆœ€ๅธธ่ง็š„้œ€ๆฑ‚ไน‹ไธ€ๆ˜ฏๅฏนๆ—ฅๅฟ—่ฟ›่กŒ่‡ชๅŠจๅˆ‡ๅ‰ฒ๏ผŒไปฅๆ–นไพฟ็ฎก็†ใ€‚ๆก†ๆžถๅฏนๆ—ฅๅฟ—ๅˆ‡ๅ‰ฒ็š„ๆ”ฏๆŒ็”ฑ [egg-logrotator](https://github.com/eggjs/egg-logrotator) ๆ’ไปถๆไพ›ใ€‚ @@ -324,14 +322,12 @@ app.getLogger('errorLogger').set('remote', new RemoteErrorTransport({ level: 'ER ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { logrotator: { - filesRotateBySize: [ - path.join(appInfo.root, 'logs', appInfo.name, 'egg-web.log'), - ], + filesRotateBySize: [path.join(appInfo.root, "logs", appInfo.name, "egg-web.log")], maxFileSize: 2 * 1024 * 1024 * 1024, }, }; @@ -348,14 +344,12 @@ module.exports = (appInfo) => { ```js // config/config.${env}.js -const path = require('path'); +const path = require("path"); module.exports = (appInfo) => { return { logrotator: { - filesRotateByHour: [ - path.join(appInfo.root, 'logs', appInfo.name, 'common-error.log'), - ], + filesRotateByHour: [path.join(appInfo.root, "logs", appInfo.name, "common-error.log")], }, }; }; diff --git a/site/docs/core/security.md b/site/docs/core/security.md index b66bf21139..d848cd4578 100644 --- a/site/docs/core/security.md +++ b/site/docs/core/security.md @@ -49,7 +49,7 @@ For example, just open csp when path contains `/example`, you can configure with ```js exports.security = { csp: { - match: '/example', + match: "/example", policy: { //... }, @@ -64,7 +64,7 @@ For example, just disable xframe when path contains `/example` while our pages c ```js exports.security = { csp: { - ignore: '/example', + ignore: "/example", xframe: { //... }, @@ -189,7 +189,7 @@ Note shtml uses a strict whitelisting mechanism, not only filter out the XSS ris For example, tag `HTML` is not in the whitelist. ```js -const html = ''; +const html = ""; // html { @@ -279,11 +279,7 @@ The framework combines these precautions to provide a configurable CSRF preventi In synchronous rendering the page, you should add a parameter name called `_csrf` in the form's submit url, the value is `ctx.csrf`, when user submitting this form , CSRF token will be submitted: ```html -
+ title: file:
@@ -296,8 +292,8 @@ Fields that pass the CSRF token can be changed in the configuration: module.exports = { security: { csrf: { - queryName: '_csrf', // CSRF token parameter name passed through query, default is _csrf - bodyName: '_csrf', // CSRF token parameter name passed through body, default is _csrf + queryName: "_csrf", // CSRF token parameter name passed through query, default is _csrf + bodyName: "_csrf", // CSRF token parameter name passed through body, default is _csrf }, }, }; @@ -312,7 +308,7 @@ In the default configuration, the token is set in the Cookie, which can be fetch In jQuery: ```js -var csrftoken = Cookies.get('csrfToken'); +var csrftoken = Cookies.get("csrfToken"); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection @@ -321,7 +317,7 @@ function csrfSafeMethod(method) { $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { - xhr.setRequestHeader('x-csrf-token', csrftoken); + xhr.setRequestHeader("x-csrf-token", csrftoken); } }, }); @@ -334,7 +330,7 @@ The fields that pass the CSRF token through the header can also be changed in th module.exports = { security: { csrf: { - headerName: 'x-csrf-token', // CSRF token passed through header, default is x-csrf-token + headerName: "x-csrf-token", // CSRF token passed through header, default is x-csrf-token }, }, }; @@ -350,8 +346,8 @@ module.exports = { security: { csrf: { useSession: true, // default is false๏ผŒif set to true , it will store csrf token in Session - cookieName: 'csrfToken', // Field in Cookie , default is csrfToken - sessionName: 'csrfToken', // Filed in Session , default is csrfToken + cookieName: "csrfToken", // Field in Cookie , default is csrfToken + sessionName: "csrfToken", // Filed in Session , default is csrfToken }, }, }; @@ -400,15 +396,15 @@ exports.login = async function (ctx) { Below, we implement a simple TRACE support server based on Koa: ```js -var koa = require('koa'); +var koa = require("koa"); var app = koa(); app.use(async function (ctx, next) { - ctx.cookies.set('a', 1, { httpOnly: true }); - if (ctx.method === 'TRACE') { - var body = ''; + ctx.cookies.set("a", 1, { httpOnly: true }); + if (ctx.method === "TRACE") { + var body = ""; for (header in ctx.headers) { - body += header + ': ' + ctx.headers[header] + '\r\n'; + body += header + ": " + ctx.headers[header] + "\r\n"; } ctx.body = body; } @@ -493,7 +489,7 @@ You need to do the following configuration in the application configuration file ```js // config/config.default.js exports.security = { - domainWhiteList: ['.domain.com'], // security domain while list, start with . + domainWhiteList: [".domain.com"], // security domain while list, start with . }; ``` @@ -635,13 +631,13 @@ Calling the `safeCurl` method directly does not have any effect. It also needs t exports.security = { ssrf: { ipBlackList: [ - '10.0.0.0/8', // support CIDR subnet - '0.0.0.0/32', - '127.0.0.1', // support specific IP address + "10.0.0.0/8", // support CIDR subnet + "0.0.0.0/32", + "127.0.0.1", // support specific IP address ], // ipBlackList does not take effect when checkAddress is configured checkAddress(ip) { - return ip !== '127.0.0.1'; + return ip !== "127.0.0.1"; }, }, }; @@ -671,7 +667,6 @@ For sites that do not open HTTPS, this function can be limited to preventing ISP ## Revert CVE - In the security fixes of node.js, there may be breaking changes. For example, in version 18.9.1, a security vulnerability was fixed, which caused some encryption-related code to not function properly. To address this issue, we provide a revert parameter, which is converted to the --security-revert parameter at startup, allowing the bypassing of the CVE fix. ```json @@ -682,7 +677,7 @@ In the security fixes of node.js, there may be breaking changes. For example, in // One is to use a string directly, specifying a CVE "revert": "CVE-2023-46809", // The other is to use an array of strings, allowing the specification of multiple CVEs - "revert": [ "CVE-2023-46809" ] + "revert": ["CVE-2023-46809"] } } ``` diff --git a/site/docs/core/security.zh-CN.md b/site/docs/core/security.zh-CN.md index 74796e06ff..193666da7c 100644 --- a/site/docs/core/security.zh-CN.md +++ b/site/docs/core/security.zh-CN.md @@ -47,7 +47,7 @@ exports.security = { ```js exports.security = { csp: { - match: '/example', + match: "/example", policy: { // ... }, @@ -60,7 +60,7 @@ exports.security = { ```js exports.security = { csp: { - ignore: '/example', + ignore: "/example", xframe: { // ... }, @@ -82,9 +82,10 @@ exports.security = { ไธ‹้ขๅฐ†้’ˆๅฏนๅ…ทไฝ“็š„ๅœบๆ™ฏ๏ผŒๆฅ่ฎฒ่งฃๅฆ‚ไฝ•ไฝฟ็”จๆก†ๆžถๆไพ›็š„ๅฎ‰ๅ…จๆ–นๆกˆ่ฟ›่กŒ Web ๅฎ‰ๅ…จ้˜ฒ่Œƒใ€‚ --- + ## ๅฎ‰ๅ…จๅจ่ƒ XSS ็š„้˜ฒ่Œƒ -[XSS](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS))๏ผˆCross-Site Scripting๏ผŒ่ทจ็ซ™่„šๆœฌๆ”ปๅ‡ป๏ผ‰ๆ”ปๅ‡ปๆ˜ฏๆœ€ๅธธ่ง็š„ Web ๆ”ปๅ‡ป๏ผŒๅ…ถ้‡็‚นๆ˜ฏโ€œ่ทจๅŸŸโ€ๅ’Œโ€œๅฎขๆˆท็ซฏๆ‰ง่กŒโ€ใ€‚ +[XSS]()๏ผˆCross-Site Scripting๏ผŒ่ทจ็ซ™่„šๆœฌๆ”ปๅ‡ป๏ผ‰ๆ”ปๅ‡ปๆ˜ฏๆœ€ๅธธ่ง็š„ Web ๆ”ปๅ‡ป๏ผŒๅ…ถ้‡็‚นๆ˜ฏโ€œ่ทจๅŸŸโ€ๅ’Œโ€œๅฎขๆˆท็ซฏๆ‰ง่กŒโ€ใ€‚ XSS ๆ”ปๅ‡ปไธ€่ˆฌๅˆ†ไธบไธค็ฑป๏ผš @@ -174,7 +175,7 @@ const value = `google