LancerComet / vue2-jsx-runtime

JSX runtime for Vue 2.
Apache License 2.0
23 stars 6 forks source link

可用在 vue2+jsx 的非 ts 的项目吗 #4

Closed screetBloom closed 2 years ago

screetBloom commented 2 years ago

在非 ts 项目中是没有 ts.config.json 的,大概按照文档操作了一下,发现并没有 run 起来

想咨询一下这个目前是支持 vue2+jsx+js 的项目吗

如果需要工作量的话可以开个赞助,这个包我会赞助一些费用

LancerComet commented 2 years ago

可以的,这个包原则上可以用在任何支持 New JSX Transform 的工具链中 对于 TS 项目,TS 的两款编译器 SWC 跟 TSC 原生支持 对于纯 JS 项目,需要使用 Babel 去做转换 简单配置了一个 Webpack 5 的例子,可以参考一下: https://github.com/LancerComet/vue2-jsx-runtime-webpack

之后更新一下 JS 项目配置的说明

screetBloom commented 2 years ago

好的,十分感谢,可以增加一个赞助的二维码或者 github sponsor

另外追问一下如果项目 .js loader 如果已经切换为 swc-loader

config.module.rule('js').uses.clear().end().use('swc-loader').loader('swc-loader')


下述代码是放到 .swcrc 还是 babel.config.js

{
  'throwIfNamespace': false, // defaults to true
  'runtime': 'automatic', // defaults to classic
  'importSource': '@lancercomet/vue2-jsx-runtime' // defaults to react
}
LancerComet commented 2 years ago

放在 .swcrc 中:

{
  "jsc": {
    "transform": {
      "react": {
        "runtime": "automatic",  // Please set to "automatic" to enable new JSX transform.
        "importSource": "@lancercomet/vue2-jsx-runtime",  // Please set to the package name.
        "throwIfNamespace": false
      }
    }
  }
}
screetBloom commented 2 years ago

经过我的项目测试后,大多数基础 jsx 场景都 ok,但是发现了一个挺怪异的场景


可复现仓库

https://github.com/screetBloom/vuecli5-swc-jsx


问题描述

如果 jsx 文件中有下述代码,一定会报错:Module not found: Error: Can't resolve 'react' in xxx

return (
  <div>
    // 当 {...{}} 后还有其它属性时会报错: Module not found: Error: Can't resolve 'react' 
    <div {...{ props: {} }} key={item.name}>测试</div>
  </div>
)
image




猜测可能是这个场景下 jsx 代码编译后多注入了 react

LancerComet commented 2 years ago

因为我没有做 prop 合并,<div {...xxx} xxx={xxx} /> 这个写法我甚至没有单元测试测试

关于 key 这个属性,我在开发的时候发现一个特别奇怪的现象,我无法正确拿到 key 的值,所以我里在文档中额外声明了目前需要使用 v-bind:key

关于这两个问题我需要再看一下

如果急得话可以先把 prop 拆开,我个人不会这么写所以确实没有考虑 🤣

请把 key 改为 v-bind:key,prop merging 反而没有问题,这部分我补充一下单元测试.

LancerComet commented 2 years ago

我试下来,把 key 改为 v-bind:key 就好了 @screetBloom 关于 key 的这个目前看来确实是属于限制了,因为其实是架接于 react-jsx 之上,在处理 key 的时候编译器行为比较怪异,我还没有深入去看怎么回事.

screetBloom commented 2 years ago

好的,感谢,后续我也来看看如何参与建设

讲真的,来个赞赏码吧,不然太不好意思了

LancerComet commented 2 years ago

还好还好,客气了 如果除了 key 之外暂时没有其他问题的话我先 close 掉,如果还有问题的话请随时再开

songyazhao commented 2 years ago

最近把项目升了vuecli5、webpack5,babel-loader换成了esbuild-loader,可以正常运行.. 有需要的同学可以参考下面配置

  chainWebpack(config) {
    const jsRule = config.module.rule('js').test(/\.m?jsx?$/)
    jsRule.uses.clear() // 清理自带的babel-loader
    jsRule // 使用sbuild-loader
      .use('esbuild-loader')
      .loader('esbuild-loader')
      .options({
        target: 'es2015',
        loader: 'jsx',
        jsx: 'automatic',
        jsxImportSource: '@lancercomet/vue2-jsx-runtime'
      })
      .end()

    // 换用ESBuild-minimize-plugin
    config.optimization.minimizers.delete('terser')
    config.optimization
      .minimizer('esbuild')
      .use(ESBuildMinifyPlugin, [{ minify: true, css: true }])

    ...
  }
guohuihot commented 1 year ago

兄弟你这个插件和“@vue/babel-preset-jsx”是不是一样的效果?还是解决“@vue/babel-preset-jsx”v-model报错的问题?我是不是二选一就行了

LancerComet commented 1 year ago

@guohuihot

这个插件和 @vue/babel-preset-jsx 达成的目的是一样的,但实现方式不同 官方的 @vue/babel-preset-jsx 是一组 Babel 插件,使用 Babel 对 JSX 转换,转换为 Vue 可以使用的函数 vue2-jsx-runtime 是一个 Vue 使用的 new JSX transform 插件,这是处理 JSX 的另一种形式,编译器将 JSX 编译为“标准格式数据”,然后 vue2-jsx-runtime 去解析这些数据,然后在运行环境中实时处理,比如实现 v-model 等

官方之前的 v-model 一直有问题没有修复(不知道现在修复了没有),所以就做了这个库,使用的话二选一就可以;但因为实现不同,所以一些指令的行为细节有差距

关于 new JSX transform 可以看这里: Introducing the New JSX Transform