emotion icon indicating copy to clipboard operation
emotion copied to clipboard

Rewrite to TypeScript

Open Andarist opened this issue 3 years ago • 26 comments

Since Flow is not actively used by any core contributor and its adoption in the community has dropped significantly (especially in comparison to its alternative) it's time to refactor the codebase from Flow to TypeScript.

We could use some help with that. It's best to start from the small, leaf packages. We already have TS types for our packages, they are just not generated from the source.

Progress

  • [ ] babel-plugin
  • [x] babel-plugin-jsx-pragmatic
  • [ ] babel-preset-css-prop
  • [ ] cache
  • [x] css
  • [ ] css-prettifier
  • [x] eslint-plugin
  • [x] hash
  • [x] is-prop-valid
  • [ ] jest
  • [ ] memoize
  • [ ] native
  • [ ] primitives
  • [x] primitives-core
  • [ ] react
  • [x] serialize
  • [ ] server
  • [x] sheet
  • [ ] styled
  • [x] unitless
  • [x] utils
  • [x] weak-memoize

Andarist avatar Apr 26 '21 10:04 Andarist

Cooool ! This is a big migration work, we need a detailed roadmap to implement it.

iChenLei avatar Apr 26 '21 11:04 iChenLei

For now, I would try to convert a simple package like @emotion/memoize to see what exact steps will be required there. When we know that then similar steps will have to be replicated in other packages.

Andarist avatar Apr 26 '21 11:04 Andarist

I took a stab at the utils package: https://github.com/emotion-js/emotion/pull/2359

rjdestigter avatar Apr 26 '21 19:04 rjdestigter

I opened #2360 to try to handle some of the tooling/config stuff needed to support the rest of the conversions. As of right now, it's mostly focused on tsconfig.json files and eslint config stuff.

eslint is able to auto-fix quite a few of the existing issues (didn't include the auto-fixes in the PR yet to keep it readable), but there are still 155 errors and 62 warnings. I need to go through those and figure out what's caused by missing config stuff versus what's caused by flow usage/will be resolved by actual TypeScript conversion.

with-heart avatar Apr 27 '21 11:04 with-heart

I would be honored to help with this! 🙌

Is there a list anywhere of what's in scope, and/or recommendations about what to start with?

JoshuaKGoldberg avatar May 10 '21 14:05 JoshuaKGoldberg

@JoshuaKGoldberg it turned out that I have posted this issue at the totally wrong time for myself 😂 The last 2 weeks were super crazy for me and I didn't have time to sit down properly to review the 2 existing PRs for this that have started working on migrating some packages.

I think @with-heart's PR is currently the closest to getting the tooling-related stuff done: https://github.com/emotion-js/emotion/pull/2360 but there is still some work there to be done. If you could take a look into it - that would be highly appreciated. If no - I would wait a couple of days before we figure this out and land that PR. When that will be done it should be fairly easy to start migrating package after package - starting from "leaf" ones.

Andarist avatar May 10 '21 15:05 Andarist

I've created a ts-migration branch. It seems to me that the easiest approach to do this would be to actually:

  1. drop Flow entirely - from the source code, CI configs, tooling
  2. add TS tooling (partially already done in #2360 and #2359
  3. migrate packages one by one

This would simplify both the whole process and individual PRs.

Andarist avatar May 11 '21 11:05 Andarist

I've created a ts-migration branch. It seems to me that the easiest approach to do this would be to actually:

  1. drop Flow entirely - from the source code, CI configs, tooling
  2. add TS tooling (partially already done in #2360 and #2359
  3. migrate packages one by one

This would simplify both the whole process and individual PRs.

I think this is a great idea 🙂 Thanks for setting it up!

michaeljaltamirano avatar May 11 '21 15:05 michaeljaltamirano

  1. drop Flow entirely - from the source code, CI configs, tooling

I've started a PR in parallel to do so against the ts-migration branch here: https://github.com/emotion-js/emotion/pull/2385

If a maintainer could grant my builds to run, that'd be very helpful. 😄

JoshuaKGoldberg avatar May 21 '21 03:05 JoshuaKGoldberg

If a maintainer could grant my builds to run, that'd be very helpful. 😄

I hate that GitHub "feature" >.< Can I somehow grant you permission to run builds? Or will I have to approve them manually until we merge your PR? I believe that the restrictions get lifted if you already have some commits in the repo.

Andarist avatar May 21 '21 11:05 Andarist

I'd also love to help with this effort. What's the next best package to tackle for this?

sarayourfriend avatar Jul 12 '21 15:07 sarayourfriend

@sarayourfriend @emotion/sheet, @emotion/unitless, @emotion/memoize, @emotion/weak-memoize and @emotion/is-prop-valid are the easiest picks right now

Andarist avatar Jul 12 '21 16:07 Andarist

Just noting that is-prop-valid will be blocked by memoize.

sarayourfriend avatar Jul 13 '21 13:07 sarayourfriend

I opened several PRs for this. @Andarist any chance they could get merged sometime soon?

sarayourfriend avatar Jul 29 '21 13:07 sarayourfriend

Yes, definitely! Thanks a lot for your contributions. I've seen all of them but I'm being slammed lately with work and didn't find the time to sit down to this in the late evenings (the only time I currently have for OSS). Sorry for the delay

Andarist avatar Jul 29 '21 14:07 Andarist

Okay, no worries! Just wanted to make sure it didn't slip through the cracks 🙂 Let me know if you need anything from me in the meantime!

sarayourfriend avatar Jul 29 '21 15:07 sarayourfriend

Hey!

If you still need help, please let me know where I can help! 👋

Beraliv avatar Sep 29 '21 15:09 Beraliv

@Beraliv thank you for the offer! It feels like we should now take care of @emotion/cache and @emotion/serialize, after that we can try to convert @emotion/css and @emotion/server, which would bring us to the grand finale: @emotion/react and @emotion/styled. There are some other packages - like Babel plugins, ESLint plugin, and @emotion/jest but they are less important for now and they could be taken care of even after landing the TS migration on the main branch.

Note that the current progress is available on the ts-migration branch and PRs that got merged to it can serve as an example of how a migration PR should roughly look like. A single PR should, preferably, focus on a single package.

Andarist avatar Sep 29 '21 22:09 Andarist

Hi, I would like to help migrating cache or serialize. A merge from master would be required so we don't migrate stale code or introduce regressions.

Migrating everything at once in a single ts-migration branch is a huge task and the branch will be out of date very quickly.

Could we somehow merge the current work while keeping Flow enabled for the non-migrated packages?

danilofuchs avatar Oct 29 '21 20:10 danilofuchs

Probably not that much has changed on the main branch since the last merge - i will merge it to the ts-migration soon. Feel free to migrate anything and just branch off the ts-migration branch. I will take care of the merge conflicts

Andarist avatar Nov 04 '21 18:11 Andarist

In the packages that have already been migrated, we still have .d.ts files, tslint.json, and type checking tests. Is it safe to remove all of this stuff?

image

By the way, I am planning on working on some of the TypeScript tooling:

  • The tsconfig.json in each package will extend a top-level tsconfig.json. This keeps the configs consistent across packages.
  • Fix ESLint configs as there are currently configuration errors when trying to run lint
  • Remove the workflows that run dtslint (depending on the answer to my above question)
  • Add tsc script to the root package.json that type checks everything
  • Maybe other stuff 🤔

srmagura avatar Nov 14 '21 17:11 srmagura

👋 I'm about to attempt a PR updating eslint-plugin to support ESLint v8, and saw this - I've done a fair amount of work in TS, including writing and converting ESLint plugins to TypeScript (I did it for eslint-plugin-jest); would folks like me to take a stab at converting @emotion/eslint-plugin?

I'm not sure when I'll get around to it, but I'm also happy to be pinged to help out if folks want :)

G-Rath avatar Nov 23 '21 05:11 G-Rath

In the packages that have already been migrated, we still have .d.ts files, tslint.json, and type checking tests. Is it safe to remove all of this stuff?

This is still useful for testing the types - the index.d.ts and tslint.json are just enforced by the dtslint that we are using for the testing.

The tsconfig.json in each package will extend a top-level tsconfig.json. This keeps the configs consistent across packages.

Let's keep a single, top-level, config for the time being. It's how the setup works in some other repos that I collaborate on, like Changesets

Remove the workflows that run dtslint (depending on the answer to my above question)

The main advantage of using dtslint is that it runs those tests against multiple versions of TS - so I think we need to stick with it. However, this tool needs upgrading, see here

Add tsc script to the root package.json that type checks everything

This should be done - good catch (dtslint might not test our source files and it definitely wont test the test files)

👋 I'm about to attempt a PR updating eslint-plugin to support ESLint v8, and saw this - I've done a fair amount of work in TS, including writing and converting ESLint plugins to TypeScript (I did it for eslint-plugin-jest); would folks like me to take a stab at converting @emotion/eslint-plugin?

@G-Rath if you could take a stab at converting this, it would be great. I've never worked with ESLint rules written in TS so this would be of a great help.

Andarist avatar Nov 23 '21 15:11 Andarist

Keeping the dtslint tests during migration is very useful to make sure the TS public interface is not being changed in the process. I myself caught a missing export when migrating serialize because of it.

If we only change the internal implementation from JS to TS, it should be transparent to end users, as many already use the currently exported TS types. After the migration is complete and stable, it might make sense to remove it.

Checking for multiple versions of TS is useful, might be worth keeping dtslint for it.

danilofuchs avatar Nov 23 '21 15:11 danilofuchs

Currently yarn build (preconstruct) is creating .d.ts in the src directory of various packages. I'm pretty sure these should not be committed since they are compiled output, so I have just been careful not to add them when using git add.

Is there a way to prevent preconstruct from generating these unwanted files? @mitchellhamilton

srmagura avatar Nov 26 '21 19:11 srmagura

Hello @Andarist, Would there be anything I could help with? First time contributor.

abreel avatar Aug 23 '23 04:08 abreel