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

Add TypeScript support to React Native #209

Closed
wants to merge 2 commits into from

Conversation

LinusU
Copy link
Contributor

@LinusU LinusU commented Jul 31, 2018

Summary

This PR adds support for TypeScript out-of-the-box. Existing codebases should work as before, but React Native should be able to pick up .ts and .tsx files automatically, and transpile them using Babel.

Note that no actual type-checking will be done, this is in line with how the current Flow support is working. The user can run tsc --noEmit to type-check the project.

Test plan

I'm currently working on this. I haven't been able to figure out how to test these changes in a local RN application.

I'll be meeting up with @kelset today, hopefully he can help me with this 💌

With these changes, the following RN project should be able to work without further configuration: https://github.com/LinusU/react-native-babel-typescript-test

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 31, 2018
@kelset
Copy link
Contributor

kelset commented Jul 31, 2018

CI error:

TypeError: /home/circleci/metro/packages/metro/src/commands/serve.js: Duplicate declaration "restart" (This is an error on an internal node. Probably an internal error)

Not sure what this means 🤷‍♂️

Anyway I think that @CompuIves or @rafeca could provide some feedback on this.

@LinusU
Copy link
Contributor Author

LinusU commented Jul 31, 2018

Yeah, looked at that as well, and inspecting that file I can only find one declaration of restart 🤔

Won't have much more time during the day to look at this though...

@rafeca
Copy link
Contributor

rafeca commented Jul 31, 2018

TypeError: /home/circleci/metro/packages/metro/src/commands/serve.js: Duplicate declaration "restart" (This is an error on an internal node. Probably an internal error)

I have a commit that's going to land soon that fixes this error

@LinusU
Copy link
Contributor Author

LinusU commented Jul 31, 2018

@rafeca nice! I worked around it in a really strange way: 4e00488

Seems like it's a bug inside of Babel?

@codecov-io
Copy link

codecov-io commented Jul 31, 2018

Codecov Report

Merging #209 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #209      +/-   ##
==========================================
+ Coverage   85.46%   85.47%   +<.01%     
==========================================
  Files         134      134              
  Lines        4390     4391       +1     
  Branches      676      677       +1     
==========================================
+ Hits         3752     3753       +1     
  Misses        566      566              
  Partials       72       72
Impacted Files Coverage Δ
...etro-react-native-babel-preset/src/configs/main.js 100% <100%> (ø) ⬆️
packages/metro-config/src/defaults/defaults.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d915cc7...37f2c3c. Read the comment docs.

@rafeca
Copy link
Contributor

rafeca commented Jul 31, 2018

Yes, it's a bug in babel scope counting (more info) that causes an issue in our inline requires transformer.

I've worked around the issue by disabling the inline requires plugin in our tests (that's fair because we don't use inline requires to transpile Metro)

@LinusU LinusU changed the title [WIP] Add TypeScript support to React Native Add TypeScript support to React Native Aug 1, 2018
@LinusU
Copy link
Contributor Author

LinusU commented Aug 1, 2018

I've worked around the issue by disabling the inline requires plugin in our tests (that's fair because we don't use inline requires to transpile Metro)

Awesome!

I've rebased on master and the problem went away.

I also changed the approach to be a bit simpler, now the only thing added is an override for .ts and .tsx files. This approach was made possible in v7.0.0-beta.48 of Babel, and we are using a newer version than that.

I've opted to enable JSX in both .ts and .tsx files, since it's enabled for .js files and doesn't require the .jsx file ending. I'd be happy to change this if having it enabled only for .tsx files would be preferable.

@LinusU
Copy link
Contributor Author

LinusU commented Aug 1, 2018

If anyone is interested, the size of the two new dependencies are:

plugin-syntax-typescript-7.0.0-beta.54.tgz          1053 bytes
plugin-transform-typescript-7.0.0-beta.54.tgz       3896 bytes

So adding TypeScript support to React Native will only add 4,949 bytes of extra download 😄

Copy link
Contributor

@rafeca rafeca left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the contribution! I love how simple it's been to add native support for TypeScript 😃

Small note: since we don't use TypeScript internally at FB, we're not going to be able to fully maintain this feature, so I expect you/the community to help here in the future 😄

Something I recommend to do is to add a TypeScript file to the test bundle that we use for our end to end tests: this will prevent TypeScript support from breaking in the future.

@@ -124,6 +128,14 @@ const getPreset = (src, options) => {
comments: false,
compact: true,
plugins: defaultPlugins.concat(extraPlugins),
overrides: [
{
test: file => isTypeScriptSource(file || 'internal.js'),
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you make the fileName param in isTypeScriptSource() optional (and check if it's not null there)? This way we can avoid passing the internal.js thingy 😄

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 thing!

@LinusU
Copy link
Contributor Author

LinusU commented Aug 1, 2018

@rafeca Fixed your comment 👌

Some things, just because I'm new to this repo:

  • I amended my commit instead of pushing a new commit
  • I used !! since I found that 10 times in the rest of the code, I only found Boolean(...) once
  • I rebased on master again

Please let me know if you prefer any other style/way of working ☺️

@LinusU
Copy link
Contributor Author

LinusU commented Aug 1, 2018

so I expect you/the community to help here in the future

Will absolutely maintain this!

We are going to use this at work so will be able to this during work hours 👍

Something I recommend to do is to add a TypeScript file to the test bundle that we use for our end to end tests: this will prevent TypeScript support from breaking in the future.

Absolutely 🙌

Thanks a lot for the contribution!

Thanks for the comments and quick responses ❤️

Copy link
Contributor

@rafeca rafeca left a comment

Choose a reason for hiding this comment

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

I amended my commit instead of pushing a new commit

👍

I used !! since I found that 10 times in the rest of the code, I only found Boolean(...) once

💯

I rebased on master again

🥇

var type = 'TypeScript';
exports.type = type;
var test = true;
exports.test = test;
Copy link
Contributor

Choose a reason for hiding this comment

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

nice!!! 👍

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

rafeca is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@LinusU
Copy link
Contributor Author

LinusU commented Aug 2, 2018

Thank you for landing this 🚀

@LinusU
Copy link
Contributor Author

LinusU commented Aug 2, 2018

@rafeca would it be possible to cut a release, 0.43.3, so that I can easier test this out? Thanks!

@rafeca
Copy link
Contributor

rafeca commented Aug 2, 2018

yes, I was planning to release 0.43.3 today! 🏃

@LinusU
Copy link
Contributor Author

LinusU commented Aug 2, 2018

Awesome 👏 thanks!

@emin93
Copy link

emin93 commented Aug 28, 2018

Wow this is really great thanks a lot! I just added a note to the TypeScript template (https://github.com/emin93/react-native-template-typescript) that it will be supported out of the box in future React Native versions. 😄

@nicolashemonic
Copy link

Thanks! Love it!

bsr203 referenced this pull request in react-native-community/react-native-template-typescript Oct 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants