Как я могу выполнить ручное разделение кода с помощью preact?

Я хочу выполнить разделение кода вручную, используя 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 поддерживает работу с графикой и аудио, что позволяет создавать мультимедийные веб-приложения.


2
1 046
1

Ответ:

Решено

Если вы используете 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;
}