Replies: 6 comments 19 replies
-
Thanks for this writeup! 👍 to simple so @babel/register. How about we do this in two stages? We first ship a zero-config option and get it out there and then follow up with a way for people to configure Typescript compilation? That way we prioritize fixing ASAP the most basic problem here of being able to use Typescript for gatsby-* files(which is all most people would want) and then we'll get a lot more community input about I'm not sure I love the idea of compiling Typescript files in plugins. There is a perf hit on startup for each Typescript file so it'd be best to keep this to a minimum. SWC might change that though https://github.com/TypeStrong/ts-node#bundled-swc-integration — benchmarking the cost would be helpful too — but again in the interest of keeping things simple initially, having plugins continue to need a build step seems fine. Almost every plugin in the monorepo here has a build step. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the write-up! What I didn't 100% got was, do you want syntax support or also linting support? The former makes a lot of sense. Gatsbyrc goes a bit to far, I don't believe you'll need to configure custom plugins, ... I'm not a big fan of JIT, it's easy to implement but you don't know what it transpiles to. Every update of the library can give you different results and it's hard to figure out why things went wrong. AOT make sense and isn't that expensive if you look at rollup and it would help us improve our caching layer too, if onCreateWebpackConfig changed, we don't need to throw away the node store, ... |
Beta Was this translation helpful? Give feedback.
-
I'd say, having a choice on the compiler and its options is quite essential. There are many different desires and use cases out there and allowing the user to configure what they need is the only solution to avoid troubles in implementation. From a user point of view, any solution that results in a minimal change is always the best. @Js-Brecht may not recommend, but I actually support the notion of a However, they should be strictly static and serve the purpose of configuring the transpiler only. The best and cleanest implementation should enable user just simply rename Today, I have a tacky way to have all node_modules/.bin/babel-node --presets @babel/preset-env --presets @babel/preset-typescript --extensions '.ts,.tsx' node_modules/.bin/gatsby build It doesn't work on windows, but it does the job for cloud deployment and more importantly on my local machine. |
Beta Was this translation helpful? Give feedback.
-
@Js-Brecht and others in this discussion - Typescript support is something we've prioritized for 2022.Q1, and we're looking for folks that would like to participate. We will have a Gatsby core maintainer focused on this feature, and it'd be great to team with our community members to bring this all to life. @Js-Brecht - are you still up for contributing in this area? |
Beta Was this translation helpful? Give feedback.
-
Hello all 👋 Thanks @Js-Brecht again for your WIP branch. I took the changes and put it into its own branch on our repo: https://github.com/gatsbyjs/gatsby/compare/poc/ts-jit I've published the contents of it under the alpha tag With the help of this RFC I've written an internal tech spec for this project and I plan on writing a new RFC that contains contents from that and how we envision things going forward. We'll want to do AOT compilation for various reasons so I didn't feel like editing this RFC here is appropriate since it suggests JIT. So my plan of action is:
|
Beta Was this translation helpful? Give feedback.
-
The new RFC including a new canary for AOT is out here: #34613 |
Beta Was this translation helpful? Give feedback.
-
Summary
It would be advantageous for Gatsby to provide native Typescript (or simply ES6 support, even) for
gatsby-config
andgatsby-node
through the core. Because of the Gatsby's design, its pluggable nature and the GraphQL source layer, using Typescript ingatsby-config
andgatsby-node
provides a number of advantages, to include:gatsby-config
settingsgatsby-node
.gatsby-node
, which can get quite extensive.The way I see it, this could be done a couple different ways, with increasing levels of difficulty. I would be able to handle the development of this feature, but before I begin, I would like to get some feedback on the following implementation options.
Simple - JIT
The simplest method for implementing Typescript support would be to use an always-on JIT transpiler:
babel-register
. This would guarantee ES6/Typescript support for any files run from node during the build process.This would simply involve starting
babel-register
prior to collecting plugins/themes.babel-preset-gatsby-package
could be used for the majority of cases (with some minor updates). To reduce the impact on performance,babel-register
can be configured to ignore files outside of the directories of the default site and each of its plugins.Caveats
gatsby-config
andgatsby-node
files, there will be a (sometimes) noticeable hang time during startup..babelrc
... which comes with all of its own issues, of course.babel-register
, this entails utilizing Node'srequire.extensions
.require.extensions
is deprecated and has been for some time, but I don't think there's any real plans to get rid of it completely... yet. I also haven't seen any plans for a replacement. This means that JIT transpiling may not be completely future-proof.Complex - AOT
Ahead-of-time transpiling would be a more "future-proof" method, but would increase the complexity of the implementation considerably. To remain compatible with all package managers, the transpiled source modules would need to be dumped into the default site cache. This creates a lot of problems with module scope:
.ts
files would also need to be transpiled and dumped next to the entry file, either in the same folder structure or using some kind of uid with the import changed to matchThese problems will either result in a great deal of limitations, or a prohibitive level of complexity (IMO). Would not recommend this approach.
I would definitely recommend using the JIT method. I have been using it in gatsby-plugin-ts-config for some time now, with excellent results. My first approach was to use AOT, but it started to turn into a "reinventing the wheel" thing so I abandoned it.
While the simple/always-on method will be functional, and I'd be happy to implement it, I feel like there should also be some extensibility/configuration options available to the consumer. I'd like to get some feedback on these, and then see if there is a good way to include them. The only one that I'd like to be decided on before the initial implementation would be the opt-in/out option. Everything else could be added in another iteration.
gatsby-*
files in Typescript/ES6 and signal to the core that they should be transpiled. If they don't, then the transpiler will ignore them.ts-node
instead of locking it in to onlybabel-register
ts-node
is not as performant asbabel-register
, but I feel strongly that it should be up to the consumer whether they want that performance hit in exchange for the added functionality.ts-node
nor Typescript itself need to be shipped with Gatsby. Can simply look for them in the consumer's dependencies to see if the desired run type is supported.babel-register
, this would mean allowing the consumer to add their own presets / plugins / other options to the babel processts-node
, this means allowing them to some additional options for thets-node
process. This like the compiler or the transformers mentioned earlier.This raises a new question: how to include this configuration. I have considered a few methods in order of (IMO) their efficacy:
.gatsbyrc
Because
gatsby-config
should also be.ts
compatible, it doesn't make a lot of sense to configure the bootstrap from it. Instead, perhaps Gatsby's own.rc
file would make sense.Like most other
.rc
files, this would define configurations for the running Gatsby process. In this case, it defines options that are used for configuring the bootstrap process itself, prior to consuminggatsby-config
andgatsby-node
.An alternative to having a
createRcOptions
type function would be to document the usage with a JSDoc. Their sole purpose is to provide types for the configuration, simply to make it easier to set up.gatsby-config
extendsAn alternative configuration method may be to allow
gatsby-config
to "extend" another config file. This way, the initialgatsby-config
could be written in.js
, and "extend" the.ts
one.package.json
configurationThis would involve adding a key to
package.json
for defining initial configurations for Gatsby. I don't recommend this method: since it is a simple.json
file, there will be a lot of things you can't do.opt-out of the transpiler
Include transpiler options
This is where it gets trickier. A lot of configuration options for
babel-register
andts-node
need functions. Can't define functions in.json
.Beta Was this translation helpful? Give feedback.
All reactions