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

[Feat] Support new jsx - jsx-runtime #5085

Closed
dolymood opened this issue Dec 10, 2021 · 4 comments
Closed

[Feat] Support new jsx - jsx-runtime #5085

dolymood opened this issue Dec 10, 2021 · 4 comments

Comments

@dolymood
Copy link
Contributor

What problem does this feature solve?

Same feature issue in Vue2 vuejs/vue#12379.

See https://babeljs.io/docs/en/babel-plugin-transform-react-jsx for more details.

We can have a better JSX experience.

Even we can process all the directives/ref/slot features with vue/jsx functions.

Transform original jsx(...) input to vue.h(...)

What does the proposed API look like?

In:

/** @jsxImportSource vue */

const profile = (
  <div>
    <img src="avatar.png" class="profile" />
    <h3>{[user.firstName, user.lastName].join(" ")}</h3>
  </div>
)

Out:

import { jsx as _jsx } from "vue/jsx-runtime";
import { jsxs as _jsxs } from "vue/jsx-runtime";

const profile = _jsxs("div", {
  children: [
    _jsx("img", {
      src: "avatar.png",
      class: "profile",
    }),
    _jsx("h3", {
      children: [user.firstName, user.lastName].join(" "),
    }),
  ],
});
@caozhong1996
Copy link
Contributor

I don't quite get your meaning, we already have jsx-next, what is the different?

@yyx990803
Copy link
Member

Don't use the React JSX transform for Vue... they are not the same.

For Vue 3 you should be using https://github.com/vuejs/jsx-next

@dolymood
Copy link
Contributor Author

dolymood commented Dec 14, 2021

@yyx990803

The repo

I created a repo for support JSX runtime vue-jsx-runtime and examples vue-jsx-runtime-examples.

Runtime size:

  • minify Iife: 2.53Kb (no gzip)
  • ES Module: 8.79kb (no minify)

About examples( used TS):

Different with vue jsx-next

  • jsx-next is a plugin for Babel only.
  • vue-jsx-runtime can be used with Babel, TypeScript, swc, esbuild and more.

vue-jsx-runtime limits:

  • can not merge ele/component props
  • v-model syntax is little different with jsx-next - v-model

First of all

We should forget the react xx, something like babel-plugin-transform-react-jsx. Maybe babel and other tools can be renamed to other name, like: jsx-runtime. 😆

The advantages

  • "Standard" JSX supported, runtime jsx. It can be used with Babel, TypeScript, swc, esbuild and more...
  • Runtime transform JSX ast to vue render(). Simple and easy to extend and maintain
  • Maybe we can share transform logic with compile-core and compile-dom in the future

@morlay
Copy link

morlay commented Mar 24, 2023

@yyx990803 react-jsx just make a way to let us to define any jsx not just react

Once vue provider exports vue/jsx-runtime and vue/jsx-dev-runtime,
We could easy to make use to use vue jsx with current build tools typescript/esbuild/swc, not only babel.
Just with options "jsx": "react-jsx" and "jsxImportSource": "vue"

If you don't want rewrite too much, we could just wrap h instead.

Howerver, hope it could do some refactor.
Because the key logic is different, more context facebook/react#20031

// vue/jsx-runtime.ts
export const jsxs = (type: any, { children, ...otherProps }: any = {}, key: string | undefined) => {
  const props = key ? { ...otherProps, key } : otherProps;
  if (typeof type === "object") {
    return h(type, props, isProxy(children) ? children : () => children);
  }
  return h(type, props, children);
};

export const jsx = (type: any, { children, ...otherProps }: any = {}, key: string | undefined) => {
  const props = key ? { ...otherProps, key } : otherProps;
  if (children) {
    if (typeof type === "object") {
      return h(type, props, isProxy(children) ? children : () => children);
    }
    return h(type, props, children);
  }
  return h(type, props);
};
// vue/jsx-dev-runtime.ts
import { Fragment } from "vue";
import { jsx, jsxs } from "./jsx-runtime";

export { Fragment };

export function jsxDEV(
  type: any,
  props: any = {},
  key: string | undefined,
  _isStaticChildren: boolean,
  _source: object,
  _self: object
) {
  if (Array.isArray(props.children)) {
    return jsxs(type, props, key);
  }
  return jsx(type, props, key);
}
{
  "exports": {
    "./jsx-runtime": {
      "import": {
        "types": "./jsx-runtime.d.ts",
        "default": "./jsx-runtime.mjs"
      }
    },
    "./jsx-dev-runtime": {
      "import": {
        "types": "./jsx-dev-runtime.d.ts",
        "default": "./jsx-dev-runtime.mjs"
      }
    }
  },
}

@github-actions github-actions bot locked and limited conversation to collaborators Sep 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants