yandex-maps-unofficial / vue-yandex-map

Yandex Maps Component for VueJS
MIT License
359 stars 103 forks source link

SSR and YandexMap import error #444

Closed Horizonnns closed 1 year ago

Horizonnns commented 1 year ago

При попытке вызова команды "php artisan inertia:start" выдает ошибку:

file:///D:/OpenServer/domains/anor/bootstrap/ssr/ssr.mjs:14 import { YandexMap, YandexMarker } from "vue-yandex-maps"; ^^^^^^^^^ SyntaxError: Named export 'YandexMap' not found. The requested module 'vue-yandex-maps' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:

import pkg from 'vue-yandex-maps'; const { YandexMap, YandexMarker } = pkg;

at ModuleJob._instantiate (node:internal/modules/esm/module_job:123:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:189:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
at async loadESM (node:internal/process/esm_loader:91:5)
at async handleMainPromise (node:internal/modules/run_main:65:12)

Node.js v18.12.1

Много способов попробовал, но безуспешно. Кто сталкивался с такой проблемой. Помогите решить его.

PNKBizz commented 1 year ago

Какая версия Я.Карт?

Horizonnns commented 1 year ago

v1 beta: "vue-yandex-maps": "^1.0.5"

PNKBizz commented 1 year ago

Вот таким образом пробовали?

import YmapPlugin from 'vue-yandex-maps' Vue.use(YmapPlugin, settings)

Horizonnns commented 1 year ago

Вот таким образом пробовали?

import YmapPlugin from 'vue-yandex-maps' Vue.use(YmapPlugin, settings)

Да, но после того как вы это мне сказали. Конечно спасибо, ошибка карты исчезла, но появилась другая ошибка:

ReferenceError: window is not defined at normalizeContainer (D:\OpenServer\domains\anor\node_modules\@vue\runtime-dom\dist\runtime-dom.cjs.js:1622:5) at app.mount (D:\OpenServer\domains\anor\node_modules\@vue\runtime-dom\dist\runtime-dom.cjs.js:1566:27) at setup (file:///D:/OpenServer/domains/anor/bootstrap/ssr/ssr.mjs:2528:113) at file:///D:/OpenServer/domains/anor/node_modules/@inertiajs/vue3/dist/index.esm.js:1:5478 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async I (file:///D:/OpenServer/domains/anor/node_modules/@inertiajs/vue3/dist/index.esm.js:1:5449) at async Server. (file:///D:/OpenServer/domains/anor/node_modules/@inertiajs/core/dist/server.esm.js:1:527)

PNKBizz commented 1 year ago

Да, карту нужно монтировать на клиенте

Horizonnns commented 1 year ago

Да, карту нужно монтировать на клиенте

Я много гуглил и искал но ничего особо полезного не нашел. Я в программирование новичок поэтому если бы вы мне это подсказали как конкретно с примером или даже без него подсказали. Как исключить SSR для конкретного компонента?

PNKBizz commented 1 year ago

Покажите подключение компонента карты

Horizonnns commented 1 year ago

Покажите подключение компонента карты

Основной компонент это App.vue Карта находиться в компоненте под названием: "AnorMap.vue" Надеюсь я вас правильно понял Внутри App.vue:

<script setup>
import Header from '../components/Header.vue';
import SliderTarif from '../components/SliderTarif.vue';
import Quetions from '../components/Quetions.vue';
import AnorMap from '../components/AnorMap.vue';
import Footer from '../components/Footer.vue';

// lazy loading anim
import { defineAsyncComponent } from 'vue';

const HeaderSlider = defineAsyncComponent({
  loader: () => import('../components/HeaderSlider.vue'),
  delay: 1000,
  timeout: 1000,
  onError(error, retry, fail, attempts) {
    if (error.message.match(/fetch/) && attempts <= 3) {
      retry();
    } else {
      fail();
    }
  },
  suspensible: true,
});
// lazy loading anim

const props = defineProps({
  pictures: Array,
  tarifs: Array,
  locations: Array,
});
</script>

<template>
  <Head>
    <meta property="og:type" content="website" />
    <meta head-key="og:title" property="og:title" content="Анор" />
    <meta head-key="og:url" property="og:url" content="https://anor.mobi/" />
    <meta head-key="og:image" property="og:image" content="" />
    <meta
      head-key="og:description"
      property="og:description"
      content="Анор Моби"
    />
    <title>Главная</title>
  </Head>
  <!-- Шапка -->
  <!-- <Header /> -->

  <!-- Слайдер -->
  <Suspense>
    <!--  lazy loading anim  -->
    <template #default>
      <HeaderSlider :pictures="pictures" />
    </template>
    <template #fallback>
      <div class="animated-background min-h-[305px]"></div>
    </template>
    <!--  lazy loading anim  -->
  </Suspense>

  <!-- Тарифы -->
  <SliderTarif :tarifs="tarifs" />

  <!-- Вопросы -->
  <Quetions />

  <!-- Карта -->
  <AnorMap />

  <!-- Подвал -->
  <!-- <Footer /> -->
</template>

<style>
@import url('https://fonts.googleapis.com/css2?family=PT+Sans:wght@400;700&display=swap');

/* lazy loading anim */
@keyframes placeHolderShimmer {
  0% {
    background-position: -468px 0;
  }
  100% {
    background-position: 468px 0;
  }
}

.animated-background {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  -webkit-animation-name: placeHolderShimmer;
  animation-name: placeHolderShimmer;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  background: #f6f7f8;
  background: #eeeeee;
  background: -webkit-gradient(
    linear,
    left top,
    right top,
    color-stop(8%, #eeeeee),
    color-stop(18%, #dddddd),
    color-stop(33%, #eeeeee)
  );
  background: -webkit-linear-gradient(
    left,
    #eeeeee 8%,
    #dddddd 18%,
    #eeeeee 33%
  );
  background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
  -webkit-background-size: 800px 104px;
  background-size: 800px 104px;
  position: relative;
}
/* lazy loading anim */
</style>
PNKBizz commented 1 year ago

Чистый Vue или Nuxt? Если первое, то

const isMounted = ref(false)
onMounted(() => isMounted.value = true)
...
<AnorMap v-if="isMounted"/>

Если Nuxt, то оберните <AnorMap /> в компонент ClientOnly

Horizonnns commented 1 year ago

Чистый Vue или Nuxt? Если первое, то

const isMounted = ref(false)
onMounted(() => isMounted.value = true)
...
<AnorMap v-if="isMounted"/>

Если Nuxt, то оберните <AnorMap /> в компонент ClientOnly

Не Nuxt. Проект на Laravel v9, Vue 3, Vite, Inertia v1: Я сделал как вы сказали, но проблема не ушла к сожалению;). Говорить что ReferenceError: window is not defined Я конечно понимаю что вы не обязаны мне помогать, но я очень благодарен вам за то что вы помогаете Вот что я сделал:

<script setup>
import Header from '../components/Header.vue';
import SliderTarif from '../components/SliderTarif.vue';
import Quetions from '../components/Quetions.vue';
import AnorMap from '../components/AnorMap.vue';
import Footer from '../components/Footer.vue';

import { onMounted, ref } from 'vue';

// lazy loading anim
import { defineAsyncComponent } from 'vue';

const HeaderSlider = defineAsyncComponent({
  loader: () => import('../components/HeaderSlider.vue'),
  delay: 1000,
  timeout: 1000,
  onError(error, retry, fail, attempts) {
    if (error.message.match(/fetch/) && attempts <= 3) {
      retry();
    } else {
      fail();
    }
  },
  suspensible: true,
});
// lazy loading anim

const props = defineProps({
  pictures: Array,
  tarifs: Array,
  locations: Array,
});

const isMounted = ref(false);
onMounted(() => (isMounted.value = true));
</script>

<template>
  <Head>
    <meta property="og:type" content="website" />
    <meta head-key="og:title" property="og:title" content="Анор" />
    <meta head-key="og:url" property="og:url" content="https://anor.mobi/" />
    <meta head-key="og:image" property="og:image" content="" />
    <meta
      head-key="og:description"
      property="og:description"
      content="Анор Моби"
    />
    <title>Главная</title>
  </Head>
  <!-- Шапка -->
  <!-- <Header /> -->

  <!-- Слайдер -->
  <Suspense>
    <!--  lazy loading anim  -->
    <template #default>
      <HeaderSlider :pictures="pictures" />
    </template>
    <template #fallback>
      <div class="animated-background min-h-[305px]"></div>
    </template>
    <!--  lazy loading anim  -->
  </Suspense>

  <!-- Тарифы -->
  <SliderTarif :tarifs="tarifs" />

  <!-- Вопросы -->
  <Quetions />

  <!-- Карта -->
  <AnorMap v-if="isMounted" />

  <!-- Подвал -->
  <!-- <Footer /> -->
</template>

<style>
@import url('https://fonts.googleapis.com/css2?family=PT+Sans:wght@400;700&display=swap');

/* lazy loading anim */
@keyframes placeHolderShimmer {
  0% {
    background-position: -468px 0;
  }
  100% {
    background-position: 468px 0;
  }
}

.animated-background {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  -webkit-animation-name: placeHolderShimmer;
  animation-name: placeHolderShimmer;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  background: #f6f7f8;
  background: #eeeeee;
  background: -webkit-gradient(
    linear,
    left top,
    right top,
    color-stop(8%, #eeeeee),
    color-stop(18%, #dddddd),
    color-stop(33%, #eeeeee)
  );
  background: -webkit-linear-gradient(
    left,
    #eeeeee 8%,
    #dddddd 18%,
    #eeeeee 33%
  );
  background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
  -webkit-background-size: 800px 104px;
  background-size: 800px 104px;
  position: relative;
}
/* lazy loading anim */
</style>

И вот как ругается:

$ php artisan inertia:start-ssr
Starting SSR server on port 13714...
Inertia SSR server started.
ReferenceError: window is not defined
    at normalizeContainer (D:\OpenServer\domains\anor\node_modules\@vue\runtime-dom\dist\runtime-dom.cjs.js:1622:5)
    at app.mount (D:\OpenServer\domains\anor\node_modules\@vue\runtime-dom\dist\runtime-dom.cjs.js:1566:27)
    at setup (file:///D:/OpenServer/domains/anor/bootstrap/ssr/ssr.mjs:2540:70)
    at file:///D:/OpenServer/domains/anor/node_modules/@inertiajs/vue3/dist/index.esm.js:1:5478
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async I (file:///D:/OpenServer/domains/anor/node_modules/@inertiajs/vue3/dist/index.esm.js:1:5449)
    at async Server.<anonymous> (file:///D:/OpenServer/domains/anor/node_modules/@inertiajs/core/dist/server.esm.js:1:527)
Horizonnns commented 1 year ago

Я все понял. Оказывается неправильно настроил файл ssr.js. Я скопировал свои настройки из моего app.js, а также скопировал .mount(el) в createSSRApp к функции настройки. Я удалил эту строку, и все, SSR компилируется.

-Но только одна примечание: Если с картой используете SSR в таком случае вам необходимо карту рендерит на клиенте.

const isMounted = ref(false)
onMounted(() => isMounted.value = true)
...
<Map v-if="isMounted"/>