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:
jongleberry 2017-03-07 22:59:42 -08:00 committed by GitHub
parent e9d7abaf79
commit e812339033
3 changed files with 159 additions and 50 deletions

View file

@ -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,69 +78,46 @@ 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
Check the [Troubleshooting Guide](docs/troubleshooting.md) or [Debugging Koa](docs/guide.md#debugging-koa) in
Check the [Troubleshooting Guide](docs/troubleshooting.md) or [Debugging Koa](docs/guide.md#debugging-koa) in
the general Koa guide.
## Running tests

133
docs/migration.md Normal file
View 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.

View file

@ -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 || '-');