首页 > 解决方案 > Gridsome Full Calendar 构建错误 - 没有 SSR

问题描述

我正在尝试在 Gridsome 项目中使用完整日历 vue 组件( https://github.com/fullcalendar/fullcalendar-vue ),如下所示:

<template>
  <div class="tabStaffManage">
    <div>
          <FullCalendar
            ref="staffCalendar"
            class="fullCalendar"
            defaultView="dayGridMonth"
            :events="calendarEvents"
            :plugins="calendarPlugins"
            :allDaySlot="false"
            :header="{
              center: 'dayGridMonth, timeGridDay',
              right: 'prev, next'
            }"
            minTime="09:00:00"
            :selectable="true"
            maxTime="18:30:00"
            @eventClick="onEventClick"
            @select="onDateSelect"
            :showNonCurrentDates="false"
          ></FullCalendar>
    </div>
  </div>
</template>


<script>
import { formatDate } from "@fullcalendar/core"
import FullCalendar from "@fullcalendar/vue"
import timeGridPlugin from "@fullcalendar/timegrid"
import dayGridPlugin from "@fullcalendar/daygrid"
import interactionPlugin from "@fullcalendar/interaction"

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarPlugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
    }
  },
}
</script>

但是,这会在构建时产生错误:

Could not generate HTML for "/staff/dashboard/":
ReferenceError: Element is not defined
    at Object.338 (node_modules/@fullcalendar/core/main.esm.js:102:0)
    at __webpack_require__ (webpack/bootstrap:25:0)
    at Module.552 (assets/js/page--src-pages-staff-dashboard-vue.ea5234e7.js:598:16)
    at __webpack_require__ (webpack/bootstrap:25:0)

我了解完整日历不支持 SSR。因此,根据 Gridsome 文档(https://gridsome.org/docs/assets-scripts/#without-ssr-support),我这样做是为了导入组件:

我在 gridsome.config.js 中为它的依赖项创建了一个别名,如下所示:

var path = require('path');
api.configureWebpack({
    resolve: {
      alias: {
        "timeGridPlugin": path.resolve('node_modules', '@fullcalendar/timegrid'),
        etc....
      }
    },
  })

并在mounted() 生命周期钩子中需要这些插件:

mounted() {
  if (!process.isClient) return
  let timeGridPlugin = require('timeGridPlugin')

  ...
},
components: {
  FullCalendar: () =>
    import ('@fullcalendar/vue')
    .then(m => m.FullCalendar)
    .catch(),
}

然后我将 FullCalendar 组件包装在:

<ClientOnly>
  <FullCalendar></FullCalendar>
</ClientOnly>

mount() 挂钩中所需的额外依赖项没有问题。

但是我现在收到以下错误:

TypeError: Cannot read property '__esModule' of undefined

似乎 components() 无法导入“@fullcalendar/vue”组件。

导入“@fullcalendar/vue”组件时我做错了吗?

是否有另一种方法可以同时包含“@fullcalendar/vue”组件和没有 SSR 的插件依赖项?

标签: vue.jsfullcalendarserver-side-renderinggridsome

解决方案


通过检查 gridsome 客户端 API 并在 vue 中全局注册组件来要求 main.js 中的完整日历 vue 组件似乎可以工作并且符合我的预期:

  // Include no SSR
  if (process.isClient) {
    const FullCalendar = require("@fullcalendar/vue").default
    Vue.component("full-calendar", FullCalendar)
  }

当需要组件中的其他模块时,我也没有指向默认对象:

mounted() {
  if (!process.isClient) return
  let timeGridPlugin = require('timeGridPlugin').default

  ...
}

推荐阅读