knockout / knockout

Knockout makes it easier to create rich, responsive UIs with JavaScript
http://knockoutjs.com/
Other
10.48k stars 1.51k forks source link

Sourcecode in TypeScript #2067

Open SergioMorchon opened 8 years ago

SergioMorchon commented 8 years ago

Hi all!

I've been using Knockout for many years, and participated with its definitely typed definition files. Nowdays that TypeScript supports a mixed JS/TS project, why not use it? It will allow use the cutting-edge syntax and then transpile it down to ES3. Gradually! You can go file by file, under demmand, migrating the Knockout sources, coexisting both current javascript files with the newer typescript ones.

And this could help the project itself, you know... typescript.

I've made a pull request here: https://github.com/knockout/knockout/pull/2068.

As you can see, it's pretty simple and still passes all the tests.

What do you think about it?

IanYates commented 8 years ago

Clever thoughts :) I love using Typescript with Knockout. Might be a bit tricky in some spots as the code has been written with minification in mind, which leads to the debug build not being quite the same as the production (minified) build.

SergioMorchon commented 8 years ago

I feel this kind of changes pretty necessary. Nowadays the source code is written with the edge syntax and features, and delegates de compatibility to polyfills. Ans even more, with typescript we could scale up knockout! More agile, predictable, stable, self-documented... I love this library for it's simplicity and power (components!), and I'd like to revamp it. Starting by removing the creepy google closure complier xD

brianmhunt commented 8 years ago

@SergioMorchon You might be interested in https://github.com/knockout/tko – it's still nascent, but a candidate for KO 4.0. It's not TS, but is modularized into ES6/imports so that things like TS will be easier (trivial) to integrate in the future.

far-blue commented 8 years ago

Just to add my thoughts: I know the majority of the JS community seems very pro transpiling and polyfills but actually these approaches do have significant downsides as well. Polyfills make consistent performance across browsers problematic and transpiling makes performance optimisation and tuning much harder. Overall, the combination of the two also, in my experience, adds barriers to debugging. In an open-source environment where KO's "competitors" include lightweight options like React and heavyweight options like Angular I think KO sits in a good place and moving to rely on polyfills and switching to typescript could shift the relative position of KO in the space of solutions, to its disadvantage.

jlaustill commented 8 years ago

I'd also like to add my thoughts. I think it adds another barrier to entry for developers. Without REALLY good benefits, I don't see it outweighing the negatives. One of the big reasons I left angular and came back to KO was because KO is just easier to get into and doesn't transpile.

I say stick with Brian's tko, it looks like he's trying really hard to stick with standards and ES6. I think that is a GREAT roadmap for the future...

IanYates commented 8 years ago

Good points here.

TypeScript mainly adds a good degree of documentation (via types) and helps avoid the boneheaded errors. I guess I come from a statically typed background and enjoy writing code where the compiler and I are working to support each other. TypeScript is nowhere near as dogmatic as a typical statically typed language - the types are purely there for design-time purposes and don't themselves influence the output.
Using TypeScript for view model code takes away 99% of the thinking to do with "is this observable" and so on since the types flow quite well. Lambda syntax for functions (which any ES6 transpiler would give) makes definitions of computed observables really slick :)

If KO did start including some TS in its source, the shipped code for end-users of KO to use is still a JS file. End users could be blissfully unware. KO currently uses the closure compiler which, IMH (and possibly unknowingly uninformed admittedly) opinion, is a bigger barrier for devs to just jump into than TypeScript if they wanted to contribute to KO.

TKO does seem like a great idea. I've already starred the repo as a result of this thread.

far-blue commented 8 years ago

I've looked into using Typescript myself and it does have a number of nice features and I do think it would be sensible for the KO project to supply the definitions (or whatever they are called) for TypeScript. I've experience with both statically typed and dynamically typed languages and personally prefer the flexibility of PHP, Javascript etc. but I think this is always going to be a personal choice. The biggest thing to put me off TypeScript is the need to compile after code change. Dart at least had dev support directly in Chrome. What I'm not keen on, however, is the extra barriers to debugging caused by transpiling. I've already had issues with Closure Compiler and, with other projects, CoffeeScript, because there is a layer of magic you need to treat like a black box and associating stack trace javascript back to the original TypeScript or CoffeeScript etc. can be tricky.

Also mentioned alongside TypeScript was the use of Polyfills. While I can see their benefits if you want to use the 'new shiny' immediately, I've found in the end many of them introduce their own issues. Even with something as 'simple' as polyfilling Promises - one of the most fantastic new ES additions everyone should adopt - I've had all sorts of headaches across browsers. In the end I've had to switch to using Bluebird for all browsers because the mix of partial native implementations and polyfills for older browsers introduced all sorts of weird edge cases where Promises were fulfilled in different orders or at different times etc. I think with a framework like KO the need for polyfills should be kept to a minimum not only to make life easier for end users of KO but also those trying to debug edge cases and fix bugs.

Of course, you don't need to switch to TypeKit and polyfills to improve areas like documentation; Doc-Block comments for self-documentation are almost universally standard. I'd suggest this would be a good idea whether switching to TypeScript or not. The developers might also consider a coding style checker as well if they've not already got one. Both these would make the code easier to work with.

One word of caution I would give with TypeScript is that since KO has existed there's been a few of these languages - I've already mentioned Dart and CoffeeScript - but in the end most javascript developers are still actual javascript developers rather than Dart or CoffeeScript or TypeScript developers. If you want pull requests and feature contributions from the community you might find less of them if you move to a less well-known language. I know a lot of people value KO because it is basically 'just javascript' unlike, for instance, Angular.

SergioMorchon commented 8 years ago

Only to clarify the idea. First, what I'm NOT talking about:

And now, the main idea:

Also you can generate .map files, to hep debugging.

The result is:

jlaustill commented 8 years ago

It sounds to me like you just want angular2? I strongly dislike this idea. I'm a full stack developer, Microsoft certified c# developer. I understand the desire for a statically typed language, but Transpiling is just adding a layer of complication that isn't needed here.

ES6 addresses most of these things, that's why Brian is doing tko. Someday browsers will fully support it. I'll be contributing with him and his project, sorry.

far-blue commented 8 years ago

Don't forget KO currently supports older browsers such as IE9. It would not be possible to use TypeScript and generate IE9-compatible code without transpiling.

IanYates commented 8 years ago

Fair points here, and every point of view is quite valid.
Nit pick: Just because Angular 2 is using TS doesn't mean someone wanting to try to bring TS to KO is suddenly "wanting Angular 2". I certainly don't. I was using TS quite happily well before Angular 2 was even a thing, as were many other devs. I'm very happy they're using TS but it has no real bearing on this discussion.

As for the need for build or compilation. I don't use grunt, gulp or anything else. There's no real build step for me. I edit my .ts file. Hit save. A .js file comes out beside it. I originally got my .ts files by simply renaming the .js files to .ts and adding types where I felt they'd help. If I wanted to ditch TS I'd just delete the .ts files and I'd have idiomatic Javascript left behind. If I was transpiling things like classes and lambda to ES5 then I have different looking Javascript from what I'd get if TypeScript was putting out ES6. I do let it transpile down to ES5 - there's even an option for ES3 if that was desired.

TS has nothing to do with promises. There is async/await coming in the future, which will be very handy, but .then(result=>{}, failure=>{}) isn't too big a deal to use either.

Source maps are made. I don't use them - I find it nicer to just read the plain JS in the browser as it's pretty close to the TS anyway. The differences are that classes become IIFE's and lamdbas get expanded to function.

Someone checking out my published site code wouldn't even realise it's written with TS. For me TS is all about developer productivity. Contributing to KO would be easier as TS, unlike the other languages (Dart, etc) is at least just Javascript with optional type annotations. It's not going anywhere (famous last words...) given it's pretty core to how MS writes many of its web properties plus VS Code, as well as the Angular team depending on it.

Yes you can have build pipelines that take your TS, use ES6 module loading, wrap it all up, etc. That's not necessary though, and the TS team has strictly adhered to the principle that a TS file can be compiled on its own to produce JS and its output wouldn't be influenced by the presence of other TS or JS files. That makes it quite easy to grok and leaves packaging, if you even want it, up to you.

Anyway, whilst this is a great discussion, it's not going to affect KO directly anytime soon. @brianmhunt 's TKO, if it's relying on ES6 (and transpilation / assembly via rollup - not used it before?), could perhaps rely on TS in future if he wished. I could see that being great from the refactoring point of view.

However, as someone whose use of KO is 99.9% consumption with the occasional foray into reading KO's source, I'm pretty happy with the typescript definitions available at definitely typed plus a few tweaks I made to them (I should get around to contributing them back).

Eisenspalter commented 8 years ago

I love to use Knockout and Typescript together. And it would be great to have a Knockout source code written in Typescript. This give you an easy ability to extend Knockout with to killer features:

  1. Typed templates(jsx technology)
  2. Decorators(Validation, Logging) This would be really really really amazing and gives you a perfect workflow to develop SPA's or Framework's.
IanYates commented 8 years ago

Both of which are end-user (a developer consuming KO) features that don't strictly require the KO source to be in Typescript. Having KO source in Typescript though would at least make these more of a first-class citizen or more front-of-mind when writing KO itself :)

I've been giving some though to point 1 - typed templates/JSX - for the past couple of months. It would be a killer feature. It'd require something like the class-based binding done by @rniemeyer (you can create your bindings as an object) and each binding handler to have some type definitions made. Additionally, things that shimmed the binding context would need to be documented via type definitions too. A lot of that is automatic and implicit unfortunately (although it's part of what makes KO easy to use) so an 80% solution isn't too hard to achieve (relatively) but a 100% accurate solution is probably out of the question. When TS settles down (post 2.0 release), and I get some spare time I was going to give the JSX side of things a try and see how much can be reasonably achieved with KO as-is today.

Eisenspalter commented 8 years ago

React and mobX offers all the nice features I missed in knockout: