You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ReactJS+TypeScript组件导出给Vanilla JS和HTML使用?

将React组件导出为Vanilla JS/HTML可用的独立产物(无需引入React)

下面是几种简便可行的方案,无需react-scripts eject:

方案1:打包为Web Components(自定义元素)

Web Components是原生标准,可直接在纯HTML/JS中使用,完全不需要依赖React。步骤如下:

  1. 安装打包依赖
npm install @babel/core @babel/preset-react @babel/preset-env rollup rollup-plugin-babel rollup-plugin-postcss rollup-plugin-terser --save-dev
  1. 配置Rollup
    在项目根目录创建rollup.config.js:
import babel from 'rollup-plugin-babel';
import postcss from 'rollup-plugin-postcss';
import { terser } from 'rollup-plugin-terser';

export default {
  input: 'src/YourMainComponent.jsx', // 你的主组件入口
  output: {
    file: 'dist/your-custom-element.js',
    format: 'iife', // 生成浏览器可直接运行的自执行函数
    name: 'YourComponentBundle'
  },
  plugins: [
    babel({
      presets: ['@babel/preset-react', '@babel/preset-env'],
      exclude: 'node_modules/**'
    }),
    postcss({
      inject: true, // 把CSS打包进JS,无需单独引入样式文件
      minimize: true
    }),
    terser() // 压缩代码
  ]
};
  1. 改造组件为自定义元素
    修改你的主组件文件,用原生自定义元素API包裹:
import React from 'react';
import ReactDOM from 'react-dom/client';
import YourChildComponent from './YourChildComponent';
import './YourComponent.css';

// 自定义元素类
class YourCustomElement extends HTMLElement {
  connectedCallback() {
    // 当元素被添加到DOM时渲染React组件
    const root = ReactDOM.createRoot(this);
    root.render(<YourComponent {...this.getPropsFromAttrs()} />);
  }

  // 将HTML属性转为React props
  getPropsFromAttrs() {
    return Object.fromEntries(
      Array.from(this.attributes).map(attr => [attr.name, attr.value])
    );
  }
}

// 注册自定义元素
customElements.define('your-component', YourCustomElement);
  1. 打包并使用
    运行打包命令:
npx rollup -c

然后在纯HTML中直接使用:

<script src="dist/your-custom-element.js"></script>
<!-- 直接用自定义标签,属性会自动转为组件props -->
<your-component title="示例标题" desc="这是一个React转Web组件的示例"></your-component>

方案2:用Vite打包为独立JS库(内置React)

如果不想改造成Web组件,可以用Vite的库模式把React和组件一起打包成单个JS文件,浏览器直接引入即可:

  1. 配置Vite
    创建vite.config.js:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    lib: {
      entry: 'src/YourComponent.jsx',
      name: 'YourComponent',
      formats: ['iife'],
      fileName: () => 'your-component.bundle.js'
    },
    rollupOptions: {
      // 将React和ReactDOM打包进产物,不依赖外部引入
      external: [],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM'
        }
      }
    }
  }
});
  1. 打包并使用
    运行npm run build,生成的dist/your-component.bundle.js可直接在HTML中使用:
<script src="dist/your-component.bundle.js"></script>
<script>
  // 手动挂载组件到DOM
  const container = document.getElementById('app');
  ReactDOM.createRoot(container).render(React.createElement(YourComponent, { title: 'Hello' }));
</script>
<div id="app"></div>

方案3:替换React为轻量替代库(如Preact)

Preact体积仅3KB,API和React几乎完全兼容,迁移成本极低,打包后的产物更小:

  1. 替换依赖
npm uninstall react react-dom
npm install preact preact-render-to-string
  1. 修改组件导入
    把所有React相关导入替换为Preact:
// 原代码
import React from 'react';
import ReactDOM from 'react-dom';

// 替换后
import { h } from 'preact';
import { render } from 'preact';
  1. 打包
    用Rollup或Vite按照方案1/2的方式打包,最终产物包含Preact,直接在HTML中引入使用即可。

方案4:Parcel零配置打包

Parcel无需复杂配置,适合快速打包:

  1. 安装Parcel
npm install -D parcel
  1. 创建入口文件
    新建src/index.jsx,内容为组件挂载逻辑(可参考方案1的自定义元素写法)。
  2. 打包
npx parcel build src/index.jsx --no-source-maps --dist-dir dist

生成的dist/index.js可直接在HTML中引入使用。

关键注意点

  • 确保打包时将所有依赖(包括React/Preact、CSS、子组件)都打包进单个文件,避免外部依赖。
  • 如果组件用到状态管理库(如Redux),需将其也加入打包流程。

内容的提问来源于stack exchange,提问作者ibrahimtuna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:46:35