adonisjs / core

AdonisJS is a TypeScript-first web framework for building web apps and API servers. It comes with support for testing, modern tooling, an ecosystem of official packages, and more.
https://adonisjs.com
MIT License
16.97k stars 637 forks source link

Typescript Branch #871

Closed anurbol closed 6 years ago

anurbol commented 6 years ago

Hi there. Recently I've started to push forward typings here: https://github.com/thisdotvoid/adonisjs-types. However, two things bother me: 1) if we use "use" function, we have to make monkey patching adding export{} otherwise TS will throw "cannot redeclare block-scoped variable" . If we use es6 import or require() , then we just lose code completion, because we including .js file. And Typescript's allowJs works bad if .js lives in node_modules. There is so much more to write about this, I've tried so many ways, but none of them is elegant and working at the same time. 2) typings is an additional maintenance overhead - once source changed, typings are obsolete/broken and must be changed too.

After fighting for long hours for few days, for me there is only option that left: source code of Adonis must be written in TS, as files with .ts extension. I,ve already started to try this locally, and it works very well.

Now what I am going to do: fork, transform js extensions to ts, write required ts types, class fields, etc. And write some doc section about typescript. What is important, Adonis will still be usable by those who do not know/use/like typescript.

Now my question: @thetutlage is it ok? What can you say before I start? Hopefully you just say OK, but that OK should mean that you have made thoughtful decision. Thanks

RomainLanz commented 6 years ago

Hi @anurbol 👋

Code-base is currently being rewritten for V5 in TypeScript.

thetutlage commented 6 years ago

@anurbol Seems like you have spent some good time researching on how to add intellisense in AdonisJs. I did same and found that Valid Javascript is Typescript is not 100% true.

I decided to re-write bunch of stuff in Typescript and our reasons can be different. For me Intellisense or atleast VsCode is not important than the ease of using AdonisJs.

What I am not doing

  1. I want, Adonis to work like a charm with Javascript. However, you can opt in to use Typescript.
  2. The standard modules of Node.js should work fine, without any transpilation.
  3. I am not making changes in the public API of Adonis, just to make Typescript happy.

Why I am using Typescript

  1. For automated API docs via Typedoc.
  2. Improve intellisense, if I can without sacrificing the charm of Adonis.
anurbol commented 6 years ago

Thanks for the quick answers! @RomainLanz, that's a good news! However, I failed to find corresponding branch or commits. If it's currently being rewritten, then where it is happening? I mean, is it done locally? Is the job just at the very-very beginning (done locally on your computer), so there is no single commit yet? Or is it now just a stage of discussion, if yes then where (I haven't found one on github and gitter)? Or is everything just in our heads still :D

@thetutlage "I decided to re-write bunch of stuff in Typescript" - Same questions as above, is it just only decision, that exist at the moment? Which is also totally makes me happy, because that decision is key thing, other is matter of time/code. I even tracked your activity, and I noticed you are currently working on Edge template system, using TypeScript though, that's great. If you are going to start re-writing main library, then when it is going to happen? If not soon, can I start it now (in fork), without fear that you or someone already has done some fraction of work (e.g on your computer) and we'd have conflicts? If fork is not acceptable, maybe branch is a way to go (better, because others will see it and participate)?

I totally agree with you on all points, and happy that you push exactly all mentioned by you principles, I just was slightly confused by this sentence, and not sure what you mean: "For me Intellisense or atleast VsCode is not important than the ease of using AdonisJs" - ease of using AdonisJS for me (and maybe others) definitely is a good code completion (intellisense), instead of learning docs/API. I really feel old and tired of hundreds of documentations that I have to read again and again. I want to give you good example of reason of my motivation : I started to migrate my migrations (sorry my wordplay) from Laravel to Adonis. I see, while main principles are the same, there is new API, new method names like notNullable() instead of nullable(false). Reading docs, or even diving into source code is exhausting, I just want to migrate as quick as possible and continue developing business logic. Instead of investigating API/docs, I've installed typings (even in their current, far from perfect realisation) and got code completion, so I quickly (seconds rather than minutes) see that new method is notNullable. Also, chance of mis-typing is next to none, I see which methods are chainable and what they return, etc. My long-term memory and mental capacity freed for business logic and other tasks, which is key for effectiveness. I hope you include this case in concept of "ease of using".

All the other points, I totally agree with them: 1. I want, Adonis to work like a charm with Javascript. However, you can opt in to use Typescript. Yes, only thing that'll change, is that source files would contain not only .js files but also .ts (but .js files would be compiled, non-human-readable)

2. The standard modules of Node.js should work fine, without any transpilation. I see no single reason why they'd break. No transpilation (e.g. babel, webpack, i do not love them frankly) would be used, only TypeScript compilation .ts => .js

3. I am not making changes in the public API of Adonis, just to make Typescript happy. No one single change. Again, I see no reasons why this can happen.

P.S. other 2 cents: I have strong belief, that some deep, incapsulated libraries and classes of main library (adonis/framework) do not need to be rewritten, only those which we use during developing app (e.g. Lucid), at least at the start.

anurbol commented 6 years ago

Found this: https://github.com/adonisjs/discussion/issues/62 but it hardly answered my questions. Please let me start work on TS ASAP, if there is no conflicting current work, because, firstly, I have to migrate fast, and secondly, I do not even want touch things in bare JS (I have physical headaches from it), even despite the fact that code of Adonis is written really, I mean really well (thanks to that, converting it to TS seems easy).

thetutlage commented 6 years ago

@anurbol

Yes, no public work has started with Typescript on AdonisJs. I started with Edge to see how the tooling works and how helpful Typescript will be for the end user.

For me Intellisense or atleast VsCode is not important than the ease of using AdonisJs

By this I mean, Intellisense doesn't work 100% when your project is written in Javascript, even though type definitions exists. For example

const Route = use('Route')

I don't think in a Javascript project, the Intellisense will be able to guest the type of use('Route').

Also what makes Javascript great is it's dynamic nature. So I have to give up all the dynamic stuff, just to make Vscode happy, then ofcourse I am not doing it.

For example: You can add macros to Request and Response classes. The macros are added at runtime

Request.macro('username', function () {
  return this.input('username')
})

and you can use the macro as any other method on the Request object. So again I am not sure if Intellisene will be able to detect username as a method on Request class.

anurbol commented 6 years ago

@thetutlage

I don't think in a Javascript project, the Intellisense will be able to guess the type of use('Route') :D Easy! In fact it already works with https://github.com/anurbol/adonisjs-types/blob/develop/index.d.ts (scroll to the very end and you'll understand how it works) though previous author made it bit over-complexified, below I provide simpler example:

Your example with Request.macro is handle-able with TS same way:

declare class Request {
    static macro(what:'username', callback: () => string) : MacroClassOrWhatever
    static macro(what:'another_thing', callback: () => string) : MacroClassOrWhatever
}

more here: https://www.typescriptlang.org/docs/handbook/functions.html ("Overload" section). declare class is not real class, it is just additional description of existing class.

Those things are exactly why people love TS (I used to hate it too)

anurbol commented 6 years ago

Well, from your answer I concluded that there is no work started. That means I can start it by forking? What you think about creating TypeScript branch? I really want to complete this work in a week. Maybe 2 days if I will have luck. Maybe 2 weeks though, if not. I mean, it should not take so much time, so that many conflicts between branches would arise before finishing. I am not big OSS expert, though, so direct me.

anurbol commented 6 years ago

Well I am starting today anyway. When something will be ready, I'll update status here and request comments.

thetutlage commented 6 years ago

Ohh nice examples. Yeah I am not much into Typescript, so still playing around, getting myself familiar and using it in Edge.

Yes, you can fork any repo you want and I will create a typescript branch and you can create PR against that branch.

anurbol commented 6 years ago

Good! Let's begin :-) I'll try my best: https://github.com/anurbol/adonis-framework/tree/typescript

PazzaVlad commented 6 years ago

Hi everyone

Sorry if I get it wrong, just wanna clear it out: In order to use Adonis v5 we will have to use Typeccript?

thetutlage commented 6 years ago

Nope, it will work as it does right now

anurbol commented 6 years ago

@PazzaVlad no, as thetutlage said absolutely nothing changes in API (no one gonna notice any changes or change how they work), it is only about tooling and code completion for Typescript users

anurbol commented 6 years ago

@thetutlage Hi! Should I make pull requests incrementally after each step completed, or should I make many pull requests at once when everything is ready?

For now, lucid types are ready at that point when you can use migrations with .ts extension, enjoying full code completion, including chained methods. See https://github.com/anurbol/adonis-lucid/commits/ts peek 2018-06-03 15-14 You see, now I don't have to open docs every 2 minutes or learn it. I am absolutely confident that I wrote method correctly without looking to them docs and without executing migrations to ensure that they work.

In the screencast I replaced use() method with import, but it can also be used, though shouldn't (at least in TS workflow), there are some problems with it, I can explain if you want.

What I plan next is: add TS support for routes, controllers and models add docs about enabling and using TS. (quite complex one) add option to generate migrations, controllers, models with TS extension (and corresponding minor syntax differences). I though about this, how to do it the best way: easy for TS users and hidden from JS users, I think TS users should have command e.g. adonis ts:init, which creates config/typescript.ts. That file have something like:

{
  generateTsFilesFor: {
    migrations: true,
    controllers: true,
    models: true,
  }
}

So when user runs e.g. adonis make:model, cli should parse that config and generate files with correct extension.

What do you think (do not forget question at the beginning pls)?

thetutlage commented 6 years ago

@anurbol This looks awesome :)

I believe, we can do it incrementally inside a new branch, so it will be easier to track the changes and also simple for you to work incrementally on it.

I have created a typescript branch in Lucid and framework repo. Feel free to create a PR anytime

anurbol commented 6 years ago

Thanks for the response! Great!!

tiansin commented 6 years ago

@anurbol https://github.com/tiansin/adonis-quick-start-typescript An interim solution, the application code using the typescript to write the code, then use auxiliary definition file to realize automatic. I put all the typescript code in the src directory, the directory structure should be consistent with the application file structure, so the compiled files can link up.

anurbol commented 6 years ago

@tiansin Its a shame that I failed to think of this solution. Great one

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.