简体   繁体   English

fullcalendar - NextJS - 动态导入不显示日历

[英]fullcalendar - NextJS - Dynamic import doesn't show calendar

I'm using NextJS and Fullcalendar.我正在使用 NextJS 和 Fullcalendar。

I tried to use fullcalendar using dynamic import like inthis example (for more info, this example solution comes from here ).我尝试使用fullcalendar使用此示例中的动态导入(有关更多信息,此示例解决方案来自此处)。

It worked, But there was a problem.它工作,但有一个问题。 Almost every 1 out of 5 refreshing attempts ended in error Please import the top-level fullcalendar lib before attempting to import a plugin ( like this , but versions are correct in my case)几乎每 5 次刷新尝试中有 1 次以错误结束Please import the top-level fullcalendar lib before attempting to import a plugin像这样,但在我的情况下版本是正确的)

After that, I found out that the modules option for next/dynamic has been deprecated.之后,我发现 next/dynamic 的 modules 选项已被弃用。 I thought it was a source of my problem (I'm not sure 100%, but at least it was deprecated and needed to be updated).我认为这是我的问题的根源(我不确定 100%,但至少它已被弃用并且需要更新)。

As docs says, newer way to handle dynamic imports is like this:正如文档所说,处理动态导入的新方法是这样的:

const DynamicComponent = dynamic(() =>
  import('../components/hello').then((mod) => mod.Hello)
)

But because we need multiple imports I found this solution .但是因为我们需要多次导入,所以我找到了这个解决方案

For now, It seems like everything should be working, but my code has no effect.现在,似乎一切都应该正常工作,但我的代码没有效果。

import dynamic from "next/dynamic";
import { useEffect, useState } from "react";

import "@fullcalendar/common/main.css"; // @fullcalendar/react imports @fullcalendar/common
import "@fullcalendar/daygrid/main.css"; // @fullcalendar/timegrid imports @fullcalendar/daygrid
import "@fullcalendar/timegrid/main.css"; // @fullcalendar/timegrid is a direct import
import "./Fullcalendar.module.scss";
let CalendarComponent;

const Calendar = dynamic(() =>
  import("@fullcalendar/react").then((module) => module.Calendar)
);
const dayGridPlugin = dynamic(() =>
  import("@fullcalendar/daygrid").then((module) => module.dayGridPlugin)
);

export default function FullCalendar(props) {
  const [calendarLoaded, setCalendarLoaded] = useState(false);

  useEffect(() => {
    CalendarComponent = () => (
      <Calendar
        {...props}
        plugins={[dayGridPlugin]}
        initialView="dayGridMonth"
      />
    );
    setCalendarLoaded(true);
  }, []);

  let showCalendar = (props) => {
    if (!calendarLoaded) return <div>Loading ...</div>;
    return <CalendarComponent {...props} />;
  };

  return <div>{showCalendar(props)}</div>;
}

I also find another way to use next transpile modules .我还找到了另一种使用下一个转译模块的方法。 But they say that "there is currently no way to transpile only parts of a package, it's all or nothing" .但是他们说"there is currently no way to transpile only parts of a package, it's all or nothing"

In fact, I have something in next.config.js .事实上,我在next.config.js中有一些东西。 Editing this file into transpile modules is another mysterious adventure, full of problems.将这个文件编辑成 transpile 模块是另一个神秘的冒险,充满了问题。

What should I have to do?我应该怎么做?

Making FullCalendar work properly with Next.js requires some initial setup and a few changes to your initial code.使 FullCalendar 与 Next.js 正常工作需要一些初始设置并对初始代码进行一些更改。

First, let's install next-transpile-modules to process fullcalendar 's ES modules.首先,让我们安装next-transpile-modules来处理fullcalendar的 ES 模块。 Make sure to include all @fullcalendar dependencies you use.确保包含您使用的所有@fullcalendar依赖项。

// next.config.js

const withTM = require('next-transpile-modules')([
  '@fullcalendar/common',
  '@fullcalendar/react',
  '@fullcalendar/daygrid'
]);

module.exports = withTM({
  // any other next.js settings here
});

Next, add a custom Babel configuration to ignore CSS imports used in fullcalendar - babel-plugin-transform-require-ignore plugin will need to be installed.接下来,添加自定义 Babel 配置以忽略 fullcalendar 中使用的fullcalendar导入 - 需要安装babel-plugin-transform-require-ignore插件。 This prevents the Global CSS cannot be imported from within node_modules error from Next.js.这可以防止Global CSS cannot be imported from within node_modules错误来自 Next.js。

// babel.config.js

module.exports = {
    presets: [
        '@babel/preset-react'
    ],
    overrides: [
        {
            include: ['./node_modules'],
            plugins: [
                [
                    'babel-plugin-transform-require-ignore',
                    {
                        extensions: ['.css']
                    }
                 ]
            ]
        }
    ]
};

You'll have to include fullcalendar 's global CSS in _app.js to compensate for this.您必须在 _app.js 中包含fullcalendar的全局_app.js以弥补这一点。 Global CSS can only be imported from this file in Next.js.全局 CSS 只能从 Next.js 中的该文件导入。

// _app.js

import '@fullcalendar/common/main.css'
import '@fullcalendar/daygrid/main.css'
import '@fullcalendar/timegrid/main.css'

Finally, you can simplify and refactor your FullCalendar component.最后,您可以简化和重构您的FullCalendar组件。 Here you don't have to dynamically import its fullcalendar dependencies, we'll dynamically import the component itself when using it.这里不用动态导入它的fullcalendar依赖,我们会在使用的时候动态导入组件本身。

// components/FullCalendar.jsx

import Calendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import styles from './Fullcalendar.module.scss';

export default function FullCalendar(props) {
    return (
       <Calendar {...props} plugins={[dayGridPlugin]} initialView="dayGridMonth" />
    );
}

Then, dynamically import your custom component wherever it's used.然后,在任何使用它的地方动态导入您的自定义组件。

import dynamic from 'next/dynamic';

const FullCalendar = dynamic(() => import('../components/FullCalendar'), {
    ssr: false
});

const SomePage = () => {
    return <FullCalendar />;
}

export default SomePage;

For reference, this is based on the official example from fullcalendar , with some adaptations to make it work with next-transiple-modules v6.4.0.作为参考,这是基于fullcalendar官方示例,并进行了一些修改以使其与next-transiple-modules v6.4.0 一起使用。


We solve this problem我们解决这个问题


Step 1: First follow the above answer of "juliomalves" for next.config.js.第1步:首先按照上面的“juliomalves”回答next.config.js。 And also import CSS files in "_app.js" file, also follow the above answer for that.并且还在“_app.js”文件中导入 CSS 文件,也请遵循上述答案。


Step 2: Write all full calendar code as we write in react js, but make it a separate component.第 2 步:编写所有完整的日历代码,就像我们在 react js 中编写的一样,但将其作为一个单独的组件。


Step 3: Next import the "Calendar" component using NextJS dynamic import.第 3 步:接下来使用 NextJS 动态导入导入“日历”组件。


import dynamic from 'next/dynamic';

const Calendar = dynamic(()=> import('../path/to/component/Calendar'),{ssr:false})

It should work now!它现在应该可以工作了!


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM