Динамический импорт с не связанным файлом
У меня есть проект React в комплекте с Webpack.
У меня есть компонент, который я хочу, чтобы он отображал компоненты динамически. В моем случае путь компонента происходит от реквизита.
Кроме того, эти компоненты не включены в файл моего проекта.js; они являются внешними компонентами / библиотеками React.
Я пробовал импорт Dynamic 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 - компонент React):
import(`/home/user/_apps/module/react-module/lib/${cardType}`)
Webpack создает другой пакет (чанк), включая код index.js и все его зависимости.
Но это не решает мой первоначальный вопрос.
Редактирование 2: импорт сверху фактически игнорирует последнюю переменную, а Webpack создает фрагменты каждого файла внутри /lib.
1 ответ
Я наконец-то придумал решение.
Библиотека 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>
);
}
}
В конфигурационный файл веб-пакета библиотеки (производство) добавлено:
libraryTarget: 'umd',
Основной файл проекта (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
})
}
})
}
})
}
}