Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Динамический импорт (https://javascript.ru/forum/node-js-io-js/84816-dinamicheskijj-import.html)

ichor 03.01.2023 22:57

Динамический импорт
 
Подскажите, пожалуйста, как решить следующую задачу. Я пишу приложение для новостей. Содержание каждого поста частично (название, несколько иллюстраий, дата создания, раздел, аннотация, часть текста) вносятся в базу MongoDB. Каждая новость соответственно содержит уникальный id. Все это сделать, несложно.

Однако каждая новость также должна иметь часть уникального кода (html + js, как правило), который я планирую вносить вручную. К примеру, элементы canvas.
Таким образом вносить в каждую новость оригинальные элементы дизайна.

Эту задачу я планировал решить путем создания под каждую новость js файла, содержащего компонент. Файл создается вручную, оборачивается в компонент, скажем, ArtBlock и загружается на сервер в отдельную папку в ходе создания статьи (uploader), методом как и иллюстрации к статье.
Название файла должно совпадать с id статьи, чтобы через пропсы автоматически найти его в соответствующей папке и импортировать на страницу статьи.

Для этих целей я планировал использовать динамический import @loadable/component:
const Post = ({ post }) => {
  const { loading, error, data } = useQuery(IS_LOGGED_IN);
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;
  let arr = post._id;
  const ArtPage = loadable(post => import(`../arts/${arr}`));

  return (
    <article>
    <ArtPage />
    <div id={post._id}></div>
    <ImgStyle>
      <img src={post.imageUrl} />
    </ImgStyle>
      <H2>{post.title}</H2>
      <Link style={linkStyle} to={`/cats/${idcat}`}>
        <H4R>{post.category.catname}</H4R>
      </Link>
      <H4R>{post.createdAt}</H4R>
      <Link style={linkStyle} to={`/users/${iduser}`}>
        <H4R>{`author ${post.author.name}`}</H4R>
      </Link>
      <H4R>{`views ${post.viewsCount}`}</H4R>
      <PRiv4>
        <ReactMarkdown children={post.body}  />
      </PRiv4>
    </article>
  );
};


Но код упорно отказывается работать. При этом если убрать переменную и вставить конкретно название файла, но компонент подгружается.
const ArtPage = loadable(post => import(`../arts/63addc830407bc4b94f5d965`));


Почему все-таки импорт не грузит переменную?
const ArtPage = loadable(post => import(`../arts/${arr}`));

Несколько дней уже убил на поиск решения, но никак((

Aetae 04.01.2023 09:33

import в системах сборки работает на этапе компиляции, соответственно он может импортировать только то, что уже есть в папках на этом этапе.
Выражение вида
import(`../arts/${arr}`)
на самом деле означает "загрузить в бандл всё из папки ../arts/ и во время исполнения выбирать из загруженного".

Решения два:
1. делать сборку с выходной целью esm.
2. не использовать import для файлов которых нет на момент сборки, использовать для них руками fetch + eval или что-то в этом духе.

Сразу скажу: первый вариант не пробовал(т.к. в основном все проекты у меня требуют поддержки брраузеров не умеющих в модули), так что какие там подводные камни не скажу.(но уверен, что на немаленький холмик хватит)

ichor 04.01.2023 17:57

Так мы исходим из того, что файл есть в папке. Если его указать напрямую, без переменной то он грузится из папки. Через переменную, пишет что не может его найти(((

Aetae 04.01.2023 18:55

ichor, ну сделай чистый проект, куда скопируй только один этот файл, сбилди с отключённым optimize\minimize и посмотри что у тя там в итоге в сырцах...¯\_(ツ)_/¯
Если что-то не работает - надо отлаживать, вестимо.

ichor 04.01.2023 23:30

я только учусь и сленг пока не понимаю))) т.е. код что я опубликовал по импорту корректен? и надо искать причину в другом месте?

ichor 04.01.2023 23:35

Мне нужен способ простого импорт js файла в компонент, который позволяет использовать в пути к файлу переменную. Все!

Aetae 05.01.2023 06:40

ichor, завесит от системы сборки, но в терии должно работать, возможно надо добавить .js в конец.


Часовой пояс GMT +3, время: 02:19.