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

如何打包NextJS 14.2.3 React组件以注入任意网站?

打包NextJS React组件用于嵌入外部网站(WordPress/任意站点)

针对你的需求,直接用Webpack打包单个NextJS组件容易出现React重复引入、Tailwind样式丢失、运行时不兼容等问题,下面提供两种可靠方案,涵盖基础组件打包及后续扩展(Stripe、lucide-react、API通信)的适配方法。

方案一:使用Rollup打包独立可嵌入组件(推荐)

Rollup更适合打包库/独立组件,能灵活处理依赖和模块格式,适配任意外部网站。

1. 安装打包依赖

npm install --save-dev rollup rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-typescript2 rollup-plugin-postcss @rollup/plugin-babel @babel/preset-react @babel/preset-env

2. 创建Rollup配置文件(rollup.config.js)

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
import postcss from 'rollup-plugin-postcss';
import babel from '@rollup/plugin-babel';

export default {
  input: './app/test.tsx',
  output: {
    file: './public/test-bundle.js',
    format: 'umd', // 兼容全局变量、AMD、CommonJS,适合嵌入任意网站
    name: 'TestComponent', // 组件挂载到window的全局变量名
    globals: {
      react: 'React',
      'react-dom': 'ReactDOM'
    }
  },
  external: ['react', 'react-dom'], // 不打包React,让宿主网站提供(减小bundle体积)
  plugins: [
    resolve(), // 解析node_modules中的依赖
    commonjs(), // 转换CommonJS模块为ES模块
    typescript({
      tsconfig: './tsconfig.json',
      useTsconfigDeclarationDir: true
    }),
    postcss({
      extract: './public/test-bundle.css', // 提取Tailwind样式到单独CSS文件
      minimize: true,
      modules: false
    }),
    babel({
      presets: ['@babel/preset-react', '@babel/preset-env'],
      exclude: 'node_modules/**',
      babelHelpers: 'bundled'
    })
  ]
};

3. 确认Tailwind配置(tailwind.config.js)

确保Tailwind能扫描到组件内的类名:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./app/**/*.{js,ts,jsx,tsx,mdx}"],
  theme: { extend: {} },
  plugins: [],
};

4. 添加打包脚本到package.json

{
  "scripts": {
    "build:component": "rollup -c"
  }
}

5. 执行打包

npm run build:component

执行后会在public/目录生成test-bundle.js和test-bundle.css。

6. 嵌入到外部网站

在目标网站的HTML中添加以下代码(替换路径为你的bundle实际地址):

<!-- 若宿主网站未引入React,需先加载 -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

<!-- 加载组件样式 -->
<link rel="stylesheet" href="/path/to/test-bundle.css">

<!-- 加载组件bundle -->
<script src="/path/to/test-bundle.js"></script>

<!-- 组件挂载容器 -->
<div id="test-component-root"></div>

<!-- 初始化组件 -->
<script>
  ReactDOM.render(React.createElement(TestComponent), document.getElementById('test-component-root'));
</script>

方案二:NextJS导出静态组件(适合依赖NextJS生态的场景)

如果组件依赖NextJS的特定能力(如Image组件),可通过NextJS的静态导出功能生成独立资源:

1. 修改next.config.mjs

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  distDir: 'public/component-build', // 导出到public目录下
};

export default nextConfig;

2. 创建单独的组件页面(app/embed/page.tsx)

import Test from '../test';

export default function EmbedPage() {
  return <Test />;
}

3. 执行NextJS构建

npm run build

构建后public/component-build/会生成静态HTML、JS和CSS,可通过iframe嵌入外部网站:

<iframe src="/path/to/component-build/embed" width="100%" height="200" frameborder="0"></iframe>

后续扩展适配

Stripe集成

  • 推荐让宿主网站加载官方Stripe脚本:<script src="https://js.stripe.com/v3/"></script>
  • 组件中直接使用window.Stripe初始化,避免打包Stripe增大体积。

lucide-react图标

  • Rollup会自动打包图标组件,无需额外配置;若需减小体积,可按需导入单个图标:
import { ShoppingCart } from 'lucide-react';

替代Server Actions(外部网站无法直接调用NextJS Server Actions)

  • 将Server Actions的逻辑抽离为NextJS API路由(app/api/xxx/route.ts)
  • 组件中用fetch调用API:
const handleSubmit = async () => {
  const res = await fetch('https://your-nextjs-domain/api/xxx', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ data: 'xxx' })
  });
  const data = await res.json();
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:35:14