veaury

repository·master·Indexed 23 days ago

https://github.com/gloriasoft/veaury

A bridge library that enables using React components in Vue 3 applications and vice versa. Veaury supports context sharing, cross-framework hooks, and a 'Pure Mode' to prevent extra element container wrappers. It provides configuration for Webpack, Vite, and SSR frameworks like Next.js and Nuxt.js, and includes utilities for lazy loading components and mapping slots between Vue and React.

Tokens
12.8K
Snippets
27
Records
66
Agent score
82%

What's inside veaury

  1. What is Veaury?

    master

    Veaury is a tool library designed to allow the seamless use of React components within Vue 3 applications, and Vue 3 components within React applications.

    Key Features:

    • Vue 3 Support: Fully compatible with Vue 3.
    • Context Sharing: Allows sharing context across Vue and React components.
    • Cross-Framework Hooks: Use React hooks in Vue components, or use Vue's setup function and hooks within React components.
    • Pure Mode: Prevents the creation of extra element container wrappers around converted components.
  2. Compare applyReactInVue and applyPureReactInVue

    master

    Veaury provides two primary methods for integrating React components into Vue applications, which differ in how they handle children (slots) passed from Vue to React:

    1. applyReactInVue (Normal Mode): This method does not perform conversion processing on VNodes. Instead, it creates a container to render VNodes uniformly. This is the standard way to wrap a React component for use in Vue.

    2. applyPureReactInVue (Pure Mode): This method directly converts VNodes into ReactNodes. When Vue components are encountered as children, a new container is created for them. This mode ensures that children and slots are rendered completely as pure ReactNodes within the React component tree.

    <script setup>
    import { applyPureReactInVue, applyReactInVue } from 'veaury'
    import AAReact from './react_app/AA'
    
    // Children and slots in the component will be rendered completely as pure ReactNode
    const AAWithPure = applyPureReactInVue(AAReact)
    
    // Normal mode: creates a container to render VNodes uniformly
    const AAWithNormal = applyReactInVue(AAReact)
    </script>
    
    <template>
      <AAWithPure>
        <div class="flex-sub">A</div>
      </AAWithPure>
    
      <AAWithNormal>
        <div class="flex-sub">A</div>
      </AAWithNormal>
    </template>
  3. Understand the Veaury project structure

    master

    The repository is organized into several key directories:

    • babel/: Contains Babel presets used by Webpack projects to handle simultaneous Vue and React JSX compilation.
    • dist/: Contains built distribution files (only updated during releases).
    • src/: The main source code for veaury.
    • types/: TypeScript type definitions.
    • vite/: Plugins for projects using Vite to handle mixed Vue/React compilation.
    • webpack/: Webpack plugins for projects using Webpack to handle mixed Vue/React compilation.
  4. Access framework context across boundaries

    master

    Veaury allows passing context (like react-router or vuex) across the framework boundary using two methods:

    1. useInjectPropsFromWrapper: An option for applyReactInVue or applyPureReactInVue. It allows you to run hooks from the host framework and pass the results as props to the guest component.
    2. Crossing Providers: Use createCrossingProviderForVueInReact or createCrossingProviderForPureReactInVue to create a provider/hook pair. This allows components deep in the tree to access context from the other framework without manual prop drilling.
    // Example: Injecting React Router into a Vue component
    import { applyVueInReact } from 'veaury'
    import { useLocation, useNavigate } from 'react-router-dom'
    
    export default applyVueInReact(AboveVueComponent, {
      useInjectPropsFromWrapper(reactProps) {
        const location = useLocation()
        const navigate = useNavigate()
        return {
          reactRouter: { navigate, location }
        }
      }
    })
  5. Pass slots between Vue and React

    master

    Veaury maps Vue slots to React patterns:

    Vue in React: Use the v-slots prop in JSX to pass named and scoped slots.

    • slot1: <div /> maps to <slot name="slot1" />.
    • slot2: ({value}) => <div /> maps to <slot name="slot2" value={...} />.
    • default: <div /> maps to <slot />.

    React in Vue: Use standard Vue <template v-slot:...> syntax.

    • Named slots with node: prefix (e.g., v-slot:node:slot3) are treated as React Nodes.
    • Default slots are treated as props.children.
  6. Access Context (Provide/Inject and Provider/useContext) across frameworks

    master

    Veaury enables context sharing between frameworks. If a component is wrapped and nested within a component of the same framework, Veaury uses Portal (React) or Teleport (Vue) to preserve the context tree.

    • React Context in Vue: Use createCrossingProviderForVueInReact to create a React Provider and a corresponding Vue hook. The React Provider wraps the Vue component, and the Vue component uses the hook to access the context.
    • Vue Provide/Inject in React: Use createCrossingProviderForPureReactInVue to create a Vue Provider and a corresponding React hook. The Vue Provider wraps the React component, and the React component uses the hook to access the context.
    // Creating a React-to-Vue crossing provider
    import { createCrossingProviderForVueInReact } from 'veaury'
    import { useLocation, useNavigate } from 'react-router-dom'
    
    const [useReactRouterForVue, ReactRouterProviderForVue] = createCrossingProviderForVueInReact(
      () => ({
        location: useLocation(),
        navigate: useNavigate()
      })
    )
    // Use ReactRouterProviderForVue in React, and useReactRouterForVue in Vue setup()
  7. Install Veaury via npm or yarn

    master

    To use Veaury in your project, install it using your preferred package manager.

    # Install with yarn:
    yarn add veaury
    
    # or with npm:
    npm i veaury -S
    # Install with yarn:
    $ yarn add veaury
    # or with npm:
    $ npm i veaury -S
  8. Configure Veaury in a React project via Webpack

    master

    To allow a React project to develop and run Vue3 files using Veaury, you must install the necessary dependencies and add the VeauryVuePlugin to your Webpack configuration.

    Prerequisites

    Install the following packages:

    • vue (latest version recommended)
    • veaury
    • vue-loader
    • @vue/babel-plugin-jsx

    Basic Configuration

    Add new (require('veaury/webpack/VeauryVuePlugin')) to your plugins array in webpack.config.js.

    // webpack.config.js
    // ...
    module.exports = {
      // ...
      plugins: [
        new (require('veaury/webpack/VeauryVuePlugin')),
        // ...
      ]
      // ...
    }
  9. Handle events between React and Vue

    master

    Events can be passed across frameworks seamlessly:

    1. React to Vue: When a Vue component is wrapped in React, you can trigger Vue events (e.g., $emit('click')) by passing a standard React prop like onClick to the wrapped component.
    2. Vue to React: When a React component is wrapped in Vue, you can trigger React functions (e.g., props.onClick()) by using Vue's event syntax (e.g., @click="handler") on the component.
    // React calling Vue event
    <Basic onClick={onClickForVue}/>
    <!-- Vue calling React event -->
    <template>
      <ReactButton @click="onClickForReact"/>
    </template>
  10. Configure Veaury for Vite projects

    master

    If your project uses Vite and contains both .vue and .jsx/.tsx files, you must configure the veauryVitePlugins to handle the different JSX parsing requirements.

    First, ensure you have installed the following dependencies:

    • @vitejs/plugin-react
    • @vitejs/plugin-vue
    • @vitejs/plugin-vue-jsx

    Main project is Vue

    When the primary project is Vue, set type: 'vue'. In this mode, JSX in files within a directory named react_app will be parsed as React JSX; all other JSX will be parsed as Vue JSX.

    Main project is React

    When the primary project is React, set type: 'react'. In this mode, JSX in .vue files and files within a directory named vue_app will be parsed as Vue JSX; all other JSX will be parsed as React JSX.

    Custom compilation scope

    Set type: 'custom' to use vueJsxInclude and vueJsxExclude (regex arrays) to define exactly which files should be parsed as Vue JSX.

    import { defineConfig } from 'vite'
    import veauryVitePlugins from 'veaury/vite/index.js'
    
    export default defineConfig({
      plugins: [
        veauryVitePlugins({
          type: 'vue',
          // vueOptions: {...}, 
          // reactOptions: {...}, 
          // vueJsxOptions: {...}
        })
      ]
    })
  11. Configure Veaury for Vite (React Main Project)

    master

    Case 2: Main project is React

    Disable the standard react() plugin and use veauryVitePlugins({ type: 'react' }). When type is set to 'react', all .vue files and JSX files within a directory named vue_app will be compiled as Vue JSX; all other JSX files will be compiled as React JSX.

    import { defineConfig } from 'vite'
    import veauryVitePlugins from 'veaury/vite/index.js'
    
    export default defineConfig({
      plugins: [
        // react(),
        veauryVitePlugins({
          type: 'react'
        })
      ]
    })
  12. Configure Veaury for Vite

    master

    If your project uses Vite, you must configure vite.config.js using veauryVitePlugins. You should first install @vitejs/plugin-react, @vitejs/plugin-vue, and @vitejs/plugin-vue-jsx.

    Depending on your module system, import the plugin as follows:

    • CommonJS (vite.config.cjs): import veauryVitePlugins from 'veaury/vite/cjs/index.cjs'
    • ESM (vite.config.mjs): import veauryVitePlugins from 'veaury/vite/esm/index.mjs'
    • Standard JS (vite.config.js): import veauryVitePlugins from 'veaury/vite/index.js'

    Case 1: Main project is Vue

    Disable the standard vue() and vueJsx() plugins and use veauryVitePlugins({ type: 'vue' }). When type is set to 'vue', JSX in files named react_app will be compiled as React JSX; all other JSX files will be compiled as Vue JSX.

    import { defineConfig } from 'vite'
    import veauryVitePlugins from 'veaury/vite/index.js'
    
    export default defineConfig({
      plugins: [
        // vue(),
        // vueJsx(),
        veauryVitePlugins({
          type: 'vue'
        })
      ]
    })