2017-10-20 29 views
4

J'ai un projet React fourni avec Webpack.Importation dynamique avec fichier non groupé

J'ai un composant que je veux rendre les composants dynamiquement. Dans mon cas, le chemin du composant vient des accessoires.

En outre, ces composants ne sont pas regroupés dans mon fichier projet .js; ce sont des composants/librairies React externes.

J'ai essayé l'importation dynamique 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 }); 
      }) 
    } 
} 

Cela ne fonctionne pas parce que l'importation a besoin d'une route statique.

Ensuite, je l'ai essayé avec redemanderas

let dynamicComponent = require(cardType); 

Ce qui ne fonctionne pas parce que (je suppose) Webpack essaie de le trouver dans le faisceau principal.

Est-ce encore possible?

Mise à jour: Il semble que cela peut fonctionner (cardType est 'index.js' - un composant REACT):

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

Webpack crée un paquet différent (chunk), y compris le code de index.js et toutes ses dépendances.

Mais cela ne résout pas vraiment ma question originale.

Édition 2: L'importation par le dessus ignore réellement la dernière var et Webpack fait des morceaux de chaque fichier dans/lib.

Répondre

2

J'ai finalement trouvé une solution.

LoadJS bibliothèque. Vous pouvez également utiliser $script.

projet Bibliothèque (composants externes): 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> 
    ); 
    } 
} 

Dans le fichier de configuration webpack de la bibliothèque (production), a ajouté:

libraryTarget: 'umd', 

Projet principal fichier (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 
         }) 
        } 
       }) 
      } 
     }) 
    } 
}