-
-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Enables TypeScript Support (instantly) #6550
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
Conversation
Signed-off-by: ashbrener <ashley@starlogik.com>
Codecov Report
@@ Coverage Diff @@
## master #6550 +/- ##
=======================================
Coverage 20.05% 20.05%
=======================================
Files 858 858
Lines 12049 12049
Branches 1951 1951
=======================================
Hits 2416 2416
Misses 8062 8062
Partials 1571 1571
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
|
Hello thank you for your PR. Here are a few comments:
We would just need to update the generators to add a typecript option and add the npm scripts to run strapi develop / start etc. |
|
@alexandrebodin thank you for your comments. As stated in my description above I agree with you that it is not best practise to register Personally I do not like to manually compile with I agree it would be better to require typescript and associated dependencies in the generated projects. Compiling typescript to a dist dir separates (alienates) it from all other code scripts where it could happily coexist. As per my description above if one runs |
|
Alternatively even simpler if we only need to enable TypeScript just include
|
|
@alexandrebodin latest commit has the following changes:
|
|
Hello @ashbrener can you cleanup the example app so it only contains one api and one model ? it would be easier to review and we won't have to maintain two duplicates of the same app |
|
Hi @alexandrebodin are you happy with a separate example app or could it be preferable to simply include a TypeScript API controller in the getstarted project ? |
|
Separate examples are fine and easier to read for the community :) If you can just make it a bit simpler so we don't have to maintain it as we update the main one it would be great |
|
👍 will do @alexandrebodin |
Signed-off-by: ashbrener <ashley@starlogik.com>
|
Hey @ashbrener sorry I don't know what happened but your branch has a lot of commits that should be here. did you pull develop or sth ? |
|
Pulled from master. Revert ? |
Signed-off-by: ashbrener <ashley@starlogik.com>
Signed-off-by: ashbrener <ashley@starlogik.com>
|
@alexandrebodin I have reset and reapplied some of the mods. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
loading files with ts extensions should be only enabled when we run with a specific TS option (can be an env var for ex) to avoid loading ts files when running a compiled app. I would also like to see a way to no use ts-node and build in two different folders as some users to that instead.
We could detect if ts-node is running and augment file extension options if applicable. // Typescript
process.isTypescriptEnabled = !!process[Symbol.for('ts-node.register.instance')];Then, in areas where we load files (eg in filepath-to-prop-path.js) we can augment the file extension regular expression. So this: const prop = cleanPath
.replace(/(\.settings|\.json|\.js)/g, '')
.toLowerCase()
.split('/')
.map(p => _.trimStart(p, '.'))
.join('.')
.split('.');... becomes: const pathRegex = new RegExp(`(\.settings|\.json|\.js${ process.isTypescriptEnabled ? '|\.ts' : '' })`, 'g');
const prop = cleanPath
.replace(pathRegex, '')
.toLowerCase()
.split('/')
.map(p => _.trimStart(p, '.'))
.join('.')
.split('.');The downside of course is that if .ts files are compiled in the same location, both versions will be loaded.
You would then be further abstracting the Strapi file system for api controllers, middleware, hooks, plugins, extensions and so on. I would strongly recommend against. A more popular approach would be to (webpack) compile the entire application and merge it with the admin site build into a single dist output folder. This is obviously a much more complex modification to the entire system. Personally I have created custom build tasks with NX that compile and copy all Strapi project files from |
|
@alexandrebodin what do we still need to do to get this across the line. |
This comment has been minimized.
This comment has been minimized.
Signed-off-by: ashbrener <ashley@starlogik.com>
|
Hi @ashbrener I'm not sure I understood your comment on different folders as you are mentionning at the end that you do build your code into a Right now I'm still not happy with seeing .ts everywhere in the loading. system... I think we should change this somehow so it is cleaner. A ts user could add the 'ts' extension to the config and update the yarn develop command to load the extension. Maybe sth like
module.exports = () => ({
loader: {
extensions: ['js', 'json', 'ts']
}
})Then you can enable it in dev or prod or whatever and just add the ts-register to the bootstrap file or in the npm scripts 🤔 What do you think @ashbrener ? |
|
Hi @alexandrebodin, to clarify I have incorporated our Strapi project as 1 of many apps inside a broader Monorepo project constructed using Nx by @Nrwl. The Nx framework uses a series of "builders" to compile all monorepo apps to a single As you so astutely mentioned earlier in the the thread, one ideally needs to compile the Typescript to an output folder. So we achieve this in our build workflow by compiling (transpile all Great idea being able to configure allowable file extensions, that would work well. |
|
@alexandrebodin where to from here ? |
Guys we would really like to help you and the community get this over the line. Kindly guide us. |
|
@ashbrener Alex is currently out on vacation and we have been quite busy at the moment. We will let you know if we need anything else. Thank you. |
|
Hi @ashbrener, I think that implementing that With that we could have a good enough support for now. And start thinking at what is next for the next major versions |
|
Hi @ashbrener any update about this feature ? |
|
I will have a look at extensions in due course when we have some s p a c e. In the interim, anyone who wants to have a crack at it ... feel free :) |
|
Hey @ashbrener Nice to see you back here :D FYI @ascension did try some of this implementation but has be inactivte :) You can check this PR here #7803. |
|
This pull request has been mentioned on Strapi Community. There might be relevant details there: https://forum.strapi.io/t/strapi-integration-with-other-typescript-aplications-in-a-monorepo/1104/2 |
|
Closing in favor of #9076. |
Description of what you did:
TypeScript support for Strapi has long been a critical success factor for many in this community.
It is clear why there have been heated discussions about this across several forums, and understood why the idea of retrofitting TypeScript support through the Strapi core make a lot of us nervous, especially those who are not familiar or do not have an appreciation of TypeScript.
With that being said, we do not have to overthink a solution to this and hopefully the approval of this PR will solve 90% of the TypeScript use cases out there.
Personally, I do not need any of the generated code (controllers, models etc) to be ported in TypeScript.
I steer clear of making any manual edits to these files.
Approach
I have endeavored to touch the Core as little as possible.
I do not yet have clarity on how best to approach testing, and will obviously leave documentation until the PR is approved as time is precious.
Issues this PR addresses:
TypeScript Compilation Options
There are 2 ways to enable TypeScript in a project:
--typescriptflag to the strapi CLI command egThis method registers ts-node support under the hood and is usually preferably suited for running in development mode.
This method outputs the transpiled Javascript and source maps alongside their TypeScript parent source file.
Conceptually it is not best practise to use
ts-nodein production as there is a concern of a slight performance impact.However in my experience if there is, it is unnoticeable.
Further, I prefer not retaining the transpiled files in my project.
TypeScript Example Project
I have been careful to limit injection of TypeScript specific code in the overall project, and so for now have not made changes to the get started example project.
I have created a new example project to show example usage.
Namely:
API Controller
Bootstrap
Plugin Extension
Hook
Middleware
Core Changes
New Dependencies
I am curious why the Strapi project has no
devDependenciesinpackage.jsonwhich would be the preferred reference for the TypeScript dependencies.However I have followed protocol by adding the following to
dependencies:typescript, ts-node and tsconfig-paths
TypeScript file support
I have added support for requiring .ts file extensions (for ts-node) which provides support for the following:
CLI
Addition of a new typescript flag
packages/strapi/bin/strapi.js
packages/strapi/lib/commands/start.js
packages/strapi/bin/strapi.js
packages/strapi/lib/commands/develop.js
Type Declarations
It may not be necessary (or practical) to describe the entire shape of the Strapi object instance.
The previous version left a ton of room for improvement, and I have had good shot at it though it may need expansion, and possibly some reduction as well.
index.d.ts
New Project Generator
Addition of 2 new files to a new base project:
tsconfig.json
Strapi object instance global namespace support
Conclusion
I have implemented a marvelously simple solution here and hoping I get support here.
All comments and contributions welcome, I look forward to helping the community accelerate this process and have it included in the core as quickly as possible.