如何在其他站点上嵌入 React 组件?

Gam*_*mmi 5 javascript node.js ecmascript-6 reactjs webpack

我已经创建了 React 应用程序,我需要为其他网站生成嵌入代码。这是一个大型应用程序,我只想将一个组件作为其他域的小部件。我已阅读使用 React 和 Webpack 编写可嵌入的 Javascript 插件以及如何将React组件嵌入其他域?. 我设置了我的 webpack,但仍然无法在另一个域上呈现小部件。

这个小部件应该:

  1. 可以通过<script>标签获得,而不是 iframe
  2. 只显示应用程序的一部分(路径/referral),而不是所有应用程序

小部件是一个按钮和弹出窗口,通过单击按钮显示。

这是我webpack.config.jsclient文件夹:

const path = require('path');
const bundleOutputDir = './referral';
const env = require('yargs').argv.env;

module.exports = env => {
  const isDevBuild = !(env && env.prod);

  if (env === 'build') {
    mode = 'production';
  } else {
    mode = 'development';
  }

  return [
    {
      mode: mode,
      entry: './src/components/early-referrals/Referral.js',
      output: {
        filename: 'widget.js',
        path: path.resolve(bundleOutputDir),
        library: 'Referral',
        libraryTarget: 'umd',
        umdNamedDefine: true
      },
      devServer: {
        contentBase: bundleOutputDir
      },
      module: {
        rules: [
          { test: /\.html$/i, use: 'html-loader' },
          {
            test: /\.css$/i,
            use: [
              'style-loader',
              'css-loader' + (isDevBuild ? '' : '?minimize')
            ]
          },
          {
            test: /\.(png|jpe?g|gif)$/i,
            use: [
              {
                loader: 'file-loader'
              }
            ]
          },
          {
            test: /(\.jsx|\.js)$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: [
                  [
                    '@babel/env',
                    {
                      targets: {
                        browsers: ['ie 6', 'safari 7']
                      }
                    }
                  ]
                ]
              }
            }
          }
        ]
      }
    }
  ];
};
Run Code Online (Sandbox Code Playgroud)

这是 component RegisterReferral.js,它是 webpack 的入口点:

import PopupRef from '../popup/PopupRef';

const RegisterReferral = ({
...
}) => {
  const [...] = useState();

  useEffect(() => {
    ...
  }, []);

  return (
    <div>
        // some styles for button that displays popup
        <PopupRef />
    </div>
  );
};

const mapStateToProps = state => ({
  ...
});

export default connect(
  mapStateToProps,
  { ... }
)(RegisterReferral);
Run Code Online (Sandbox Code Playgroud)

PopupRef.js 是一个带有弹出窗口的组件,它应该显示在按钮内的其他网站上。

在 中App.js,我有这个组件的路由,我想创建一个可嵌入的组件:

<Route exact path="/referral" component={RegisterReferral} />
Run Code Online (Sandbox Code Playgroud)

这是我将代码粘贴到另一个域的一种方式:

// the URL in script is an URL of bundle file from webpack
<html>
    <head>
        <script src="http://example.com/client/referral/widget.js"  type="text/javascript"></script>   
    </head>
    <body>
        <p>Another website</p>
        <div id='app'></div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

另外,我尝试webpack.config.js使用Referral.js. 这是这个组件:

// Referral.js
import React from 'react';
import { render } from 'react-dom';
import App from './RegisterReferral.js';

render(<App />, document.getElementById('app'));

// At this case, webpack.config.js has 2 changes:
entry: './src/components/early-referrals/Referral.js',
output: {
        ...
        library: 'Referral',
      },

Run Code Online (Sandbox Code Playgroud)

什么都行不通。我的组件没有显示在其他网站上。

请帮助我找出问题所在,以及如何在其他网站上从 React 应用程序嵌入一个组件(不是所有应用程序)。

Ton*_*Ngo 0

假设您正确配置了 webpack 以捆绑 React js 代码

这就是我在任何我想要的页面中渲染组件的方式

假设我有这个组件

import React, {Component} from "react";
import {render} from "react-dom";

class LoginForm extends Component { }

render(<LoginForm/>, document.getElementById("loginForm")); // use render method
Run Code Online (Sandbox Code Playgroud)

编辑:

刚刚看到你的代码我认为你还需要更改index.html中的id

<div id="root"></div> 
Run Code Online (Sandbox Code Playgroud)

<div id="referral"></div> 
Run Code Online (Sandbox Code Playgroud)