Code Monkey home page Code Monkey logo

babel-plugin-jsx's Issues

Issue with using className instead of just class

Hello team,

I am currently developing new library that would output JSX template, so this output could be used in Vue and React projects.

Unfortunately, I found this library does not adhere DOM API same way as React do. My issue is caused by using className instead of just class, because I am using object destructing I cannot use class keyword. Same situation would happen by using htmlFor instead of just for. Both class and for are reserved keywords and cannot be used in object destructing.

So I want to ask, if there is possibility to introduce new option to convert those two attributes.

Thanks

Develop VUE components using rollup,But the vue. CreateTextVNode unsuccessful

  • version
    vue: 3.0.0
    rollup:2.28.2
    @vue/babel-plugin-jsx: 1.0.0-rc.3

  • babel.config

{
  "plugins": ["@vue/babel-plugin-jsx"]
}
  • conponent detail
const bar: any = {
  name: "BBar",
  render() {
    return (
      <div class="bar">
        <div class="bar_text">aaa</div>
      </div>
    );
  },
};

bar.install = (app) => {
  app.component(bar.name, bar);
};

export default bar;
  • build file
var bar = {
      name: "BBar",
      render: function () {
        return vue.createVNode("div", {
          "class": "bar"
        }, [vue.createVNode("div", {
          "class": "bar_text"
        }, [vue.createTextVNode("aaa")])]);
      }
    };

    bar.install = function (app) {
      app.component(bar.name, bar);
    };
  • use component

When the page is displayed, the 'AAA' is not displayed, but the class name exists.

import bar from "../../lib/bar";
import App from "./App.vue";

const app = createApp(App);

app.use(bar );

app.mount("#app");
  • demo img
    image

  • supplement

  • brower console
    image

How does it work with vue-class-component?

When creating a project with the latest version of the vue cli (4.5.7), you can select jsx, typescript, or vue-class-component to create the project together, but errors are generated in the project.

<script lang="ts">
import { Options, Vue } from "vue-class-component";

@Options({})
export default class Home extends Vue {
  render(){
    return (
        <div>456</div>
    )
  }
}
</script>

JSX element type 'List' does not have any construct or call signatures.

上级组件:
import { defineComponent, ref, reactive } from "vue";
import List from "@/components/List";
const Home = defineComponent(() => {

const list = ref([
5
]);
const flag = ref(
false
);

const list2 = reactive([
2, 3, 4, 5, 6
])
console.log(list);
const handleClick = () => {
list2[2] = 1003;
}
const handleClick2 = () => {
list2[2] = -10000;
}
return () => (
<>
// 使用list组件

{
list.value.map((item) =>

{item}


)
}
{
flag.value ?

true

:

false


}

  {
    list2.map((item) =>
      <h1>{item}</h1>
    )
  }
</>

);
})
export default Home;

// list 组件
import { onMounted, ref } from "vue";
const List = {
setup() {
const num = ref(0);
onMounted(() => {
console.log('aaa')
});
return () =>

{num.value}

}
}

export default List;

Dynamic Components support

  1. What is the recommended way to use dynamic component in JSX? In my case it is reading component names from configuration and use it in JSX.
  2. Do you plan to add/replicate previous functionality

In vue2 with composition-api: I have the following (simplified) code:

export default defineComponent({
  name:  "c-item-description",
  props: {
    item:                  {
      type:    Object,
      default: () => ({}) 
    },
    presentationComponent: String,
  },
  setup(props, context) {
    const { dynamicComponentRef} = useItemDescriptionConfiguration(props);
    return () => {
      const DynamicComponent: any = dynamicComponentRef.value || "t-item-description";
      return (
        <keep-alive>
          <DynamicComponent
            item={props.item}
          />
        </keep-alive>
      );
    };
  }
});

I found a workaround. Is it supposed to be so?

import { defineComponent, computed, ref,getCurrentInstance } from 'vue';
export default defineComponent({
  name:  "tsx-world",
  props: {
    msg: String
  },
  setup(props, context) {
    const dynamicComponent = ref("local-title"); // read from configuration
    const myTitleRef = computed(()=>getCurrentInstance()?.appContext?.components[dynamicComponent.value]);
    return () => {
      const myTitle = myTitleRef.value;
      return (
        <myTitle
          msg="dynamic component"
        />
    );}
  }
});

Update not triggering with event listener on hoc

jsx: 1.0.0-beta.3
vue: 3.0.0-beta.23

import { h, Transition } from 'vue';

function MyTransition(props, ctx) {
  return h(Transition, ctx.slots.default);
}

setup() {
  const isOpen = ref(false);
  setInterval(() => { isOpen.value = !isOpen.value }, 1000);

  return () => <MyTransition>{isOpen.value && <h1>Visible</h1>}</MyTransition>;
}

does not seem to trigger an update on isOpen change. Converting it to an h function:

return () => h(MyTransition, isOpen.value ? <h1>Visible</h1> : null);
// or recommended
return () => h(MyTransition, () => isOpen.value ? <h1>Visible</h1> : null);

works fine though. I tried converting functional component to a normal component but the problem persists.

stable release date

when this plugin stable version will be released?
is there any thing not finished in the RC to consider it not stable ?

[docs] 文档可以补充具体一点

  • 建议使用vModel
  • 自定义组件建议使用vCustom
  • directives: { custom: customDirective }中customDirective 该怎么用
  • slots子组件该怎么写
  • emit怎么写

does not support slot、v-slot、 vSlot

<compoentA>
  <template slot="name"></template>
or
  <template vSlot="name"></template>
or
  <template v-slot="name"></template>
</componentA>

I can not get $slots.name

如何同时使用 RouterView / KeepAlive / Transition ?

目前的写法是

return (
        <div>
          <RouterView>
            {{
              default: ({ Component, route }: { Component: any; route: RouteLocation }) => {
                const name = route.meta.inTab ? 'fade' : null;

                const Content = (
                  <KeepAlive max={max} include={cacheTabs}>
                    <Component />
                  </KeepAlive>);

                return (
                  <Transition
                    name={name}
                    mode="out-in"
                    appear={true}
                  >
                    {Content}
                  </Transition>
                );
              },
            }}
          </RouterView>
        </div>

异常:

Uncaught (in promise) TypeError: Cannot read property '_' of null
    at initSlots (runtime-core.esm-bundler.js?5c40:2731)
    at setupComponent (runtime-core.esm-bundler.js?5c40:6183)
    at mountComponent (runtime-core.esm-bundler.js?5c40:3960)
    at processComponent (runtime-core.esm-bundler.js?5c40:3936)
    at patch (runtime-core.esm-bundler.js?5c40:3547)
    at componentEffect (runtime-core.esm-bundler.js?5c40:4053)
    at reactiveEffect (reactivity.esm-bundler.js?a1e9:42)
    at effect (reactivity.esm-bundler.js?a1e9:17)
    at setupRenderEffect (runtime-core.esm-bundler.js?5c40:4018)
    at mountComponent (runtime-core.esm-bundler.js?5c40:3976)

单独使用 RouteView + KeepAliveRouteView + Transition 都没有任何问题,就是 KeepAlive + Transition 一起就会出问题。

另外也尝试过使用 slots / defineAsyncComponent 等方式

<KeepAlive max={max} include={cacheTabs} v-slots={{default: ()=> <Component />}} />
// or
<KeepAlive max={max} include={cacheTabs} >
   {defineAsyncComponent(Component)}
</KeepAlive>

... Transition 一致
const Content = (
                  <Transition
                    name={name}
                    mode="out-in"
                    appear={true}
                  >
                    <Component />
                  </Transition>
                );
return (
                  <KeepAlive max={max} include={cacheTabs}>
                    <Content />
                  </KeepAlive>);

均只能 KeepAliveTransition 不在一起使用时正常。

在 vite 中测试了一下是可以一起使用的。 似乎 children 在 vite 是个array,在这边是个 object ? 不太清楚。。。

edit:

在KeepAlive外层加入 <div></div> 就不会报错,但Transition失效,估计要调整一下。

How to use v-model in component?

// index.tsx
image

// Modal.tsx
image

I refer <A v-model={[val, 'argument', ['modifier']]} />, but got typescript error.

Version:
vue: 3.0.2
@vue/babel-plugin-jsx: 1.0.0-rc.3
typescript: 3.9.7

KeepAlive combined with RouterView

const Slots = {
    default: (router) => (
        <KeepAlive>
            <component is={router.Component}></component>
        </KeepAlive>
    )
}
return () => (
   <KeepAlive>
       <router-view v-slots={Slots}></router-view>
   </KeepAlive>
)
[Vue warn]: Component is missing template or render function. 
  at <Anonymous is= {__v_isVNode: true, __v_skip: true, type: {…}, props: {…}, key: null, …}anchor: nullappContext: nullchildren: nullcomponent: nulldirs: nulldynamicChildren: nulldynamicProps: nullel: nullkey: nullpatchFlag: 0props: {ref: RefImpl, onVnodeUnmounted: ƒ}ref: {i: {…}, r: RefImpl}scopeId: nullshapeFlag: 4ssContent: nullssFallback: nullstaticCount: 0suspense: nulltarget: nulltargetAnchor: nulltransition: nulltype: {name: "XXXXXX", render: ƒ}__v_isVNode: true__v_skip: true__proto__: Object > 
  at <KeepAlive> 
  at <RouterView> 

use via cdn

Is there any way to use this jsx plugin via cdn? Just like babel.min.js do with react.

Extending the catalog of recognized built-in elements

Since Vue 3 allows for custom renderers as an alternative to @vue/runtime-dom, A custom runtime might have it's own collection of 'native' elements. See Vugel for a good example. It supports built-in tags like <shader> and <container>.

At the moment @vue/babel-plugin-jsx will flag unknown native elements as a callExpression (https://github.com/vuejs/jsx-next/blob/dev/packages/babel-plugin-jsx/src/utils.ts#L111) if they are not matched in the catalog of known svg or html tags. How can we allow new native elements to be compatible JSX in Vue?

开启optimize的影响具体是什么?

开启optimize的影响会有什么,看起来诱惑很大,但是又不知道具体影响会是什么。跟vue3的什么有关系。

开启和关闭具体的优化提升又是多少

How to disable imports or specify a custom file?

I'm using the compiled file in the browser (Chromium only), and I need to specify the path like this (otherwise it throws an error):

import { createApp, createVNode, createTextVNode } from "./vue-files/vue.esm-browser.js";

Even if I add this line manually, the plugin still adds

import { createVNode, createTextVNode } from "vue";

which causes an error.

P.S. I've found https://github.com/FollowmeTech/babel-plugin-replace-import-path which replaces the path automatically. Leaving it here in case someone finds it helpful, or if someone knows a better solution.

Component "default" in record with path "/book" is a function that does not return a Promise.

Hi, there is a problom when I use jsx-next。I try [email protected] with jsx-next. here.

.babel

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    "@vue/babel-plugin-jsx",
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": false,
        "helpers": true,
        "regenerator": true,
        "useESModules": false,
        "version": "7.0.0-beta.0"
      }
    ]
  ]
}

.package.json

{
// ...
"dependencies": {
    "axios": "^0.20.0",
    "classnames": "^2.2.6",
    "lodash": "^4.17.20",
    "vue": "^3.0.0-rc.10",
    "vue-cookies": "^1.7.4",
    "vue-i18n": "^8.21.0",
    "vue-router": "^4.0.0-beta.9",
    "vuex": "^4.0.0-beta.4"
  }
// ...
}

royter.js

import Layout from 'layout/Layout';

import Hello from 'views/Hello';
import Book from 'views/Book';

const routes = [
  {
    path: '/',
    component: Layout,
    children: [
      {
        path: '/',
        redirect: '/home',
      },
      {
        path: '/home',
        component: Hello,
      },
      {
        path: '/book',
        component: Book,
      },
    ],
  },
];

export default routes;

Business component

const Book = () => <div>this is Book component!</div>;

export default Book;

but, I got a error info.

runtime-core.esm-bundler.js:153 [Vue warn]: Component "default" in record with path "/book" is a function that does not return a Promise. If you were passing a functional component, make sure to add a "displayName" to the component. This will break in production if not fixed.

help me, thanks

[TSX]:怎样解决组件props为required时,使用v-model类型提示错误问题

组件定义Tag.tsx

import { defineComponent, PropType } from 'vue'

export default defineComponent({
  name: 'Tag',
  props: {
    value: {
      type: String as PropType<string>,
     // !!! 下一行代码是导致出错的地方
      required: true,
    },
  },
  emits: ['update:value'],
  setup(props, { emit }) {
    // 这里用InputEvent 会出错
    const handleInput = (e: any) => {
      emit('update:value', e.target.value)
    }

    return () => {
      const { value } = props

      return <input type="text" value={value} onInput={handleInput} />
    }
  },
})

组件使用demo.tsx

import { defineComponent, ref } from 'vue'
import Tag from './Tag'

export default defineComponent({
  setup() {
    const modelValue = ref('')

    return () => {
      return (
        <>
          <h1>{modelValue.value}</h1>
          {/* 这样写不出错,但太麻烦了 */}
          <Tag
            value={modelValue.value}
            {...{
              'onUpdate:value': ($event: string) => (modelValue.value = $event),
            }}
          />
          {/* !!!!! 下一行代码ts会出错 */}
          <Tag v-model={[modelValue.value, 'value']} />
        </>
      )
    }
  },
})

Feature Request: Support local relative img source in JSX

current

must declarative import from JS

import Logo from '@/assets/logo.png'

const App = defineComponent({
  setup() {
    return () => (<img alt="Vue logo" src={Logo} />)
  },
})

wanted

directly import local img by absolute path string

const App = defineComponent({
  setup() {
    return () => (<img alt="Vue logo" src="./assets/logo.png" />)
  },
})

provide used in function

import { provide } from 'vue';

cosnt Component =(props,{slots})=>{
provide('a',233);
return <div>slots.default()</div>
}

it produces [Vue warn]: provide() can only be used inside setup(). so it's my problem?

Transitions not working (insert transition node)

I'm actually working on a Vue3 project with rollup and babel (ES6).
The transition is inserted as a dom node and is not recognized by VueJS.

That's my code.

export default {
    // ...
 
    render() {
        return (
            <transition name="fade" mode="out-in">
                {this.title && <Title title={this.title} />}
            </transition>
        );
    }
};

Turn into this.

e.createVNode(
    e.resolveComponent("transition"),
    { name: "fade", mode:"out-in" },
    { default: () => [ this.game && e.createVNode(p, null, null) ] }
);

And looks like this in the DOM Tree.

<transition name="fade" mode="out-in"> <!-- Why this div exist ? -->
    <div id="title">
         You are <span class="secondary">Innocent</span>
    </div>
</transition>

I don't understand where the issue could come from, maybe a JSX translation error or an issue relative to Vue3 ?

slot中支持template标签么?

在slot中使用template标签不显示

const slots = { default: () => { <template> <NavMenuItem /> <NavMenuItem /> </template> } }

.vue 文件中使用 jsx, style 的 scoped 不起作用

style 的 scoped 生成的 data-v-xxxx, jsx 生成的为 data-v-xxxx-s

image

image

===

自己尝试看了一下源码, 没有解决的, 目前猜想是, jsx 的 vnode 丢失了 scopeId 属性, 导致 vue3 的 runtime 把 jsx 的 dom 当做了 slot.

因为 template 中执行了这个方法, 使得 vnode 获取了 scopeId

image

image

Bind multiple V- model.sync

template

<div  
    v-model:expandedKeys="expandedKeys"
    v-model:selectedKeys="selectedKeys"
    v-model:checkedKeys="checkedKeys">
</div>

How to use it in JSX?

<div 
v-model={[expandedKeys,'expandedKeys']}>
v-model={[selectedKeys,'selectedKeys']}>
</div>
JSX elements cannot have more than one attribute with the same name

function children should not be parsed

<Comp>
{() => <span></span>}
</Comp>

By default slot will be parsed to function to be performent, but if we write it to a function, it should stay that instead of wrap it to another function.

I think () => <span></span> is just what we called scopedSlot in vue.

error when use this package with vue 3 and vue router next

there is error when setup with vue 3 , vue router next . and this plugin

  • Vue : 3.0.0-beta.14
  • Vue Router : 4.0.0-alpha.12
  • @ant-design-vue/babel-plugin-jsx : 1.0.0-alpha.4

Home.jsx

export default {
  name: "Home",
  setup() {
    return () => (
      <div class="home">
        <img alte="Vue Logo" src="../assets/logo.png" />
      </div>
    );
  }
};

router/index.js

import { createRouter, createWebHashHistory } from "vue-router";
import Home from "../views/Home.jsx";

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home
  }
];

const router = createRouter({
  history: createWebHashHistory(),
  routes
});

export default router;

babel.config.js

module.exports = {
  presets: ["@vue/cli-plugin-babel/preset"],
  plugins: ["@ant-design-vue/babel-plugin-jsx"]
};

The Error when open home route in the console

TypeError: Cannot read property '$createElement' of undefined
    at setup (Home.jsx?6389:3)

Fragment with condition fails with undefined vnode

jsx: 1.0.0-beta.1
vue: 3.0.0-beta.20

return (
  <>
    <h1>test</h1>
    {false && (
      <h1>test</h1>
    )}
  </>
);

return (
  <>
    {false && (
      <h1>test</h1>
    )}
    <h1>test</h1>
  </>
);

Keeps failing with Invalid VNode type: undefined (undefined) error.

return (
  <>
    {false && (
      <h1>test</h1>
    )}
  </>
);

If you leave only the conditional, it works fine.

能否使用slots和KeepAlive缓存

vue template

<router-view v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" />
  </keep-alive>
</router-view>

How to use it in JSX?

Feature Request: $attrs type enhancement

const Child = defineComponent({
  props: {
    label: String
  },
  setup(_, ctx) {
    return () => [
      <div>{_.label}</div>,
      <input {...ctx.attrs}/>
    ];
  }
});

const Parent = defineComponent(() => {
  return () => <Child label="test" placeholder="please input"/>;
});

This code will show a error as following.

Type '{ label: string; placeholder: string; }' is not assignable to type 'IntrinsicAttributes & Partial<{}> & Pick<Readonly<{} & { label?: string | undefined; }> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "label" | ... 9 more ... | "class">'.
Property 'placeholder' does not exist on type 'IntrinsicAttributes & Partial<{}> & Pick<Readonly<{} & { label?: string | undefined; }> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "label" | ... 9 more ... | "class">'

how to bind event?

I tried v-on, on, vOn, none worked. What is the correct way to bind an event?

Migrate jsx compoents

Some of my components are written in jsx (vue@2)
For example:

<script>
  import isArray from 'lodash/isArray'
  import isFunction from 'lodash/isFunction'
  import map from 'lodash/map'
  import { NewBsBox } from '@myComp'

  export default {
    name: 'Paragraph',
    functional: true,
    props: {
      content: {
        type: [String, Function, Array],
      },
      bs: {
        type: Object,
        default: () => ({}),
      },
    },
    render(h, { props }) {
      const { content, bs } = props
      let lst = content
      if (!isArray(lst)) {
        lst = [lst]
      }
      return (
        <NewBsBox bs={bs}>
          {
            map(lst, txt => {
              let text = txt
              if (isFunction(text)) {
                text = text(h)
              }
              return <NewBsBox>{text}</NewBsBox>
            })
          }
        </NewBsBox>
      )
    },
  }
</script>

If migrate to vue@3. Do i have to rewrite all my jsx components?

Should support passing object slots via JSX children

I may have missed the reasoning but I just noticed the usage of v-slots which is quite odd.

A more straightforward syntax should be:

const slots = {
  default: () => <div>default</div>,
  foo: () => <div>bar</div>
}
<Comp>{slots}</Comp>

Or inline:

<Comp>{{
  default: () => <div>default</div>,
  foo: () => <div>bar</div>
}}</Comp>

Directives is not working properly

Vite jsx Directives is not working properly

const App = {
  data() {
    return { visible:false};
  },
  render() {
    return <input v-show={this.visible} />;
  },
};

Browser display:

<input v-show="false">

Directives did not parse properly
custom directive did not parse properly

antd vue

import { SearchOutlined } from '@ant-design/icons-vue';
vite 
runtime-dom.esm-bundler-4d575bf8.js:1180 [Vue warn]: SyntaxError: The requested module '/@modules/tinycolor2/tinycolor.js' does not provide an export named 'default'

Webpack HMR not working

I am using vue js, without cli, since I need to configure webpack myself. I couldn't make jsx (vuejs 3) hot update by webpack HMR, and documentation about it is really poor and I spent several hours searching and trying to make it work.

Is there any package, which provides need loader?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.