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

Survey: How do you use Sucrase, what would make it better? #361

Open
alangpierce opened this issue Dec 1, 2018 · 22 comments
Open

Survey: How do you use Sucrase, what would make it better? #361

alangpierce opened this issue Dec 1, 2018 · 22 comments

Comments

@alangpierce
Copy link
Owner

For anyone watching this repo (or otherwise seeing this issue), it would be great to get information on how Sucrase is being used and how it could improve! Feedback of any form would be great, but here are some example questions that might provide a good template. Feel free to answer any/all that are relevant.

  • Do you use Sucrase? If not, is there something stopping you from using it?
  • Which transforms do you use? What transpiler does Sucrase replace? (Babel, TypeScript compiler, or something else?)
  • Are you using Sucrase in production or just development?
  • How big is your codebase?
  • Which integrations do you use?
  • What runtime environments do you target? (Node version, Chrome version, etc)
  • How does development performance differ with and without Sucrase?
  • Have you seen any other advantages or disadvantages from using Sucrase?
  • Are there any bugs, pain points, or missing features that you'd like to see fixed?

Some of my goals in asking these questions:

  • Understand if there are correctness or usability issues getting in the way of adoption.
  • Understand how useful further performance improvements would be compared with feature polish or other improvements.
  • Understand which transform options may be ok to remove as a breaking change. I may want to remove enableLegacyBabel5ModuleInterop and enableLegacyTypeScriptModuleInterop in a future breaking change, mostly just for simplicity. I also may want to drop support for Flow if it's rarely or never used, since I don't use it and it's non-trivial to maintain (though still quite a bit easier to implement than TypeScript).
@alangpierce
Copy link
Owner Author

Here are my answers:

Do you use Sucrase? If not, is there something stopping you from using it?

Yes, we use Sucrase at Benchling, on an engineering team of about 20. Originally, it was an opt-in flag both for JS tests and for the dev server, but recently we decided that it's stable and useful enough to be on by default, with a --no-sucrase option to switch back to the old build in case things go wrong. The response has been really positive.

Which transforms do you use? What transpiler does Sucrase replace? (Babel, TypeScript compiler, or something else?)

Our code is a big React JSX codebase that is partially converted to TypeScript, so we use the jsx and typescript transforms, plus the imports transform when running tests (in node). We used to use enableLegacyBabel5ModuleInterop and enableLegacyTypeScriptModuleInterop, but I've since cleaned up our code to work with the latest CJS interop rules, so we don't need either of those anymore. We have some createReactClass usages, so we make use of the display name transform.

In our normal build system without Sucrase, we use Babel 6 for .js files (we haven't upgraded to Babel 7 yet) and the TypeScript compiler for .ts and .tsx files.

Are you using Sucrase in production or just development?

Only development, and we have no plans to ever use it in production. We need to provide at least basic support for IE, so we'll use Babel and tsc for the forseeable future. I think the only reason we'd ever switch to using it in production is to keep production and development closer in sync. Production JS build performance certainly isn't a concern at all for us.

How big is your codebase?

About 500,000 lines of code, about 10% of which has been converted to TypeScript.

Which integrations do you use?

For the dev server build, we use the webpack plugin. For tests, we use sucrase/register. We used to use the gulp plugin for ahead-of-time builds, but not anymore.

What runtime environments do you target for development? (Node version, Chrome version, etc)

Node 8, latest Chrome, latest Firefox.

How does development performance differ with and without Sucrase?

Rough numbers:

  • Webpack startup time was about 40 seconds before and is about 20 seconds with Sucrase. We use happypack to run Sucrase in a background process and the bottleneck is now Webpack's ability to process the resulting JS, so Sucrase perf improvements wouldn't help here. (A Sucrase equivalent for Webpack could help dramatically, though.)
  • Running a small number of tests (which imports about 100,000 lines of commonly-used files) used to take maybe 8 seconds in the best case and well over a minute in the worst case (a cold cache or issues where the cache is slow to load). It now consistently takes about 5 seconds, about 1 second of which is running Sucrase on the imported code.

Directly running Sucrase on the whole codebase takes about 5 seconds, compared with over a minute before.

Have you seen any other advantages or disadvantages from using Sucrase?

There were a few nice advantages in addition to build performance:

  • Previously we had several caches (happypack cache, babel-register cache, and a build output directory for one of the build modes). With Sucrase, we compile everything on the fly with no cache, which avoids a lot of frustration that has happened with caches getting out of date.
  • We don't have source maps configured in webpack (doing so slowed down webpack significantly), so previously in the Chrome debugger we'd have a hard time reading code compiled from async functions and for...of loops. Now, the code is much easier to read since only JSX and imports are transformed.
  • Previously, NDB and the VSCode debugger both had trouble reading source maps in order to properly set breakpoints. Since Sucrase has a one-to-one line mapping with the original code, breakpoints in NDB and VSCode now just work.
  • The debug info in JSX makes React error messages more useful; line numbers now point directly into the JSX. Normally this would require Babel 7 and I believe isn't supported at all by tsc.
  • Since Sucrase doesn't compile to commonjs for the webpack build, we now get better errors from webpack if there are invalid import statements. Previously, it would be undefined at runtime.

Are there any bugs, pain points, or missing features that you'd like to see fixed?

The main disadvantage is that React Hot Loader doesn't work at all. We were already having trouble with React Hot Loader reliability, so this didn't seem like a big loss, but we would like to get it figured out in the future if possible.

In the past, there were some bugs and missing syntax features, but things seem to have been stable for a while now.

@yang
Copy link
Contributor

yang commented Dec 6, 2018

Not a user, but was searching for faster Typescript transpilation solutions, so Sucrase looked very interesting - unfortunately, need React hot loader!

@MaxGraey
Copy link

MaxGraey commented Dec 9, 2018

@alangpierce It would be nice if sucrase has a possibility of type checking for typescript and flow. Without this features development is not very useful in my opinion

@alangpierce
Copy link
Owner Author

@MaxGraey Interesting, could you describe your build setup more? From my experience, it's always best to decouple typecheck/lint from transpile/bundle, even though the easiest build setups tend to do both at the same time. In all of my TypeScript projects, I run typechecking in my editor (using an editor plugin), when running tests/lint (using tsc), and in CI (also using tsc). I intentionally don't make it so a type error anywhere in my project means I can't run my code at all. There's also https://github.com/Realytics/fork-ts-checker-webpack-plugin to have webpack run the typechecker, though I don't use that because I find in-editor typechecking to be enough.

cc @yang, if you haven't already separated transpile and typecheck, that's an easy way to speed up your TS build signficantly. In ts-loader, it's transpileOnly: true, and other tools have similar settings. Sucrase improves further upon that by making transpile faster.

@MaxGraey
Copy link

MaxGraey commented Dec 9, 2018

fork-ts-checker-webpack-plugin require rollup or webpack, CI & tests require tsc. They both eat up hard disk space. Ideally, it would be nice to have one lightweight tool that could completely replace typescript or flow.

@alangpierce
Copy link
Owner Author

tsc ships with TypeScript, and there isn't really a reasonable way to do type checking without TypeScript installed. The transpile aspect of TypeScript is simple enough that a project like Sucrase can replace it, but the typecheck aspect of TypeScript is much, much more complicated. I guess it maybe could be possible to make a weaker-but-faster typechecker for TS code, but that would be a totally different project, way outside the scope of Sucrase.

I think the best Sucrase could do is run tsc (maybe programmatically) alongside the transpile step, but that would make Sucrase dramatically slower, slow enough that it would be better to just use tsc by itself for typecheck and transpile. Happy to accept suggestions on how Sucrase could make config easier, but I also want to avoid external dependencies, especially when there isn't any problem using other tools alongside Sucrase.

As one example, at my work, running a single test takes about 5 seconds, about 1 second of which is in Sucrase. Doing a full typecheck takes about 30 seconds, so forcing a typecheck at the start of any test would make it much, much harder to iterate on tests. Incremental typechecking in the TS language service (which runs in editor plugins) is faster, but that's harder to do from the CLI.

@yang
Copy link
Contributor

yang commented Dec 12, 2018

@alangpierce Yeah we already use transpileOnly, and we're only seeing up to 33% speedup from it in incremental rebuild speed (with typechecking, takes just under 10s). I'm seeking something much faster, hence the interest in your project!

@aleclarson
Copy link
Contributor

I use @sucrase/jest-plugin and love it. My only pain point is that Node 6 is not supported.

@arv
Copy link
Contributor

arv commented Dec 20, 2018

We use Sucrase to transform all our JSX file to JS files which are then later fed into Closure Compiler (for type checking and minification). This is both in dev and prod

We have ~1100 jsx files and most of our build tool chain is in python. Python just calls out to Node.js to do the transformation. However, since the startup time of Node.js (plus sucrase) is in the order of 200ms that is a lot of wasted time. This is why we use Nodegun. Giving us transformation times as low as 3ms and for large files around 50ms. Of course we could have refactored the build tools to hand in all the files once but that would require lots of work.

Performance is great! We started off using JSXTransformer running inside Nashorn (Java JVM) (~300ms per file). That one was discontinued and we switched to Babel (still inside Nashorn). Babel was super slow, maybe 500ms to a few seconds for large files. Also Nashorn is an ES3 environment so we had to compile Babel down to a single ES3 file (babel-standalone) which was annoying.

We might use Sucrase for ts in the future

@Meai1
Copy link

Meai1 commented Dec 24, 2018

es7 bind operator would make it better, the main annoyance in javascript is the lack of easy 'this' handling

@alangpierce
Copy link
Owner Author

@Meai1 Make sense! Unfortunately, the bind operator is currently a stage 0 proposal ( https://github.com/tc39/proposals/blob/master/stage-0-proposals.md , https://github.com/tc39/proposal-bind-operator ), so I think it's too early to implement in Sucrase. Sucrase can handle a few future JS features, especially the simple ones, but for very experimental proposed features, it's probably best to use Babel.

@alangpierce
Copy link
Owner Author

@yang FYI I just released Sucrase 3.9.0 with react-hot-loader support. Hopefully that unblocks your use case!

@c-johnson
Copy link

Hey! Really love the library. I'm working on a set of guides that use Sucrase, Gulp and Rollup for a minimal modern build tool configuration, stripping out babel/webpack. So far it has worked flawlessly.

It's currently being used in production for Urbit's Landscape app (http://github.com/urbit/landscape). I just use it for JSX transformation with the gulp plugin. ~5k lines total in the source code.

I'm a big fan of having a clean, simple build tool setup. Sucrase does the job perfectly. Our gulpfile is only 117 lines and understandable with basic JS experience. I don't think I'll go back to webpack.

@jpike88
Copy link

jpike88 commented May 16, 2019

Source map support is a must.

@FDiskas
Copy link

FDiskas commented Feb 15, 2020

I'm using this with rollup especially for compiling typescript files.
TypeDefinition generation should be available or respectable in tsconfig.json setting declaration: true

@dougg0k
Copy link

dougg0k commented Jul 16, 2020

A watch/respawn feature for Typescript would be cool.

@odinho
Copy link

odinho commented Jul 21, 2020

I'm trying to use it to remove Typescript from some source code in a project, making it a regular Javascript+JSX project. But it seems to not really work for that, since you need to use the "JSX" transform to not get a syntax error, but I actually want the JSX to come through in the other end :)

@jonstuebe
Copy link

Trying to use it in a component library that is currently just running tsc -b in a monorepo. Love the speed, but would really love to see sucrase output the declaration files d.ts instead of just stripping them.

@thesoftwarephilosopher
Copy link

@alangpierce

Sucrase made the new TypeScript web framework Novo Cantico much faster than when it was using Babel or even esbuild.

The one thing that might make Sucrase better for this use-case is to save import names directly in the context.

Currently, if you have this:

import {foo} from 'bar';
console.log(foo);

It seems Sucrase translates this into:

const _bar = require('bar');
console.log(_bar.foo);

When using VS Code's debugger, and placing a breakpoint on the console.log line, hovering over foo doesn't show anything, because it doesn't exist at runtime. That's the only thing I would add so far.

@alangpierce alangpierce pinned this issue Jul 12, 2022
@renhiyama
Copy link

I use sucrase in production, and I feel developers using my library should use it too! I'm pretty much confident with using it, and if there's any missing feature, we could simply make an issue here 🙂. I target nodejs v18+, recent browser versions, deno & bun runtime too, and other serverless runtimes. I primarily use sucrase to convert {tsx, ts, jsx, js} to js.

What I'm hoping to see is sucrase (getting forked if possible, or a different package) have support for vuejs sfc components & svelte components getting transpiled.
It would widen my web framework ecosystem to support vuejs and svelte alongside reactjs.

@ko-devHong
Copy link

@sdegutis Sucrase is not support tree shaking?? beacause your example code doesn't use tree shaking

@aleclarson
Copy link
Contributor

A watch/respawn feature for Typescript would be cool.

I'd like to echo this statement

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

No branches or pull requests