2017-10-20 76 views
4

我有一個與Webpack捆綁在一起的React項目。動態導入未綁定文件

我有一個組件,我希望它動態地呈現組件。就我而言,組件的路徑來自道具。

此外,這些組件未捆綁在我的項目.js文件中;它們是外部React組件/庫文件。

我已經試過了動態ES6進口:

componentWillReceiveProps(nextProps){ 
    if(nextProps.pagesData && this.props.pagesData !== nextProps.pagesData && nextProps.pagesData.get('cards').count() > 0){ 

     // Getting the first card from the Immutable object 
     let card = nextProps.pagesData.getIn(['cards', 0]); 

     // Getting the cardType which can be: '/path/index.js' 
     let cardType = card.get('card_type'); 

     // ES6 Dynamic import 
     import(cardType) 
      .then(module => { 
       this.setState({ asyncCard: module.default }); 
      }) 
    } 
} 

這不起作用,因爲進口需要一個靜態路由。

然後我試着要求:

let dynamicComponent = require(cardType); 

不工作,因爲(我認爲)的WebPack試圖找到它進入主束。

這甚至有可能嗎?

更新:它看起來像這樣可以工作(cardType是 'index.js' - 一個陣營成分):

import(`/home/user/_apps/module/react-module/lib/${cardType}`) 

的WebPack創建一個不同的束(塊)包括index.js的代碼和所有它的依賴。

但這並不能真正解決我原來的問題。

編輯2:從上面的導入實際上忽略了最後一個var,並且Webpack使得/ lib中的每個文件都成爲塊。

回答

2

我終於想出了一個解決方案。

LoadJS庫。您也可以使用$script

庫項目(外部元件): index.js:

import App from './App'; 

export const MyComponentLib = { 
    App 
}; 

App.jsx:

import React, { Component } from 'react'; 
import logo from './logo.svg'; 
import './App.css'; 

export default class App extends Component { 
    render() { 
     return (
     <div className="App"> 
      <header className="App-header"> 
       <img src={logo} className="App-logo" alt="logo" /> 
       <h1 className="App-title">Welcome to React</h1> 
      </header> 
      <p className="App-intro"> 
       To get started, edit <code>src/App.js</code> and save to reload. 
      </p> 
     </div> 
    ); 
    } 
} 

在圖書館的WebPack配置文件(生產)補充說:

libraryTarget: 'umd', 

主項目 file(main.js):

componentWillReceiveProps(nextProps){ 
    if(nextProps.pagesData && this.props.pagesData !== nextProps.pagesData && nextProps.pagesData.get('cards').count() > 0){ 

     // Getting all asyncCards from state 
     let currentCards = cloneDeep(this.state.asyncCards); 

     // Immutable "get" function - getting cards from nextProps 
     nextProps.pagesData.get('cards').forEach(card => { 

      // Getting card_type, which in this case is the filename 
      let cardType = card.get('card_type'); 

      // Do we have this card already in the state object? 
      if(!hasIn(currentCards, cardType)) { 

       // AsyncLoading the card file 
       loadjs(`/custom/1/${cardType}.js`, cardType, { 
        success:() => { 

         // Cloning App function (the component) 
         currentCards[cardType] = window.MyComponentLib.App.bind({}); 

         this.setState({ 
          asyncCards: currentCards 
         }) 
        } 
       }) 
      } 
     }) 
    } 
}