bucklescriptreason-reactrescript

Disable react-jsx per file in a ReasonReact project


Is there a way to disable react-jsx transformation in some files of a ReasonReact project?

I think the other way around is possible by not adding "reason": { "react-jsx": 3 } to bsconfig.json and by adding @@bs.config({jsx: 3}) to the top of the files where you want react-jsx transformation, but that would force me to add this annotation in too many files.

I'd like to build a small DSL based on JSX in a few files while benefiting from React in the rest of my project.


Solution

  • Note: the solution suggested is not very straight forward, and I think it's much simpler to add @@bs.config annotations explicitly in all required files, but if you really don't want to do that, the following might work.

    If I'm reading the compiler code correctly, user-defined ppxs are applied before ReasonReact ppx. In the linked compiler module, Cmd_ppx_apply.apply_rewriters will apply with all arguments passed with -ppx flag, and Ppx_entry.rewrite_implementation is ReasonReact ppx.

    Assuming that's true, one could have a ppx that checks a top-level statement like @@custom.jsx at the top of the file, that the ppx would check. The ReasonReact ppx used to have a similar check, in case it serves as reference.

    Then if this statement is found, the custom ppx would process the nodes that have the @JSX attributes and make sure it removes the attributes from them, so when the compiler passes the AST to ReasonReact ppx, it won't see them.

    Note this would break if the ReScript ppx pipeline is updated one day to a driver-based one (unlikely I'd say because that would mean ReScript should support native libraries as 1st class citizens somehow), or if the ordering that was mentioned above changes (ReasonReact ppx applies before user-defined ones).