2017-02-22 69 views
1

假设我有一个正常的反应应用程序,使用redux和一些ajax调用。 如果我想将它传递给别人我会给他们捆绑的js文件我用的WebPack创建,并要求他们将其纳入自己的HTML +呈现一个div与ID“对myApp”的例如:导入或需要由反应应用程序创建的捆绑js文件

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

好吧,如果他们的网站也创建了反应,他们想要包括我的捆绑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> 
      ); 
     };` 

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

Uncaught Error: Minified React error #37; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=37 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

和当我访问这个网站我看到:

_registerComponent(...): Target container is not a DOM element.

然而,它们是否会使用这个文件(myBundle.js)及其部件外(顶层index.html例如),它会工作得很好,当然。

编辑: 我忘了提及,我想我知道问题是什么,应用程序没有HTML准备好这个div呢。但我不知道一个好的原生方式来等待它的存在。

编辑#2以下@Frxstrem的回答: 我想要遵循这个答案,但我认为我做错了。 我有两份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" 
    }, 

我试图使APP1 APP2的网页组件中。 所以我复制从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');

,然后试图呈现一个正常的div标签“APP1”的ID

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

似乎没有任何工作,因为我仍然得到同样的错误。 我认为问题是脚本加载的时间和元素的渲染。当捆绑脚本正在搜索时,我认为div还不存在。

回答

2

默认情况下,Webpack会将输入模块公开为一个变量,这在您使用<script>标记包含脚本时非常有用。 (因此,如果你require它可能只是{}。)但是,如果你想从其他模块加载你的包,你需要告诉Webpack公开它作为一个导出模块。

要做到这一点,最简单的方法是设置

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

在你的WebPack配置。因此,Webpack知道它应该将您的输入模块公开为Webpack中可能需要的模块,但也可以根据需要加载<script>标记。

Webpack libraryTarget documentation

+0

我似乎得到相同的错误。你能否详细说明我应该在代码中更改哪些内容? –

0

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

  • 我创建了一个组件纯粹是为了重用性的目的,而不是要求需要它的每一个部件对这个脚本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; 

它的正常工作。我唯一担心的是我可能会面对一些冲突,因为我使用了2个反应应用程序,尽管对于OW我没有看到任何错误。
我想这是另一个问题的问题。

编辑: 如果有人会使用这种方法,你应该注意到,这将只适用于第一次加载。因为在组件重新呈现自身之后,捆绑脚本将不会再次运行。