docs: create v2 Migration document (#931)
* Give v2 migration documentation its own document. Incorporate docs from #533 * Fix mis-capitalization of Koa * Remove unnecessary Dependency section * Hint at koa-convert enabled compatibility * Add section on constructing with new * Clarify es6 constructors are used * Fix varying capitalization * Restore mistakenly removed Dependency changes section * v1.x should not receive feature updates * Add next() to signature, add missing backticks * docs++
This commit is contained in:
parent
e9d7abaf79
commit
e812339033
3 changed files with 159 additions and 50 deletions
71
Readme.md
71
Readme.md
|
@ -44,11 +44,11 @@ app.listen(3000);
|
|||
|
||||
|
||||
## Middleware
|
||||
|
||||
Koa is a middleware framework that can take 3 different kinds of functions as middleware:
|
||||
|
||||
* common function
|
||||
* async function
|
||||
* generator function
|
||||
|
||||
Here is an example of logger middleware with each of the different functions:
|
||||
|
||||
|
@ -78,65 +78,42 @@ app.use((ctx, next) => {
|
|||
});
|
||||
```
|
||||
|
||||
### GeneratorFunction
|
||||
### Koa v1.x Middleware Signature
|
||||
|
||||
To use generator functions, you must use a wrapper such as [co](https://github.com/tj/co) that is no longer supplied with Koa.
|
||||
The middleware signature changed between v1.x and v2.x. The older signature is deprecated.
|
||||
|
||||
```js
|
||||
app.use(co.wrap(function *(ctx, next) {
|
||||
const start = new Date();
|
||||
yield next();
|
||||
const ms = new Date() - start;
|
||||
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
|
||||
}));
|
||||
```
|
||||
**Old signature middleware support will be removed in v3**
|
||||
|
||||
### Old signature middleware (v1.x) - Deprecated
|
||||
|
||||
**Old signature middleware (v1.x) support will be removed in v3**
|
||||
|
||||
Koa v2.x will try to convert legacy signature, generator middleware on `app.use`, using [koa-convert](https://github.com/koajs/convert).
|
||||
It is however recommended that you choose to migrate all v1.x middleware as soon as possible.
|
||||
|
||||
```js
|
||||
// Koa will convert
|
||||
app.use(function *(next) {
|
||||
const start = new Date();
|
||||
yield next;
|
||||
const ms = new Date() - start;
|
||||
console.log(`${this.method} ${this.url} - ${ms}ms`);
|
||||
});
|
||||
```
|
||||
|
||||
You could do it manually as well, in which case Koa will not convert.
|
||||
|
||||
```js
|
||||
const convert = require('koa-convert');
|
||||
|
||||
app.use(convert(function *(next) {
|
||||
const start = new Date();
|
||||
yield next;
|
||||
const ms = new Date() - start;
|
||||
console.log(`${this.method} ${this.url} - ${ms}ms`);
|
||||
}));
|
||||
```
|
||||
Please see the [Migration Guide](docs/migration.md) for more information on upgrading from v1.x and
|
||||
using v1.x middleware with v2.x.
|
||||
|
||||
## Babel setup
|
||||
|
||||
For Node 4.0+ and Babel 6.0 you can setup like this:
|
||||
If you're not using `node v7.6+`, we recommend setting up `babel` with [`babel-preset-env`](https://github.com/babel/babel-preset-env):
|
||||
|
||||
```bash
|
||||
$ npm install babel-register babel-plugin-transform-async-to-generator --save
|
||||
$ npm install babel-register babel-preset-env --save
|
||||
```
|
||||
|
||||
Setup `babel-register` in your entry file:
|
||||
|
||||
```js
|
||||
// set babel in entry file
|
||||
require('babel-register')({
|
||||
plugins: ['transform-async-to-generator']
|
||||
});
|
||||
require('babel-register');
|
||||
```
|
||||
|
||||
Check out an example in koa's [test](test/babel/index.js).
|
||||
And have your `.babelrc` setup:
|
||||
|
||||
```json
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"targets": {
|
||||
"node": true
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
|
133
docs/migration.md
Normal file
133
docs/migration.md
Normal file
|
@ -0,0 +1,133 @@
|
|||
# Migrating from Koa v1.x to v2.x
|
||||
|
||||
## New middleware signature
|
||||
|
||||
Koa v2 introduces a new signature for middleware.
|
||||
|
||||
**Old signature middleware (v1.x) support will be removed in v3**
|
||||
|
||||
The new middleware signature is:
|
||||
|
||||
```js
|
||||
// uses async arrow functions
|
||||
app.use(async (ctx, next) => {
|
||||
try {
|
||||
await next() // next is now a function
|
||||
} catch (err) {
|
||||
ctx.body = { message: err.message }
|
||||
ctx.status = err.status || 500
|
||||
}
|
||||
})
|
||||
|
||||
app.use(async ctx => {
|
||||
const user = await User.getById(this.session.userid) // await instead of yield
|
||||
ctx.body = user // ctx instead of this
|
||||
})
|
||||
```
|
||||
|
||||
You don't have to use asynchronous functions - you just have to pass a function that returns a promise.
|
||||
A regular function that returns a promise works too!
|
||||
|
||||
The signature has changed to pass `Context` via an explicit parameter, `ctx` above, instead of via
|
||||
`this`. The context passing change makes koa more compatible with es6 arrow functions, which capture `this`.
|
||||
|
||||
## Using v1.x Middleware in v2.x
|
||||
|
||||
Koa v2.x will try to convert legacy signature, generator middleware on `app.use`, using [koa-convert](https://github.com/koajs/convert).
|
||||
It is however recommended that you choose to migrate all v1.x middleware as soon as possible.
|
||||
|
||||
```js
|
||||
// Koa will convert
|
||||
app.use(function *(next) {
|
||||
const start = new Date();
|
||||
yield next;
|
||||
const ms = new Date() - start;
|
||||
console.log(`${this.method} ${this.url} - ${ms}ms`);
|
||||
});
|
||||
```
|
||||
|
||||
You could do it manually as well, in which case Koa will not convert.
|
||||
|
||||
```js
|
||||
const convert = require('koa-convert');
|
||||
|
||||
app.use(convert(function *(next) {
|
||||
const start = new Date();
|
||||
yield next;
|
||||
const ms = new Date() - start;
|
||||
console.log(`${this.method} ${this.url} - ${ms}ms`);
|
||||
}));
|
||||
```
|
||||
|
||||
## Upgrading middleware
|
||||
|
||||
You will have to convert your generators to async functions with the new middleware signature:
|
||||
|
||||
```js
|
||||
app.use(async ctx => {
|
||||
const user = await Users.getById(this.session.user_id);
|
||||
await next();
|
||||
ctx.body = { message: 'some message' };
|
||||
})
|
||||
```
|
||||
|
||||
Upgrading your middleware may require some work. One migration path is to update them one-by-one.
|
||||
|
||||
1. Wrap all your current middleware in `koa-convert`
|
||||
2. Test
|
||||
3. `npm outdated` to see which koa middleware is outdated
|
||||
4. Update one outdated middleware, remove using `koa-convert`
|
||||
5. Test
|
||||
6. Repeat steps 3-5 until you're done
|
||||
|
||||
|
||||
## Updating your code
|
||||
|
||||
You should start refactoring your code now to ease migrating to Koa v2:
|
||||
|
||||
- Return promises everywhere!
|
||||
- Do not use `yield*`
|
||||
- Do not use `yield {}` or `yield []`.
|
||||
- Convert `yield []` into `yield Promise.all([])`
|
||||
- Convert `yield {}` into `yield Bluebird.props({})`
|
||||
|
||||
You could also refactor your logic outside of Koa middleware functions. Create functions like
|
||||
`function* someLogic(ctx) {}` and call it in your middleware as
|
||||
`const result = yield someLogic(this)`.
|
||||
Not using `this` will help migrations to the new middleware signature, which does not use `this`.
|
||||
|
||||
## Application object constructor requires new
|
||||
|
||||
In v1.x, the Application constructor function could be called directly, without `new` to
|
||||
instantiate an instance of an application. For example:
|
||||
|
||||
```js
|
||||
var koa = require('koa');
|
||||
var app = module.exports = koa();
|
||||
```
|
||||
|
||||
v2.x uses es6 classes which require the `new` keyword to be used.
|
||||
|
||||
```js
|
||||
var koa = require('koa');
|
||||
var app = module.exports = new koa();
|
||||
```
|
||||
|
||||
## ENV specific logging behavior removed
|
||||
|
||||
An explicit check for the `test` environment was removed from error handling.
|
||||
|
||||
## Dependency changes
|
||||
|
||||
- [co](https://github.com/tj/co) is no longer bundled with Koa. Require or import it directly.
|
||||
- [composition](https://github.com/thenables/composition) is no longer used and deprecated.
|
||||
|
||||
## v1.x support
|
||||
|
||||
The v1.x branch is still supported but should not receive feature updates. Except for this migration
|
||||
guide, documentation will target the latest version.
|
||||
|
||||
## Help out
|
||||
|
||||
If you encounter migration related issues not covered by this migration guide, please consider
|
||||
submitting a documentation pull request.
|
|
@ -107,8 +107,7 @@ module.exports = class Application extends Emitter {
|
|||
if (isGeneratorFunction(fn)) {
|
||||
deprecate('Support for generators will be removed in v3. ' +
|
||||
'See the documentation for examples of how to convert old middleware ' +
|
||||
'https://github.com/koajs/koa/blob/master/Readme.md' +
|
||||
'#old-signature-middleware-v1x---deprecated');
|
||||
'https://github.com/koajs/koa/blob/master/docs/migration.md');
|
||||
fn = convert(fn);
|
||||
}
|
||||
debug('use %s', fn._name || fn.name || '-');
|
||||
|
|
Loading…
Reference in a new issue