Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Koa 2.0.0 #533

Closed
jonathanong opened this issue Oct 16, 2015 · 341 comments
Closed

Koa 2.0.0 #533

jonathanong opened this issue Oct 16, 2015 · 341 comments
Milestone

Comments

@jonathanong
Copy link
Member

Roadmap

We do not plan to release v2 as "stable" until async/await hits node.js. Requiring babel to run your server is just not good developer experience. I do this right now, and I run into a host of problems. Writing your middleware with just promises or with co() or Bluebird.coroutine() everywhere isn't a good experience either. The current way to write middleware is ideal until async/await is native.

You can track v8's progress on async functions here: https://bugs.chromium.org/p/v8/issues/detail?id=4483. After v8 implements async functions, it will take some time for that v8 version to hit stable (6 weeks i think, not sure), then more time for that v8 version to hit node stable (i believe they plan to release a major version every 6 months).

Thus, once async functions hit v8, we have between 2-7 months to release Koa v2 as stable, but it'll probably just take us a day since not much other than the middeware signature has changed.

Don't be scared to use Koa v2 Alpha right now, though. People are already using it in production, and we don't foresee any major changes until we mark it stable.

Changes

The new middleware signature is:

// 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!

We don't know how much performance difference there will be, nor do many of the maintainers really care. Koa is as minimal as a framework can be and will not be your app's bottleneck.

New Features

Hopefully, Koa v2 will not have any new features as new features can be added to v1 as well. The only new features that will be added to Koa v2 will be breaking changes. Some possible features are:

Features for HTTP2 support can still go into Koa v1. The only problem is that if it's not in require('http') or require('https'), we're not going to include it in Koa. node-spdy is probably going to be the code that is merged into node.js.

Middleware

All of the current stable versions of middleware should be targeting koa v1. If it doesn't, let us know and we'll fix it.

Middleware may have an "alpha" version of the koa v2 version. These should NOT be marked as stable. If they do not exist, let us know and we'll create an alpha version so you can try it with koa v2. Better yet, make a PR!

Upgrading Middleware

You will have to convert your generators to async functions with the new middleware signature:

app.use(async ctx => {
  const user = await Users.getById(this.session.user_id)
  ctx.body = { message: 'some message' }
})

Upgrading your middleware may be a pain in the ass. 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

We have plans to create a migration bot #625 to make this process slightly better.

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.

I currently use babel and use async functions + flow type outside of koa middleware. this will make my migration path in the future easier. I'm not sure if I plan to ever remove babel though since I really like flow type.

How You Can Help

  • Documentation - we need a lot!
  • Testing Koa v2 and its corresponding middleware
  • Help create the migration bot Migration bot #625

Questions

  • Should we transpile w/ babel before we publish? It might make performance better as it transpiles down to ES5, which V8 is more optimized with. Anyone wanna try benchmarking it?
@jonathanong jonathanong added this to the 2.0.0 milestone Oct 16, 2015
@fengmk2
Copy link
Member

fengmk2 commented Oct 16, 2015

Should let user to do that, not koa itself.

@tejasmanohar
Copy link
Member

@fengmk2 Maybe I'm missing something, but I don't think making the user transpile through Babel here is an adequate solution... wouldn't that require the user to modify what's in node_modules/ (/ fork koa and add babel transpiling in prepublish etc)?

Should we transpile w/ babel before we publish? It might make performance better as it transpiles down to ES5, which V8 is more optimized with. Anyone wanna try benchmarking it?
I think we should transpile for more reasons than performance (though that is a potential one). We can play with even more features this way, and there are quite useful / nice features in Babel that are hidden behind --harmony-x flags or entirely non-existent in Node 4.x.x.

@jonathanong
Copy link
Member Author

yeah you can't expect users to transpile any of their node modules

@tejasmanohar
Copy link
Member

Agreed. Personally, I think we should use Babel. Then, we don't require Node 4.x.x+ either- we just require an ES6 engine to use Koa (not to install / require etc) @jonathanong. Maybe not everyone is using Node 4.x.x because apps using Koa don't have to use a Node version that has any ES6 natively if we transpile, right? They could just be transpiling with Babel (or something else) themselves?

Basically, I think we should allow the user to decide how they want to run their app using our module. If we ship it as is without transpiling, then the user must use Node 4.x.x, but if we transpile and ship, they can use that, Babel, or something else- no restrictions as long as their engine is ES5+ and their application somehow supports ES6 (since generators). That is giving the user options.

But either way, asking users to transpile the module itself if they don't want to use Node 4.x.x isn't really reasonable (asking them to transpile it, that is. just saying only node 4.x.x is suboptimal, imo, but still reasonable).

@yanickrochon
Copy link
Contributor

I personally don't transpile. I can see the benefit, but in most case it just adds overhead for only a little benefit (code readability... which most dev don't need anyhow).

As far as I'm concerned, the 2.0 version should just be 4.x+ compatible, period. Devs can just stick with the 1.x branch for their existing applications. Everything is just fine. One of my project is still using a 0.21.0 version, and I don't see any reason to upgrade it. I started this project back when Node 0.11 was released, been using the --harmony flag then, and still using it with Node 0.12.7 at the moment.

Bottom line is, I don't see why 2.0 should be BC. I sure don't have any problem with it.

@tj
Copy link
Member

tj commented Oct 17, 2015

+1 for 4.x only. To me there's nothing overly compelling enough to really make anyone feel like they have to upgrade if they can't quite yet, just a signature change etc. If the perf thing proves out then maybe that'll be worth it, but still a little weird.

@travisjeffery
Copy link
Member

+1 to 4.x only too. with koa < 1.x people had to run recent/certain versions of node to have generators and that worked out alright/didn't seem to be an issue there.

@chentsulin
Copy link
Contributor

+1 for 4.x only. koa is significant project which using new coming features to achieve great develop experience, so it needs move forward to the next steps.

@tejasmanohar
Copy link
Member

@chentsulin Babel vs Node 4.x.x isn't about being able to use new features or not.

@chentsulin
Copy link
Contributor

@tejasmanohar but support only Node 4.x.x will encourage people to upgrade, not just stay on 0.12. support from 0.x to 4 always be a nightmare to project maintainers. (maybe just like IE 6 ~ 11?)

If I does not use koa one year ago, I will stay on 0.10 for a long time.

@yanickrochon
Copy link
Contributor

@tejasmanohar what @chentsulin said is not really related to the use of Babel or not, but more about if Koa should be BC or not. My take is that, it should not and people should move forward.

That being said and in regards to the use of a transpiler, I don't like all the features in Babel... This is my choice, my opinion. I also do not use any project which are coded in CoffeeScript either. I may be an extremist on this matter, but I really don't like to have dependencies I don't really need nor use in my project. (And I have seen bugs and bad implementations being produced by transpilers that could have been trivial to avoid otherwise.)

My problem with using a transpiler is that it is opiniated. As everyone agree to be Node 4.x+ for version 2.0, all necessary optimizations are already there without using any development flags or a transpiler. As for code readability is concerned, there's not much Babel can add on top of that. Koa is supposed to be lightweight anyway. I haven't seen any valuable objective arguments to justify such dependency.

@tejasmanohar
Copy link
Member

Ah, I see. Yeah, I don't think Koa 2.0 needs to be BC either.

@felixfbecker
Copy link
Contributor

+1 for Node 4.x requirement

@thelinuxlich
Copy link

+1 for Node 4.x requirement!

@cesarandreu
Copy link

+1 for Node 4.x requirement.

Koa only works on node.js anyway, right? So it's not like other engines are at a loss. Any Node 4.x is LTS, so I'd expect people to be able to upgrade sooner or later.

@mike-marcacci
Copy link

I'm all for the node 4.x requirement, but I do have a note about babel compatibility:

I've been using the branch from #533 on a brand-new project over the past week, and I discovered that because it uses native, uncompiled es6, I had to be careful what babel transformers are used on my code. Just as one example, if the "es6.class" transformer is enabled (which isn't necessary in 4.x, but is nonetheless on by default) the Koa class can't be extended by babel-compiled code and throws compile-time errors.

This is really a babel issue if it's an issue at all, and I've opted to explicitly declare my transformations in my package.json to avoid it, but I'm sure others will encounter this use case.

These are my babel configs that work seamlessly with the latest Koa.

...
  "babel": {
    "whitelist": [
      "strict",
      "regenerator",
      "es6.modules",
      "es6.arrowFunctions",
      "es6.destructuring",
      "es6.spread",
      "es7.asyncFunctions"
    ]
  }
...

@yanickrochon
Copy link
Contributor

How is Babel currently being used in Koa? Why is it listed as a devDependency?

@tejasmanohar
Copy link
Member

@yanickrochon I assume it's listed as a dev dependency because you need it (or another transpiler of sorts) to develop on the experimental portion with ES7 async functions and all that jazz. 🎶

That said, doesn't look like it's actually being used to transpile anything in the scripts etc but rather only in usage by a developer. Maybe @jonathanong can shed some light here?

@jonathanong
Copy link
Member Author

oh yeah it was part of the experimental tests. i removed the tests in the async-function branch but not babel yet.

@jonathanong
Copy link
Member Author

also, i'm not changing the stance on the node 4.x compatibility. i just know people care about performance and the usage of es6 features slows performance (due to VM not optimizing yet). using babel to transpile to ES5 may improve performance (as well as being very easy), but i would want to benchmark that before doing that.

@yanickrochon
Copy link
Contributor

Dev for 2.0 doesn't have to have an RC just yet and may as well be a proof of concept. Angular 2.0 has been in alpha for ages... lol... so Koa 2.0 doesn't have to be released next month. At some point, all these new ES6 features will be optimized.

Also, as a thought; is co still relevant, or will still be relevant in 2.0?

@jonathanong
Copy link
Member Author

yeah we'll leave it in for now for function* (ctx, next) {} middleware. i don't see a reason not to unless anyone has objections.

@felixfbecker
Copy link
Contributor

Old middleware will not work anyway and will require koa-convert. I think we should remove co and instead let koa-convert take care of converting legacy, generator-based, context-as-this middleware. Might add performance, but the question should be why should we leave it in if old middleware won't work anyway.

@thelinuxlich
Copy link

Arrow functions are optimized in Node 4

@jonathanong
Copy link
Member Author

should we remove co from koa, guys? this means that all your generator functions should look like this if you don't use babel:

app.use(co.wrap(function* (ctx, next) {
  yield next()
})

we're going to eventually remove co anyways... could be v2 or v3.

@dead-horse
Copy link
Member

remove co after node LTS support async await ?

@tejasmanohar
Copy link
Member

👍 for after Node LTS supports async/await

@felixfbecker
Copy link
Contributor

That's gonna be ages.

@fl0w
Copy link
Contributor

fl0w commented Nov 15, 2016

@sulliwane a v8 version bump may or may not happen, it all depends on breakage. Compatibility comes first, and by default a v8 bump should (though not exclusively) require a node major semver bump as well. v8 v5.5 is scheduled for release in december.

@marvinhagemeister
Copy link

@sulliwane as @fl0w already said. At the time node 7.0.0 was branched, v8 5.5 was not stable.

@ilkkao
Copy link
Contributor

ilkkao commented Nov 15, 2016

nodejs/node#9618 v8 5.5 may happen soon afterall

@stephank
Copy link

So definitely in Node.js 8.x in April, but a backport PR for Node.js 7.x also exists: nodejs/node#11029

Maybe in Node.js 7.5.0? There's currently a proposal PR (without V8 5.5), slated for release February 1st, which is a bit soon: nodejs/node#11062

@pi0
Copy link

pi0 commented Feb 1, 2017

@stephank It seems we have to wait for another 7.x release. 7.5 was released without that... But nodejs/node#11029 is still open :)

@qoh
Copy link

qoh commented Feb 1, 2017

There's a test build of v7.5.0 with V8 5.5 here

nodejs/node#11062 (comment)

@saadq
Copy link
Contributor

saadq commented Feb 3, 2017

According to this tweet, v7.6 might have async/await available without a flag :o

@italoacasas
Copy link

Hi everyone. I'm going to be releasing Node.js 7.6.0 RC next week, with v8 5.5 (async/await)...

@pe8ter
Copy link

pe8ter commented Feb 22, 2017

Node.js 7.6 is out.

Edit: Blog post.

@arden
Copy link

arden commented Feb 22, 2017

when koa2.0 release?
seems, use async/await in 7.6.0, must be open --harmony also. so disappointed.

@ljharb
Copy link
Member

ljharb commented Feb 22, 2017

@arden --harmony is absolutely not required; node in v7.6.0 allows async function foo() {} ; foo; to work just fine.

@PlasmaPower
Copy link
Contributor

Sounds like it's time to make v2 default then. Anything else blocking?

@dead-horse
Copy link
Member

personally, I tend to

  1. Release 2.0.0 in npm officially now, so people can use koa@2 follow the semver.
  2. Keep latest tag point to 1.x, because most people will stick on node LTS(6.x) for now.
  3. Make 2.x default(master in github and latest in npm) when LTS support async fuction.

@fengmk2
Copy link
Member

fengmk2 commented Feb 22, 2017

cc @jonathanong Going to release the 2.0.0 version to npm?

@jaydenseric
Copy link

jaydenseric commented Feb 22, 2017

IMHO if the latest is v2.0.0, tag it so. Semver indicates breaking changes just fine and package.json has engines. Anything else punishes up-to-date node users and creates confusion in docs, etc.

@Talento90
Copy link

Everyone is waiting for the same! Release the BEAST aka (koa v2.0.0)!

@pesho
Copy link

pesho commented Feb 22, 2017

Everyone is waiting for the same! Release the BEAST aka (koa v2.0.0)!

Release the Koaken 🐙

@hulkish
Copy link

hulkish commented Feb 23, 2017

i can't await

@DJviolin
Copy link

I'm happy if I can use Koa v2 today under the @next flag, have it in the master not changes anything for our projects, just have a good feeling that Koa v2 is "out". We shouldn't expect a full release without an updated documentation, which looks like no one doing at the moment. But at this stage, I compromised myself with the markdown docs in the repo. ctx.state yet alone worth the hassle.

Of course, I'm awaiting too!

@benseitz
Copy link

The documentation is automatically imported from the docs in the master branch (except the introduction and the links)

But since on our official homepage the first sentence is

Koa - next generation web framework for node.js

I believe its save to update to Koa 2.0.0. We are the next generation, not the legacy generation :)

@ilkkao
Copy link
Contributor

ilkkao commented Feb 23, 2017

It also feels that some middleware authors struggle to maintain support for 2.0 as a separate non-default branch. It would simplify things if middlewares could just do a new major release and make 2.0 branch as the default.

@jonathanong
Copy link
Member Author

6c6aa4d :)

jonathanong added a commit that referenced this issue Mar 8, 2017
* 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++
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests