flightcontrolhq / superjson

Safely serialize JavaScript expressions to a superset of JSON, which includes Dates, BigInts, and more.
https://www.flightcontrol.dev?ref=superjson
MIT License
4.13k stars 91 forks source link

SWC Plugin #157

Closed stnwk closed 2 years ago

stnwk commented 3 years ago

Next.js seems to be switching from babel to swc, see: https://github.com/vercel/next.js/pull/29811

In the next stable release, swc will be used by default to compile a Next.js project if there is no custom babel.config.js, with the goal to eventually completely drop support for babel.

I guess this means, there will be a need for a superjson-swc plugin of some sort? babel-plugin-macro is having a similar discussion about it here: https://github.com/kentcdodds/babel-plugin-macros/issues/144

What are your thoughts?

Skn0tt commented 3 years ago

Thanks for opening this issue! Given Next's typical behaviour around deprecations, I don't see this as something we immediately have to act on. But I definitely see the need for an SWC plugin!

Warning: Plugin apis are going to be deprecated in v2. With v2, swc will provide a rust-based plugin api instead. ~ SWC Docs

Given that status, I propose to wait until SWC v2 is released.

flybayer commented 3 years ago

@Skn0tt you can already use the Rust plugin APIs. Next.js is using them.

Here's the source for the next.js plugins: https://github.com/vercel/next.js/tree/canary/packages/next/build/swc/src

We definitely want an swc version of this. We're going to be writing rust version of our other blitz plugins too.

flybayer commented 3 years ago

I managed to get more information from the Vercel team: https://twitter.com/flybayer/status/1454547398521393153

TLDR: There are no docs for SWC plugins because there is not yet an official SWC Rust plugin API.

The SWC Rust plugin API is starting to be worked on now.

So not much we can do for now.

elie222 commented 3 years ago

warn - Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc" https://nextjs.org/docs/messages/swc-disabled

A quick fix would just be to manually use this package when needed instead of relying on Babel to do it, right?

flybayer commented 3 years ago

@elie222 correct

elie222 commented 3 years ago

Ah, just tried it: superjson.serialize().json means you lose the TS types. will pass for now :(

CanKattwinkel commented 2 years ago

Ah, just tried it: superjson.serialize().json means you lose the TS types. will pass for now :(

Then you might want to wrap all your props simply with

type Serialized<T> = {
    [P in keyof T]: T[P] extends Date ? string : Serialized<T[P]>
};

Disclaimer: this might need to be extended to cover any object structure, js data type.

remorses commented 2 years ago

I made a nextjs plugin that does not disable the SWC transform

You can try it here

Basically it applies the superjson babel plugin only on the pages files, without adding a .babelrc file

Skn0tt commented 2 years ago

Putting this here for anybody who comes across this issue: @remorses's plugin, while not adding a .babelrc file, still uses Babel. I consider this to be a work-around, the real goal will be to create an SWC equivalent of babel-plugin-superjson-next.

elie222 commented 2 years ago

Does it matter if it’s using Babel if SWC works? Or are we still seeing slow builds because of it. I’ve started using remorses package.

Best, Eliezer

On Mon, Nov 22 2021 at 9:57 AM, Simon Knott < @.*** > wrote:

Putting this here for anybody who comes across this issue: @remorses ( https://github.com/remorses ) 's plugin, while not adding a.babelrc file, still uses Babel ( https://github.com/remorses/next-superjson/blob/959b3dc6063976ac2298a86b7169e38034b7bcbe/next-superjson/src/index.ts#L25 ). I consider this to be a work-around, the real goal will be to create an SWC equivalent of babel-plugin-superjson-next.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub ( https://github.com/blitz-js/superjson/issues/157#issuecomment-975218021 ) , or unsubscribe ( https://github.com/notifications/unsubscribe-auth/AAXSQXYIMPIWTW5HSTWHK7LUNHZXNANCNFSM5GTQEOPA ).

Skn0tt commented 2 years ago

It will introduce another bundler into the pipeline, which will slow things down, yes. It won't be as big of a slowdown as the full-on babel strategy which happens when there's a .babelrc (this will fully disable SWC, and use Babel for everything), but I suspect it's noticeably slower. It's also somewhat of a weird setup, where code goes through two transpilers (first babel, then SWC); and I suspect that this is not officially unsupported by Next.js. Maybe @timneutkens can shed some light.

remorses commented 2 years ago

@Skn0tt the Babel plugin only runs on the pages directory, this can’t be a performance problem unless you have a page 10k lines long

Skn0tt commented 2 years ago

That's a good point @remorses! Thank you, I missed that.

ghost commented 2 years ago

Any updates on this?

kevinsimper commented 2 years ago

Could this be solved by using Next.js new middleware? That seems like a possible solution, adding superjson to all responses and then if one wants to use superjson in the component, they need to call superjson.parse?

markhughes commented 2 years ago

I would be happy to try make this into a plugin? It's a fairly simple plugin to make judging by the babel one

Skn0tt commented 2 years ago

That would be great @markhughes!

markhughes commented 2 years ago

I've been able to write the base of it but next.js does not yet allow adding custom swc plugins. Once they update swc and add plugin support I'll give it a proper test.

cryptoAlgorithm commented 2 years ago

@elie222 maybe using the stringify and parse methods can help preserve types? From a quick look at the readme it seems like sending the stringified string as a prop then parsing it with a type will preserve the type.

masnwilliams commented 2 years ago

Any updates on this?

markhughes commented 2 years ago

I've been meaning to test it in the nextjs experimental stuff :) i'll put it up on github i've just been super sick.

orionmiz commented 2 years ago

I'm working on swc plugin of superjson for Next.js with some supports from main creator of swc.

Also, a stale issue in current babel plugin would be resolved too.

Coming ASAP!

orionmiz commented 2 years ago

Done! You've been waiting for a long time.

🚀 next-superjson-plugin

Please check README.md and follow the instructions to apply the plugin.

I've already tested working in Next.js 12.2.4

But if you find any bugs, please leave issues and I will check it out quickly.

flybayer commented 2 years ago

@orionmiz that's awesome, great work!!!