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

umd distribution for jsx-runtime #20923

Closed
WGroenestein opened this issue Mar 3, 2021 · 16 comments
Closed

umd distribution for jsx-runtime #20923

WGroenestein opened this issue Mar 3, 2021 · 16 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@WGroenestein
Copy link

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.

@eps1lon eps1lon added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Mar 3, 2021
@contactjavas
Copy link

contactjavas commented Sep 12, 2021

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.

@gbrocha
Copy link

gbrocha commented Oct 21, 2021

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

@heldergoncalves92
Copy link

heldergoncalves92 commented May 10, 2022

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

@leidegre
Copy link
Contributor

leidegre commented Sep 22, 2022

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.

@gaearon
Copy link
Collaborator

gaearon commented Sep 22, 2022

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?

@leidegre
Copy link
Contributor

leidegre commented Sep 22, 2022

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?

@gaearon
Copy link
Collaborator

gaearon commented Sep 22, 2022

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

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

@leidegre
Copy link
Contributor

leidegre commented Sep 23, 2022

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.

@idler8
Copy link

idler8 commented Mar 15, 2023

look it
reactjs/react.dev#5659

@GabrielDelepine
Copy link

GabrielDelepine commented Apr 27, 2023

@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

@leidegre
Copy link
Contributor

leidegre commented May 1, 2023

@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"?

@Gregory-Gerard
Copy link

Gregory-Gerard commented Sep 11, 2023

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'],
    },
  },
});

@noherczeg
Copy link

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.

Copy link

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 github-actions bot added the Resolution: Stale Automatically closed due to inactivity label Apr 10, 2024
@NWYLZW
Copy link

NWYLZW commented Apr 10, 2024

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

@github-actions github-actions bot removed the Resolution: Stale Automatically closed due to inactivity label Apr 11, 2024
@sebmarkbage
Copy link
Collaborator

sebmarkbage commented Apr 17, 2024

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.

#28735

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests