【问题标题】:Import or require a bundled js file created by react application导入或需要由 react 应用程序创建的捆绑 js 文件
【发布时间】:2017-07-12 11:23:40
【问题描述】:

假设我有一个使用 redux 和一些 ajax 调用的普通反应应用程序。 如果我想将它传递给某人,我会给他们我使用 webpack 创建的捆绑 js 文件,并要求他们将其包含在他们的 HTML 中 + 渲染一个具有“myApp”的 id 的 div,例如:

<div id="myApp"></div>

好的,如果他们的网站也是用 react 创建的,并且他们想将我捆绑的 js 文件包含在他们的一个组件中,当然还要渲染相关的 div 怎么办?

我尝试使用importrequire 来模拟这个:
require('./path/to/myBundle.js');
import './path/to/myBundle.js';

例子:

    //...
    import './path/to/myBundle.js'; // the file that will render myApp to the relevant div
    // ....
    export function SomeApp(args){
            return(
                <div>  
                    <div id="myApp"></div>
                    <SomeComponent />
                </div>
            );
        };`

这不起作用,因为我收到一些错误:

未捕获的错误:缩小的 React 错误 #37;访问 http://facebook.github.io/react/docs/error-decoder.html?invariant=37 获取完整消息或使用非缩小开发环境获取完整信息 错误和其他有用的警告。

当我访问这个网站时,我看到:

_registerComponent(...):目标容器不是 DOM 元素。

但是,如果他们在他们的组件之外(例如顶级index.html)使用这个文件(myBundle.js),它当然可以正常工作。

编辑: 我忘了提到我想我知道问题出在哪里,应用程序还没有准备好带有这个div 的 HTML。但我不知道等待它存在的好方法。

在@Frxstrem 的回答之后编辑#2: 我正在尝试遵循这个答案,但我认为我做错了。 我有 2 份 corry house slingshot demo app 作为 app1 和 app2。 将 app1 的 webpack.config.prod.js 上的“输出”更改为:

  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/',
    filename: 'app1Bundle.js',
    library: "App1",
    libraryTarget: "umd"
  },

我正在尝试在 app2 的主页组件中呈现 app1。 所以我将“已发布”文件从 app1 复制到 app2 的根目录并调用文件夹 app1,然后添加了导入调用:

import {app1} from '../../app1/app1Bundle';

以及返回函数内的匹配标签:

const HomePage = () => {
  return (
    <div>
      <app1 />
      <h1>App 2</h1>
    </div>
  );
};

我收到与上面发布的相同的错误。

我也尝试了不同的组合:

import app1 from '../../app1/app1Bundle'; // without curly braces

甚至只是将脚本作为普通的 js 脚本获取

import '../../app1/app1Bundle';

或 要求('../../app1/app1Bundle');

然后尝试渲染一个 id 为“app1”的普通 div 标签

const HomePage = () => {
  return (
    <div>
      <div id="app1"></div>
      <h1>App 2</h1>
    </div>
  );
};

似乎没有任何效果,因为我仍然遇到同样的错误。 我认为问题在于脚本加载的时间和元素的渲染。我认为捆绑脚本正在搜索 div 时该 div 尚不存在。

【问题讨论】:

    标签: javascript reactjs import webpack require


    【解决方案1】:

    默认情况下,Webpack 会将入口模块作为变量公开,这在您包含带有 &lt;script&gt; 标签的脚本时很有用。 (因此,如果你 require 它,你可能只会得到 {}。)但是,如果你想从其他模块加载你的包,你需要告诉 Webpack 将它作为导出模块公开。

    最简单的方法是设置

    {
      ...
      "libraryTarget": "umd"
    }
    

    在你的 Webpack 配置中。这样,Webpack 知道它应该将您的入口模块公开为 Webpack 中可能需要的模块,但也可以根据需要使用 &lt;script&gt; 标签加载。

    Webpack libraryTarget documentation

    【讨论】:

    • 我似乎遇到了同样的错误。你能详细说明我应该在我的代码中改变什么吗?
    【解决方案2】:

    我面临的主要问题是在 DOM 包含它需要的目标 div 之后包含 app1 的捆绑 js 文件。
    我最终做的是,在 app2 项目中创建一个组件,该组件将 require() componentDidMount() 上的捆绑 js 文件,并将呈现并返回具有相关 ID 的目标 div

    • 我创建一个组件的原因纯粹是为了可重用性的目的,而不是在每个需要它的组件上都需要这个带有componentDidMount() 的脚本。

    所以,这就是组件:

    import React from 'react';
    
    class AppOne extends React.Component {
    
      componentDidMount() {
        require('../app1/app1Bundle.js');
      }
    
      render() {
        return (
          <div id="app1"></div>
        );
      }
    }
    export default AppOne;
    

    这就是我在其他组件中使用它的方式:

    import React from 'react';
    import AppOne from './AppOne';
    
    const HomePage = () => {
      return (
        <div>
          <h1>App 2 - wrapper for app1</h1>
          <hr />
          <AppOne />
          <hr />
          <h1>This is App2 as well </h1>
        </div>
      );
    };
    
    export default HomePage;
    

    一切正常。我唯一担心的是我可能会面临一些与 react 的冲突,因为我正在使用 2 个 react 应用程序,但现在我没有看到任何错误。
    我想这是另一个问题的问题。

    编辑: 如果有人会使用这种方法,您应该注意这仅适用于第一次加载。因为在组件重新渲染后,捆绑的脚本将不会再次运行。

    【讨论】:

      猜你喜欢
      • 2020-06-21
      • 2014-12-12
      • 2017-05-10
      • 2018-04-22
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多