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
73
Readme.md
73
Readme.md
|
@ -44,11 +44,11 @@ app.listen(3000);
|
||||||
|
|
||||||
|
|
||||||
## Middleware
|
## Middleware
|
||||||
|
|
||||||
Koa is a middleware framework that can take 3 different kinds of functions as middleware:
|
Koa is a middleware framework that can take 3 different kinds of functions as middleware:
|
||||||
|
|
||||||
* common function
|
* common function
|
||||||
* async function
|
* async function
|
||||||
* generator function
|
|
||||||
|
|
||||||
Here is an example of logger middleware with each of the different functions:
|
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
|
**Old signature middleware support will be removed in v3**
|
||||||
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 (v1.x) - Deprecated
|
Please see the [Migration Guide](docs/migration.md) for more information on upgrading from v1.x and
|
||||||
|
using v1.x middleware with v2.x.
|
||||||
**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`);
|
|
||||||
}));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Babel setup
|
## 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
|
```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
|
```js
|
||||||
// set babel in entry file
|
require('babel-register');
|
||||||
require('babel-register')({
|
|
||||||
plugins: ['transform-async-to-generator']
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Check out an example in koa's [test](test/babel/index.js).
|
And have your `.babelrc` setup:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"targets": {
|
||||||
|
"node": true
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## 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.
|
the general Koa guide.
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
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)) {
|
if (isGeneratorFunction(fn)) {
|
||||||
deprecate('Support for generators will be removed in v3. ' +
|
deprecate('Support for generators will be removed in v3. ' +
|
||||||
'See the documentation for examples of how to convert old middleware ' +
|
'See the documentation for examples of how to convert old middleware ' +
|
||||||
'https://github.com/koajs/koa/blob/master/Readme.md' +
|
'https://github.com/koajs/koa/blob/master/docs/migration.md');
|
||||||
'#old-signature-middleware-v1x---deprecated');
|
|
||||||
fn = convert(fn);
|
fn = convert(fn);
|
||||||
}
|
}
|
||||||
debug('use %s', fn._name || fn.name || '-');
|
debug('use %s', fn._name || fn.name || '-');
|
||||||
|
|
Loading…
Reference in a new issue