Как создать библиотеку, предоставляющую один компонент Vue, который может использоваться распределенным файлом .mjs?

Я хочу создать один компонент Vue, который будет объединен в один файл .mjs. Другой проект Vue может получить этот файл .mjs через HTTP и использовать компонент. Установка подключаемого компонента через npm невозможна, поскольку другое приложение пытается получить его на основе конфигурации во время выполнения.

Что следует учитывать для подключаемого компонента

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

Воспроизведение библиотеки

Я создал новый проект Vuetify через npm create vuetify

Удалил из папки src все, кроме vite-env.d.ts, создал компонент Renderer.vue

<script setup lang = "ts">
import { VContainer } from "vuetify/components"

defineProps<{ value: unknown }>()
</script>

<template>
  <v-container>
    <span class = "red-text">Value is: {{ JSON.stringify(value, null, 2) }}</span>
  </v-container>
</template>

<style>
.red-text { color: red; }
</style>

и файл index.ts

import Renderer from "./Renderer.vue";

export { Renderer };

Я добавил библиотечный режим в vite.config.ts

  build: {
    lib: {
      entry: resolve(__dirname, "./src/index.ts"),
      name: "Renderer",
      fileName: "renderer",
    },
    rollupOptions: {
      external: ["vue"],
      output: {
        globals: {
          vue: "Vue",
        },
      },
    },
  },

и расширил файл package.json с помощью

  "files": ["dist"],
  "main": "./dist/renderer.umd.cjs",
  "module": "./dist/renderer.js",
  "exports": {
    ".": {
      "import": "./dist/renderer.js",
      "require": "./dist/renderer.umd.cjs"
    }
  },

Поскольку я использую пользовательский CSS, Vite сгенерирует файл styles.css, но мне нужно вставить стили в файл .mjs. Основываясь на этой проблеме Я использую плагин vite-plugin-css-injected-by-js.

При сборке я получаю нужный файл .mjs, содержащий мой собственный CSS.


Потребление компонента

Я создал новый проект Vue через npm create vue

и в целях тестирования я скопировал сгенерированный файл .mjs прямо в каталог src нового проекта и изменил файл App.vue на

<script setup lang = "ts">
import { onMounted, type Ref, ref } from "vue";

const ComponentToConsume: Ref = ref(null);

onMounted(async () => {
  try {
    const { Renderer } = await import("./renderer.mjs"); // fetch the component during runtime

    ComponentToConsume.value = Renderer;
  } catch (e) {
    console.info(e);
  } finally {
    console.info("done...");
  }
});
</script>

<template>
  <div>Imported component below:</div>
  <div v-if = "ComponentToConsume === null">"still loading..."</div>
  <component-to-consume v-else :value = "123" />
</template>

К сожалению, я получаю следующие предупреждения и ошибки

[Предупреждение Vue]: Vue получил компонент, который стал реактивным объектом. Это может привести к ненужной нагрузке на производительность, и этого следует избегать, помечая компонент знаком markRaw или используя shallowRef вместо ref.

[Предупреждение Vue]: инъекция «Символ (vuetify: по умолчанию)» не найдена.

[Vue warn]: необработанная ошибка во время выполнения функции настройки

[Vue warn]: необработанная ошибка во время выполнения сброса планировщика.

Uncaught (в обещании) Ошибка: [Vuetify] Не удалось найти экземпляр по умолчанию

Кто-нибудь знает, что мне не хватает или как это исправить?

Пожалуйста, опубликуйте ошибки в виде текста, см. meta.stackoverflow.com/questions/285551/… . Vuetify не предоставляет изолированные компоненты и требует инициализации подключаемого модуля. Вам нужно сделать это в основном приложении и убедиться, что vuetify не дублируется в проектах, ваша библиотека и основное приложение используют одну и ту же копию. Библиотека должна использовать vuetify в качестве зависимости от разработчиков и указать ее в external

Estus Flask 02.02.2023 11:23

Я опубликовал ошибки в виде текста, создал новое основное приложение с помощью Vuetify и в библиотеке переместил зависимость vuetify в зависимости от разработки. Что вы имеете в виду под external? Я не мог найти его в документах npm

baitendbidz 02.02.2023 11:55

кстати. после создания основного приложения с помощью Vuetify все заработало нормально, но да, мне интересно external :)

baitendbidz 02.02.2023 12:00

Я имею в виду то, что вы уже используете, external: ["vue"]. Вам нужно предотвратить объединение вещей, которые являются глобальными для проекта, с библиотекой.

Estus Flask 02.02.2023 12:02

ах, спасибо, я добавил "vuetify" в массив, все еще работает. Вы хотите опубликовать ответ?

baitendbidz 02.02.2023 12:07

Конечно, возможно, поможет кому-то еще

Estus Flask 02.02.2023 12:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Vuetify не предоставляет изолированные компоненты и требует инициализации плагина, вам нужно сделать это в основном приложении:

app.use(Vuetify)

Убедитесь, что vuetify не дублируется в проектах, поэтому библиотека и основное приложение используют одну и ту же копию.

Библиотека должна использовать vuetify в качестве зависимости от разработчиков и указать ее в Rollup external, чтобы предотвратить объединение вещей, которые являются глобальными для проекта, с библиотекой:

external: ["vue", "vuetify"]

Другие вопросы по теме