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

Typescript-lite - minimal conversion to Typescript #33

Merged
merged 8 commits into from
Feb 8, 2020

Conversation

rossknudsen
Copy link
Contributor

This is another attempt at converting to TS. This time, a minimal approach was taken since the previous attempt was too large to review. Since Babel can translate JS with Flow as well as Typescript, this works well (pretty sure the TS compiler doesn't understand Flow). So the changes are mostly to configuration files with a single example JS file converted to TS as a proof of concept (/src/index.js => /src/index.ts).

Inclusion of a .gitattributes file and changing single quotes to double quotes in the package.json scripts was introduced to help with Windows compatibility.

package.json Outdated Show resolved Hide resolved
Copy link
Member

@stephtr stephtr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it looks good.

Copy link
Collaborator

@connectdotz connectdotz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, @rossknudsen for adopting the incremental approach. I do see the potential complexity of living in flow and typescript worlds simultaneously, but I guess that is what we agree as a trade-off for the massive one-time conversion...

This incremental approach made it easier to get the typescript tooling right. I have added a few comments, let's discuss and see if we can establish a solid starting point.

.eslintrc.js Outdated
@@ -16,7 +16,7 @@ module.exports = {
},
plugins: ['flowtype', 'prettier'],
rules: {
'prettier/prettier': 'error',
'prettier/prettier': 'off', // disabled temporarily to prevent un-necessary delta in conversion to TS.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My vote is to keep this unchanged ('error'), as long as we keep our change progressive, I'd rather live with the whitespace diff (which we could probably turn off during diffing) than inconsistent coding style.

I didn't see any typescript specific support (@typescript-eslint/xxx). Should we add those? Not sure if it can live in the same config with "flow", worst case separate config?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My vote is to keep this unchanged ('error'), as long as we keep our change progressive, I'd rather live with the whitespace diff (which we could probably turn off during diffing) than inconsistent coding style.

May I suggest that we keep it 'off' in this MR and follow-up with a "quick" whitespace-only MR that'll be an almost automatic approval?


I didn't see any typescript specific support (@typescript-eslint/xxx). Should we add those? Not sure if it can live in the same config with "flow", worst case separate config?

👍 It's a small repo. Should we go with the recommendations? I don't know how much these diverge from our coding style. If it's bad, maybe it should follow the whitespace MR. ;). https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/TYPED_LINTING.md

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, happy to leave Prettier on.

Regarding @typescript-eslint/xxx linting rules/presets, I have been playing with the linting recently. Hopefully I'll get that up shortly.

"typescript.validate.enable": false,
"javascript.validate.enable": false,
"typescript.validate.enable": true,
"javascript.validate.enable": true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with "javascript.validate.enable": true, I started to see ts error in the non-converted js files. Should we follow this for the flow js files?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, keep it off for JS files and use the linting/flow tools from the CLI until we're through this? 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Flow extension recommends turning off the JS validation because it seems to use the TS compiler which then complains about Flow type syntax being invalid. I'm happy leaving the JS validation off, but the TS validation seems to work Ok.

@@ -5,5 +5,6 @@ module.exports = {
{ useBuiltIns: 'usage', corejs: '3' }
],
'@babel/flow',
'@babel/typescript'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to rely on babel to transpile typescript files or just have typescript (tsc) do both transpile and type checking and generation? Furthermore, I am wondering maybe we will not need babel once flow dependency is removed... therefore, maybe not add any new dependency where tsc can handle? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion either way. Once Flow is gone, I'm AOK with just tsc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference is to use the TS compiler for TS projects rather than babel.

However, while there is a mixture of JS with Flow types and TS code, I reckon that babel is a better choice. That is because babel can understand TS, Flow and JS simultaneously, while the TS compiler doesn't understand Flow (if you know of a way to precompile the Flow types out or some other voodoo let me know). I've played around converting a few other files and the difficulties soon become apparent. I might push up a couple more code changes that expose the issues.

I think in the long term, moving to a configuration that is the same/similar to what Jest itself uses would be the ideal.

Comment on lines +21 to +22
"build": "babel src/ -d build/ --extensions \".js,.ts\" --source-maps inline",
"build:types": "tsc --emitDeclarationOnly",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we agree to use babel for flow type only, then this should be adjusted accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my thoughts on going with babel in the short term above.

@@ -18,21 +18,25 @@
]
},
"scripts": {
"build": "babel src/ -d build/",
"build": "babel src/ -d build/ --extensions \".js,.ts\" --source-maps inline",
"build:types": "tsc --emitDeclarationOnly",
"prepublish": "yarn run build",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"prepublish" should call both build js and ts and types.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You OK with chaining them?

Suggested change
"prepublish": "yarn run build",
"prepublish": "yarn run build && yarn run build:types",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that there is index.d.ts in the project root. This seems to have type definitions for all the public types in the project and I didn't want to double up. Maybe when the entire codebase is TS, then include the built definitions? What do you think?

Also I can't see what steps are performed for a release - I presume the types are added manually?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe when the entire codebase is TS, then include the built definitions? What do you think?

I prefer that, since we want to stick to our index.d.ts until the whole project and all types have been converted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I can't see what steps are performed for a release - I presume the types are added manually?

Ah I see that the typings are referenced in the package.json, which is probably how that works.

package.json Outdated Show resolved Hide resolved

/* Strict Type-Checking Options */
"strict": false, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know why we have to have this set to true now due to many files haven't been migrated over. Please make a note that this should be reset to false once the migration is completed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to make a GitHub project to track it, or should we put a TODO list on an issue? 😁

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, do we need an issue to track this? As mentioned above, I think we should look at making this as close to Jest's configuration as feasible. I don't think we need a comment in source, so much of the config will change once we get to 100% TS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I added #34 to track the conversion. If you'd like to upgrade it to a project feel free.

// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

/* Strict Type-Checking Options */
"strict": false, /* Enable all strict type-checking options. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not "true"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know right 😄

Copy link
Member

@seanpoulter seanpoulter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, thank you so much for splitting up your epic MR @rossknudsen! 🎉 It looks great. I'm sure we'll dial in the configuration as we go along. I don't think there's any of those config changes I'd consider blocking so I'll approve it for now. We can start to converge on the tsconfig from as we go.

(What were you thinking of? I had checked facebook/jest, jest-community/vscode-jest, and @orta's (?) microsoft/TypeScript-Babel-Starter).

tsconfig.json Outdated
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to choose es5? Is the Node v6 in the TravisCI config the limiting factor?

I've been out of the loop for a while and forget where to check Node support for those target versions. I used to use https://node.green to check this kinda thing but it seems like that's a subset of these tables which includes https://kangax.github.io/compat-table/es6/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when I created the config (tsc --init) that's what it was set to. Happy to change it to your preference, do we know what runtimes that we're supporting? We might be able to bump to node v8 now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this to ES6 since we've bumped up to node v8 which the link(s) you posted seem in indicate is ES6 compatible.

.eslintrc.js Outdated
@@ -16,7 +16,7 @@ module.exports = {
},
plugins: ['flowtype', 'prettier'],
rules: {
'prettier/prettier': 'error',
'prettier/prettier': 'off', // disabled temporarily to prevent un-necessary delta in conversion to TS.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My vote is to keep this unchanged ('error'), as long as we keep our change progressive, I'd rather live with the whitespace diff (which we could probably turn off during diffing) than inconsistent coding style.

May I suggest that we keep it 'off' in this MR and follow-up with a "quick" whitespace-only MR that'll be an almost automatic approval?


I didn't see any typescript specific support (@typescript-eslint/xxx). Should we add those? Not sure if it can live in the same config with "flow", worst case separate config?

👍 It's a small repo. Should we go with the recommendations? I don't know how much these diverge from our coding style. If it's bad, maybe it should follow the whitespace MR. ;). https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/TYPED_LINTING.md

"typescript.validate.enable": false,
"javascript.validate.enable": false,
"typescript.validate.enable": true,
"javascript.validate.enable": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, keep it off for JS files and use the linting/flow tools from the CLI until we're through this? 👍

@@ -5,5 +5,6 @@ module.exports = {
{ useBuiltIns: 'usage', corejs: '3' }
],
'@babel/flow',
'@babel/typescript'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion either way. Once Flow is gone, I'm AOK with just tsc.

@@ -18,21 +18,25 @@
]
},
"scripts": {
"build": "babel src/ -d build/",
"build": "babel src/ -d build/ --extensions \".js,.ts\" --source-maps inline",
"build:types": "tsc --emitDeclarationOnly",
"prepublish": "yarn run build",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You OK with chaining them?

Suggested change
"prepublish": "yarn run build",
"prepublish": "yarn run build && yarn run build:types",

package.json Outdated Show resolved Hide resolved
package.json Outdated
"prettier-project": "yarn prettier-write '?(__mocks__|src|tests)/**/*.js'"
"prettier-project": "yarn prettier-write \"?(__mocks__|src|tests)/**/*.+(js|ts)\"",
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a non-blocking comment:

Oh JavaScript ... yarn this (prettier-write) ... npm that. 😅


/* Strict Type-Checking Options */
"strict": false, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to make a GitHub project to track it, or should we put a TODO list on an issue? 😁

rossknudsen and others added 4 commits January 31, 2020 21:33
Updated the ESLint config to use appropriate parsers for each file type.
Separate linting rules for each file type.
Co-Authored-By: Sean Poulter <[email protected]>
@typescript-eslint/eslint-plugin required a newer version.
package.json Show resolved Hide resolved
tsconfig.json Outdated
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when I created the config (tsc --init) that's what it was set to. Happy to change it to your preference, do we know what runtimes that we're supporting? We might be able to bump to node v8 now.

@@ -1,6 +1,6 @@
language: node_js
node_js:
- "6"
- "8"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I bumped the node version because it was erroring out saying that @typescript-eslint/eslint-plugin required a later version. If this is not acceptable, I can have a look at other options.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think node 8 is acceptable, vscode-jest also supports node >= 8. @firsttris will this node version bump ok for your repo?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@rossknudsen
Copy link
Contributor Author

Hey all. Just wanted to check if there was anything missing from this PR? I'm happy with it and as far as I can tell, I've either updated the code in response to comments or provided justification for the current changes. But I'm not sure what the etiquette is and this is my first contribution to OSS that has peer review.

Not being pushy, just wanting to check that I'm not holding things up 😃

@connectdotz
Copy link
Collaborator

Just wanted to check if there was anything missing from this PR?

@rossknudsen thanks for being patient, I checked the latest change and tested with vscode-jest, it all seemed fine! 👍 I think this PR will kickoff the ts migration that we all wanted for a while 😄

I will merge it later today.

@connectdotz connectdotz merged commit 14a1fb5 into jest-community:master Feb 8, 2020
@connectdotz connectdotz mentioned this pull request Feb 8, 2020
@rossknudsen rossknudsen deleted the typescript-lite branch February 9, 2020 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants