react icon indicating copy to clipboard operation
react copied to clipboard

umd distribution for jsx-runtime

Open WGroenestein opened this issue 3 years ago • 8 comments

Our module infrastructure relies on 3rd party dependencies to be available as global variables which we internally map in our module system. We are currently looking into updating to 17.x and utlize the new JSX Transform, however we noticed that there is no umd distribution for the jsx-runtime resulting in that we are not able to map this new dependency into our module system.

The reason why we have not switched over to a modern module/build system is that we are still in the progress of migrating (over time) our stack to be on top of react and in the current version (16.x) using the "old" JSX Transform we are able to achieve this through the provided umd distribution.

We could of course stick to 16.x or 17.x with the "old" JSX Transform, however with the rebase to react we kind of want to be future proof at the same time, so being on the new Transform would be preferred imo.

I do understand this might be a bit of a far reach due to the proprietary module infrastructure, but I think more people could benefit from having the jsx-runtime at hand as umd distribution.

WGroenestein avatar Mar 03 '21 09:03 WGroenestein

Talking about WordPress development, WordPress/Gutenberg also includes react & react-dom globally (at least when editing using Gutenberg or inside customizer).

We can stick to use the classic runtime. But yea, I think it would be awesome if there's UMD distribution of jsx-runtime.

contactjavas avatar Sep 12 '21 15:09 contactjavas

Some update about it? jsx runtime in umd is very needed for libraries that uses it as peer dependency with umd React

gbrocha avatar Oct 21 '21 22:10 gbrocha

Any news on this? It would be interesting to have it.

heldergoncalves92 avatar May 10 '22 17:05 heldergoncalves92

I just looked at the minified production source for React 17.0.2 and realized this is quite easy to do yourself. Tough the JSX runtime does depend on "react".

(function (exports) {
  /** @license React v17.0.2
   * react-jsx-runtime.production.min.js
   *
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   */
  "use strict";
  var f = require("react"),
    g = 60103;
  exports.Fragment = 60107;
  if ("function" === typeof Symbol && Symbol.for) {
    var h = Symbol.for;
    g = h("react.element");
    exports.Fragment = h("react.fragment");
  }
  var m =
      f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,
    n = Object.prototype.hasOwnProperty,
    p = { key: !0, ref: !0, __self: !0, __source: !0 };
  function q(c, a, k) {
    var b,
      d = {},
      e = null,
      l = null;
    void 0 !== k && (e = "" + k);
    void 0 !== a.key && (e = "" + a.key);
    void 0 !== a.ref && (l = a.ref);
    for (b in a) n.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
    if (c && c.defaultProps)
      for (b in ((a = c.defaultProps), a)) void 0 === d[b] && (d[b] = a[b]);
    return {
      $$typeof: g,
      type: c,
      key: e,
      ref: l,
      props: d,
      _owner: m.current,
    };
  }
  exports.jsx = q;
  exports.jsxs = q;
})((globalThis.ReactJsxRuntime = {}));

I stripped the "object-assign" polyfill.

Minified production runtime exposed as ReactJsxRuntime in the global environment.

leidegre avatar Sep 22 '22 14:09 leidegre

My current understanding is we're planning to eventually deprecate/remove UMD builds altogether in favor of ESM builds. I'm guessing this would mean you could set up an import map, and have it point inside the npm package?

gaearon avatar Sep 22 '22 15:09 gaearon

How would an ESM build expose react if I was to load it from a CDN?

Will I still be able to access react from the global environment?

leidegre avatar Sep 22 '22 17:09 leidegre

You'd use <script type="module"> and import statements.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

gaearon avatar Sep 22 '22 17:09 gaearon

Okay so this

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>

becomes

<script type="module">
import React from "https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"
window.React = React // or whatever you want
</script>

but that won't work with subresource integrity which I find important when pulling scripts from CDN.

leidegre avatar Sep 23 '22 06:09 leidegre

look it https://github.com/reactjs/reactjs.org/issues/5659

idler8 avatar Mar 15 '23 15:03 idler8

@idler8 react/jsx-runtime is currently not distributed as UMD. In my opinion, it's probably never going to be the case because ESM is coming.

If your project is using Typescript and until the ESM builds are available, I suggest you to use the following TS config:

{
  "compilerOptions": {
    "jsx": "react"
  }
}

With "jsx": "react", react/jsx-runtime is not required.

Downside: like @leidegre explain it in the comment below, you will lose all benefits of the work done to improve React performance via the JSX runtime

GabrielDelepine avatar Apr 27 '23 16:04 GabrielDelepine

@idler8 react/jsx-runtime is currently not distributed as UMD. In my opinion, it's probably never going to be the case because ESM is coming.

If your project is using Typescript and until the ESM builds are available, I suggest you to use the following TS config:

{
  "compilerOptions": {
    "jsx": "react"
  }
}

With "jsx": "react", react/jsx-runtime is not required

You understand that this forgoes all benefits of the work done to improve React performance via the JSX runtime? Why would you just "turn it off"?

leidegre avatar May 01 '23 05:05 leidegre

Hey,

I'm facing an issue in my monorepo project, where I have shared React components among different libraries within the workspace. These components are integrated into a legacy application through web components. To maintain consistency in React versions in the browser, React and React DOM are excluded from the final build and are treated as external dependencies, using vite.

The problem I'm encountering is when I use a component from library A with a component from library B, such as <A comp={<B className="w-4 h-4" />} />. Due to the presence of multiple JSX runtimes (caused by the inability to include the runtime in UMD in the browser), I encounter various issues. For instance, the runtime of library A doesn't detect a key on component B, resulting in an error as if I were using .map on an array without specifying a key={} prop. As an example: https://imgur.com/a/s6vzOi8. I may give a reproduction if necessary.

My current workaround involves manually adding a key={} prop to the passed components, but I believe this shouldn't be necessary, and I may have other problems. I've also considered switching to classic mode or modifying the jsxFactory of esbuild, but these options may lead to the loss of certain optimizations, as explained by @leidegre.

I'm wondering if there have been any developments on this issue, and if anyone has a better solution for a monorepo that ensures a single JSX runtime.

Thanks!

Edit on 2023-11-15 If anyone passing by has the same problem, I've since put in place a much simpler solution. My solution is the one recommended by most React libs, I externalize the runtime and it's up to the final implementation (and compiler) to integrate this runtime. So I only have one runtime. Example with Vite:

// vite.config.ts
const config = mergeConfig(defaultConfig, {
  build: {
    lib: {
      entry: path.resolve(__dirname, 'src/lib/index.ts'),
      name: 'XLib',
    },
    rollupOptions: {
      external: ['react/jsx-runtime'],
    },
  },
});

Gregory-Gerard avatar Sep 11 '23 23:09 Gregory-Gerard

A year has passed since Dan mentioned that you are working on ESM. Is there a thread or anything where we can track the progress? Not relying on legacy tooling and formats would be a pretty huge step in the right direction IMO.

noherczeg avatar Nov 15 '23 14:11 noherczeg

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Apr 10 '24 14:04 github-actions[bot]

We still really need this feature, otherwise, as component library developers, we would have to import React in each file, which is really painful.

NWYLZW avatar Apr 10 '24 14:04 NWYLZW

We're removing all UMD builds, in favor of esm.sh for the demo use case, so I think it's safe to say we won't do this.

https://github.com/facebook/react/pull/28735

sebmarkbage avatar Apr 17 '24 14:04 sebmarkbage