npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

transform-component

v0.2.0

Published

transform component to vue2/vue3/react

Readme

transform-component - 转换不同类型的渲染组件

前言

背景

在一些时候,当前项目技术栈可能是React,但是要引入一个vue3的组件,或者不同运行时的react组件

所以,一个跨技术栈、跨运行时,且支持插槽的组件转换器就来了

说明

支持转换的组件类型: vue@2, vue@3, react, none(无框架,类微前端) 支持在支持类型间任意转换

  • shimer - 组件垫片方法;用于创建一个宿主组件来接收节点、参数
  • renderer - 组件渲染方法;用于通过接收的参数在指定节点下渲染组件
  • transformer - 组件转换方法; 类似 shimer(wrapEl => renderer(Component, wrapEl))

用法

import transformComponent from 'transform-component'

/**
 * @desc 转换渲染组件
 * @param {string} sourceType - 来源组件类型 - ['vue2', 'vue3', 'react', 'none']
 * @param {string} targetType - 目标组件类型 - ['vue2', 'vue3', 'react', 'none']
 * @param {object|function} Component - 要转换的组件
 * @param {object} sourceOptions - 来源组件的渲染参数
 * @param {object} targetOptions - 目标组件渲染参数
 * @return {object|function}
 */
const TargetCOmponent = transformComponent(sourceType, targetType, SourceComponent, sourceOptions, targetOptions)
console.log(TargetCOmponent)

查看所有的支持类型

import { transformers, shimers, renderers } from 'transform-component'

// 默认支持的组件类型转换器对象 - transformComponent的快捷形式
console.log(transformers)
// [
//   "react2react",
//   "react2vue3",
//   "react2vue2",
//   "react2none",
//   "vue32react",
//   "vue32vue3",
//   "vue32vue2",
//   "vue32none",
//   "vue22react",
//   "vue22vue3",
//   "vue22vue2",
//   "vue22none",
//   "none2react",
//   "none2vue3",
//   "none2vue2",
//   "none2none"
// ]

// 默认支持的垫片组件类型对象
console.log(shimers)
// [
//   "react",
//   "vue@3",
//   "vue@2",
//   "none"
// ]

// 默认支持的渲染组件类型对象
console.log(renderers)
// [
//   "react",
//   "vue@3",
//   "vue@2",
//   "none"
// ]

示例

react -> vue3

import React from 'react'
import ReactDOM from 'react-dom'
import Vue from 'vue'
import ReactComponent from 'some-react-component'

// 方案一
import transformComponent from 'transform-component'
const Vue3Component = transformComponent('react', 'vue@3', ReactComponent, { React, ReactDOM }, { Vue })

// 方案二
import { transformers } from 'transform-component'
const Vue3Component = transformers.react2vue3(ReactComponent, { React, ReactDOM }, { Vue })

transformers.react2vue3 是 transformComponent.bind(null, 'react', 'vue@3') 的快捷形式

react -> none - 直接渲染组件到dom

import React from 'react'
import ReactDOM from 'react-dom'
import ReactComponent from 'some-react-component'

// 方案一
import transformComponent from 'transform-component'
const renderTo = transformComponent('react', 'none', ReactComponent, { React, ReactDOM })

// 方案二
import { transformers } from 'transform-component'
const renderTo = transformers.react2none(ReactComponent, { React, ReactDOM })

// 渲染方法
const { dispose, setProps} = renderTo(document.querySelector('#app'))

transformers.react2none 约等于 renderer.react 即直接渲染该组件

vue3 -> react

import React from 'react'
import ReactDOM from 'react-dom'
import Vue from 'vue'
import Vue3Component from 'some-vue3-component'

// 方案一
import transformComponent from 'transform-component'
const ReactComponent = transformComponent('vue@3', 'react', Vue3Component, { Vue }, { React, ReactDOM })

// 方案二
import { transformers } from 'transform-component'
const ReactComponent = transformers.vue32react(Vue3Component, { Vue }, { React, ReactDOM })

vue3 -> vue2

import Vue2 from 'vue@2'
import Vue3 from 'vue@3'
import Vue3Component from 'some-vue3-component'

// 方案一
import transformComponent from 'transform-component'
const Vue2Component = transformComponent('vue@3', 'vue@2', Vue3Component, { Vue: Vue3 }, { Vue: Vue2 })

// 方案二
import { transformers } from 'transform-component'
const Vue2Component = transformers.vue32vue2(Vue3Component, { Vue: Vue3 }, { Vue: Vue2 })

其余未列出的类型转换,与上面示例同理

扩展

扩展渲染方法 - renderer

import { renderers } from 'transform-component'

// 声明渲染器
const renderSomeTypeComponent = (SomeTypeComponent: Function | Object, wrapEl: HTMLElement, rendererOptions: Object) => {
  const {
    // 组件依赖包
    SomeTypeRender,
    // 默认的props; 变更时通过 setProps 接收
    props,
    // 默认的插槽; 变更时通过 setSlots 接收
    slots,
  } = rendererOptions

  // 在指定节点下渲染该组件 - 伪代码
  SomeTypeRender.renderComponent(SomeTypeComponent, wrapEl)

  // 实现下列方法
  // 释放组件时调用方法
  const dispose = () => void
  // 组件props变更时调用方法
  const setProps = (newProps: Object) => void
  // 抽象的插槽变更时调用方法
  const setSlots = (newSlots: SlotsObject) => void

  interface SlotsObject {
    [slotKey: string]: (slotArgs: Array<any>, slotWrapEl: HTMLElement) => void;
  }

  // 返回渲染控制方法
  return {
    dispose,
    setProps,
    setSlots,
  }
}

// 声明渲染器的依赖
renderSomeTypeComponent.deps = {
  // 默认的变量名: 默认的包名
  SomeTypeRender: 'some-type-render',
}

// 接入渲染器
renderers.someType = renderSomeTypeComponent

扩展垫片方法 - shimer

import { shimers } from 'transform-component'

// 声明渲染器
const createSomeTypeComponent = (renderToElement: Function, shimerOptions: Object) => {
  const {
    // 组件依赖包
    SomeTypeRender,
  } = shimerOptions

  // 声明一个新组件 - 伪代码
  const SomeTypeComponent = (props) => {

    // 组件挂载时触发 dispose
    let rendererHandle
    onMount(() => {
      const shimEl = shimRef.current
      rendererHandle = renderToElement(shimEl, {
        props,
      })
    })

    // 组件卸载时触发 dispose
    onUnMount(() => {
      rendererHandle.dispose()
    })

    // 组件props变更时触发 setProps
    onPropsChange(() => {
      rendererHandle.setProps(props)
    })

    // 组件slots变更时触发 setSlots
    const slotsParams = {}
    onSlotsChange(() => {
      const slots = {}
      someTypeSlotKeys.forEach(key => {
        slots[key] = (slotArgs, slotWrapEl) => {
          slotsParams[key] = [slotArgs, slotWrapEl]
        }
      })
      rendererHandle.setSlots(slots)
    })

    // 接收到slots参数回调时 生成构造插槽节点
    const fakeSlotsNodes = {}
    someTypeSlotKeys.forEach((key, i) => {
      const slotParams = slotsParams[key]
      if (slotParams && slotParams[1]) {
        const [slotArgs, slotWrapEl] = slotParams
        // const vnodes = someTypeSlotValues[i](...slotArgs)
        fakeSlotsNodes[key] = <Teleport to={slotWrapEl}>{vnodes}</Teleport>
      }
    })

    // 创建shim节点及构造的插槽节点
    return <div component-shim ref={shimRef}>{fakeSlotsNodes}</div>
  }

  // 返回生成的组件
  return SomeTypeComponent
}

// 声明渲染器的依赖
createSomeTypeComponent.deps = {
  // 默认的变量名: 默认的包名
  SomeTypeRender: 'some-type-render',
}

// 接入渲染器
shimers.someType = createSomeTypeComponent