Я хочу выполнить разделение кода вручную, используя preact. Preact уже разбивает код для маршрутов, но я хочу сделать это сам.
Мой вариант использования заключается в том, что я создаю инструмент, в котором пользователь может добавлять виджеты на панель инструментов. На домашнюю страницу я хочу включить только код виджетов, которые настроил пользователь, а не те, которые пользователь не использовал.
Поэтому я не хочу иметь код для всех виджетов, объединенных в bundle.js, а лениво запрашивать его, когда это необходимо, при рендеринге списка виджетов.
Я попытался использовать синтаксис async!
, который я видел в некоторых старых коммитах для шаблона, но это не сработало.
[{ "type": "notes", "title": "Widget 1}, { "type": "todo", "title": "Widget 2"}]
const Grid = ({ widgets }) => (
<ul>
{widgets.map((widget) => <li key = {widget.title}><Widget widget = {widget} /></li>)}
</ul>
);
Здесь у меня есть сопоставление типа с компонентом:
import notes from widgets/notes;
import todo from widgets/todo;
class Widget extends Component {
widgetMap(widget) {
if (widget.type === 'notes') {
return notes;
}
if (widget.type === 'todo') {
return todo;
}
}
render ({ widget }) {
const widgetComponent = this.widgetMap(map);
return (
<div>
<h1>{widget.title}</h1>
<widgetComponent />
</div>
);
}
}
🤔 А знаете ли вы, что...
JavaScript поддерживает работу с графикой и аудио, что позволяет создавать мультимедийные веб-приложения.
Если вы используете Preact X, в нем есть <Suspense>
и lazy
, которые используют тот же API, что и React. Подробнее об этом вы можете прочитать здесь: https://reactjs.org/docs/concurrent-mode-suspense.html
Ваш измененный пример будет выглядеть так (код изменен из здесь):
import { Suspense, lazy } from `preact/compat`;
const notes = lazy(() => import('./widgets/notes'));
const todo = lazy(() => import('./widgets/todo'));
class Widget extends Component {
widgetMap(widget) {
if (widget.type === 'notes') {
return notes;
}
if (widget.type === 'todo') {
return todo;
}
}
render ({ widget }) {
const widgetComponent = this.widgetMap(map);
return (
<Suspense fallback = {<div>loading...</div>}>
<div>
<h1>{widget.title}</h1>
<widgetComponent />
</div>
</Suspense>
);
}
}
Для более старой версии Preact вы можете самостоятельно собрать асинхронную загрузку HOC, если у вас есть Babel или какой-либо другой транспайлер, настроенный для обработки динамическая загрузка модуля.
export default asyncComponent = (importComponent) => {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = { component: null };
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({ component });
}
render() {
const Component = this.state.component;
return Component ? <Component {...this.props} /> : <div>loading...</div>;
}
}
return AsyncComponent;
}