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

Play: Experimenting with TypeScript #13436

Closed
moonmeister opened this issue Apr 18, 2019 · 21 comments
Closed

Play: Experimenting with TypeScript #13436

moonmeister opened this issue Apr 18, 2019 · 21 comments
Assignees
Labels
stale? Issue that may be closed soon due to the original author not responding any more. type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@moonmeister
Copy link
Contributor

Summary

There has been some discussion about making Gatsby easier to contribute to via TypeScript. I've been playing around with this idea in Gatsby and wanted to share what I was doing. I've modified the babel configs and such to make this possible in gatsby core and in plugins.

I'm completely new to typescript so there's somethings I probably don't have correct or haven't figured out yet.

Branch: https://github.com/gatsbyjs/gatsby/tree/typescript

Related:
#10897

@moonmeister moonmeister added type: question or discussion Issue discussing or asking a question about Gatsby Open Play™ labels Apr 18, 2019
@moonmeister moonmeister self-assigned this Apr 18, 2019
@moonmeister
Copy link
Contributor Author

FYI: This could probably be implemented for plugins pretty quickly. IT's a non breaking change...all JS files keep building. Plugins that want to convert could do so at their leisure once the updated babel-plugin-gatsby-packages is released.

One thing I haven't figured out is how to generate type definition files. I think this can be done automatically once .js files are converted to .ts and everything has been typed appropriately.

@wardpeet
Copy link
Contributor

wardpeet commented Apr 18, 2019

My honest opinion is to move to jsdoc + typescript definitions. I think it's easier to grasp than typescript and more js likely. Besides ts & tsx files I feel that typescript doesn't optimize super well for the web as it compiles async await to generators which are polyfilled again with a lot of code. When using js you can choose how to polyfill with babel (unsure if typescript has this support as well now it can be used with babel).

More info can be found here:
https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html
https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript

I don't know how others feel about this.

@moonmeister
Copy link
Contributor Author

@wardpeet How jsdoc and ts definitions work together?

@wardpeet
Copy link
Contributor

hey sorry, I pushed comment a bit to fast 😛

I updated above comment

typescript is able to parse js files and use the jsdoc comments as typing information.

@moonmeister
Copy link
Contributor Author

moonmeister commented Apr 18, 2019

@wardpeet Hey, so checkout how I've modified the babel-plugin-gatsby-packages and gatsby-plugin-manifest I just pushed more updates to them in the last minute. This is still using babel for compilation. It's just removing all the ts. @babel/preset-typescript does this for us. I have converted to using ts/tsx files and included *.d.ts of the plugin.

The one thing I like about using typescript over jsdoc is that comments(i.e. jsdoc) can get out of sync from the code. It's "extra" work. I've added a "check-types" script that runs the typescript compiler and confirms everything is valid. That could be run by CI and git hooks just like linting is.

@wardpeet
Copy link
Contributor

Jsdoc + tsc does exactly that. So they won't get out of sync. I'll create a sample starter to show this of. Also when I'm at my desktop let me dm me my calendly link so we might pair on this 😂 Maybe others are more in favor of using ts so my points might be moot.

@moonmeister
Copy link
Contributor Author

@wardpeet Sweet. I'd love to.

@DSchau
Copy link
Contributor

DSchau commented Apr 18, 2019

@moonmeister just saw this--love the label and so excited to have you working on some of this "fun stuff" (or as you say, Open Play ™️!)

Thanks for working in the open on this! I'm not a huge fan of JSDoc, but interested to hear what your thoughts are re: JSDoc vs. pure TypeScript.

@moonmeister
Copy link
Contributor Author

Okay, @wardpeet and I had a good chat comparing methods. I'm going to try to summarize.

TL;DR

We have three options, 2 that are viable, both have pros/cons. The immediate action item for me (or any one who wants to help) is to create a example of gatsby-plugin-manifest using both viable options and that will get presented in a community meeting in the future for more discussion.

The Options

  • TypeScript - We use the TypeScript compiler, file types, and syntax.
  • TypeScript + Babel - We use the Babel compiler with TS plugin, TS file types, and syntax.
  • JavaScript + JSDoc + TypeScript Definitions - Babel compiler, JS file types, JSDoc syntax in JS files, and TypeSCript Definition files and js doc imports as needed when JSDoc doesn't meet our needs.

TypeScript

The TypeScript compiler is not on par with Babel. Because of things like @babel/env and other controls we can optimize the code output. Because TypeScript doesn't have these options the code would be more bloated and less optimized. This goes against the "Blazing Fast" aspects of gatsby and not tenable.

TypeScript + Babel

Using this method we still get all the benefits of Babel as our compiler and keep benefits of TypeScript as our language and type checker. Project type definitions could be generated for APIs at build time and not manually maintained separate from code.

One concern with this method is we'd be using TS syntax and file types. This has it's benefits but means anyone contributing to Gatsby would be required to learn these things to contribute. It's a potential barrier to entry that needs to be considered.

JavaScript + JSDoc + TypeScript Definitions

This method means keeping JS syntax but adding JSDoc comments for all type definitions. JSDoc isn't as capable as TS but allows importing TS definitions. This means where JSDoc doesn't meet a need we can eject to TS definition files and import those into the JSDoc syntax.

The TS Compiler understands JSDoc and thus is still able to type check the code and require JSDoc notation.

What JSDoc can't do it generate type script definitions for use.

IMO

I think the big trade off between JSDoc and TypeScript is accessibility for contributors. JSDoc does keep JS but you also have to learn JSDoc and probably still TypeScript. Going TypeScript + Babel means just learning TypeScript. No JSDoc. Additionally, IMO TS is easier to learn then JSDoc.

Conclusion

I will work on creating a TS + Babel and a JSDoc version of gatsby-plugin-manifest.

What do you think? Anything I missed in my comparison?

@orta
Copy link
Contributor

orta commented Apr 24, 2019

Yeah, I think babel + ts is probably the right route. I think the main advantages are solid tooling for contributors (which is why we ported jest) as well as being able to provide 1st class type definitions for people using the modules.

Ideally JSDoc annotations should be added anyway, mainly so people get inline docs when working with the API.

Would this allow gatsby-config.ts from a user's perspective also?

@moonmeister
Copy link
Contributor Author

moonmeister commented Apr 24, 2019

@orta Thanks for pointing that out. Using TS + Babel still allows for documentation using JSDoc. Types are just not defined through JSDoc.

Yes, I believe it would allow for gatsby-config.ts.

@orta Are you able to estimate whether people have had more/less troubles contributing since the switch? (i.e. is TypeScript a barrier to entry, or does the developer tooling it enables provide a lower barrier to entry)

@orta
Copy link
Contributor

orta commented Apr 24, 2019

We think there are more first time contributors to jest, but don't really have anything quantifiable - Jest was already very deeply covered by flow, so there already was the types barrier to entry for JS folks.

In most of our projects owe transpile TS via babel, then after use tsc to emit *.d.ts during deploys

@moonmeister
Copy link
Contributor Author

Good to hear. And that is the exact method I want to use for Gatsby.

@moonmeister
Copy link
Contributor Author

@charrondev
Copy link

I think it would be particularly helpful to have IDE assistance and validation when using gatsby APIs in plugins.

I'm trying to do some more complicating things using onCreateNode and createPages but it's like stepping backwards in terms of knowing if I'm doing things properly or not. It's difficult to find the which package a particular method belongs to so I can find it's signature.

I'm going to see if I can get the node debugging protocol setup with VSCode so I can see what I'm working with, but ideally this type of thing would just be autocompleted in the IDE and I could jump to the definition when trying to figure something out.

@charrondev
Copy link

Sorry to make another comment but I'd also love to see how you guys approach setting up a monorepo w/typescript and lerna.

I was trying to break up an existing typescript monorepo in packages with lerna and came away with the conclusion that the tooling would need improvement before our team could move forward with Typescript + Lerna. You might already come across these types of friction due to the size of your repo already though.

The biggest drawbacks were:

  • Typescript requires you to run tsc everytime you check out new code or your IDE will be autocompleting from the old generated type definitions that live on disk (assuming you don't check these build artifacts into git).
  • On top of generated the actual source files you have to generate these extra source map files so that when jumping to definition in your IDE so that it will jump to the resolved original source file location (and not the symlinked one).

The end result being that for every typescript file you have, you need to have 2 extra files in a mirrored structure living on disk, that have to be kept up to date after every checkout.

See this issue for some additional relevant discussion microsoft/TypeScript#25600

It seems the TS team is working on some improvements to these types of issue in their 3.5 release at least.

@orta
Copy link
Contributor

orta commented Apr 28, 2019

I don't feel like we have any of these ^ problems with Jest which is a big Lerna mono-repo in TypeScript

@orta
Copy link
Contributor

orta commented Apr 28, 2019

WRT to the types in end-user code, that's pretty close to happening independent of this PR in here: #13619 (you can see some screenshots of my app which has it set up)

@charrondev
Copy link

That's great to hear! Maybe I should have prefaced this with the fact that the last time I tried this was around typescript 3.1 I think? I don't think jest was typescript at the time either. I'll go give it look, Thanks.

@gatsbot gatsbot bot added the stale? Issue that may be closed soon due to the original author not responding any more. label May 20, 2019
@gatsbot
Copy link

gatsbot bot commented May 20, 2019

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contributefor more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

@gatsbot
Copy link

gatsbot bot commented May 31, 2019

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.

Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale? Issue that may be closed soon due to the original author not responding any more. type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

5 participants