New jsx compiler?

Does anyone know how to use the new JSX compiler in Meteor? I actually don’t know where the transform is specified in my project, so I imagine it’s in the default Babel configuration of Meteor… which I haven’t yet located.

1 Like

I think you’ll need a .babelrc file, and use the @babel/preset-react

The article references it with an example

// If you are using @babel/preset-react
{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}
2 Likes

I finally got to trying this, and it doesn’t seem to work, at least with a local test server (meteor run) using a modern browser (Meteor.isModern === true). How does Meteor decide which Babel config to use in modern vs. legacy builds? I tried reading babel-compiler.js but couldn’t quite figure it out…

Could you solve it? I’m having the same issue.

I’ve been doing something similar to this for ages, but without the need to have an import inserted by the compiler everywhere (honestly, I can’t figure out why they keep making this so complicated).

Once that’s set up, you can set a global reference.

For the new jsx format, maybe try:

import {jsx as _jsx} from 'react/jsx-runtime';
h = _jsx;

Also, why is it renaming jsx as _jsx? Seems extra to me.

I haven’t tried this yet. Just some food for thought.

This turned out to be incredibly easy to get working - just add the following to your babel config:

"babel": {
  "plugins": [
    "npdev-react-loadable-babel",
    [
      "@babel/plugin-transform-react-jsx",
      {
        "runtime": "automatic"
      }
    ]
  ]
}

That is doing it through package.json, but it should be similar for .babelrc. In my case, I already had ```
@babel/plugin-transform-react-jsx”, but you may need to add that too.

1 Like

The reason why this doesn’t work out of the box is because the meteor babel compiler will ignore any custom configurations for @babel/preset-env and @babel/preset-react:

So doing something like

{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
    }]
  ]
}

will be ignored.

I am not even sure if using the @babel/plugin-transform-react-jsx plugin directly will work

  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "runtime": "automatic"
      }
    ]
  ]

because the meteor compiler will have already run @babel/preset-react by default (whether you provided it or not), which would have already transpiled all the jsx stuff to use createElement, etc. At that point, I think it’s too late for @babel/plugin-transform-react-jsx to do anything because all the jsx is already gone. I don’t know if it’s smart enough to “undo” that stuff.

At least this was my experience with it when I tried getting it to work a long time ago and wasn’t able to. Maybe things have changed. I stopped trying when I saw that I couldn’t override the core meteor babel config for the react preset.

It works with @babel/plugin-transform-react-jsx. I’ve been using that plugin for years to modify JSX pragma.

1 Like

Hmm… I clearly must have been doing something wrong then. The babel stuff always confuses me…

I’ll give it another shot. Is this how you have it configured in your starter?

My starter is configured to change the pragma to h and then I set createComponent to a global instance of h in server and client. But I did change to the method above in a project and it seems to work.

1 Like

Hi @captainn @moberegger @edemaine @mikkelking could one of you submit a PR with this change to Meteor?

Maybe you also need to make some changes here babel-preset-meteor/modern.js at master · meteor/babel-preset-meteor · GitHub

I believe we still have time to include this on Meteor 2.3.

@storyteller and I would be glad to review asap and include it in the next beta.

1 Like

I can make a PR for simply adding the package to the default - but there are additional requirements beyond just adding it. This will only work with React 17+, so a check would need to be added, or the ability to change this setting back in .babelrc would need to be retained. I’m not sure how to do all that.

I saw this note in History.md

  • The @babel/preset-env and @babel/preset-react presets will be ignored by Meteor if included in a .babelrc file, since Meteor already provides equivalent/superior functionality without them. However, you should feel free to leave these plugins in your .babelrc file if they are needed by external tools.

and this comment in the babel compiler source

  // Similar reasoning applies to these commonly misused Babel presets:
  "@babel/preset-env",
  "@babel/preset-react",

I’m not sure it’s as trivial as simply changing the babel config. Meteor doesn’t use the react preset, and it sounds like adding it could conflict with the base setup. In other words, simply adding the preset would be “misusing” it, so they decided to ignore it.

We could add it to the base meteor templates in package.json for react projects. Meteor isn’t a “react” framework, and we can’t assume users will have the latest compatible version of react installed. But we can expose the setting in package.json. It’s not that much to add it (as I’ve shown above).

1 Like

Given that React recommends using @babel/preset-react, perhaps we could change the behavior of Meteor to, instead of ignoring that package, including @babel/plugin-transform-react-jsx in that case?