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

6l7fqoea  于 2023-05-06  发布在  React
关注(0)|答案(3)|浏览(135)

我使用的是NextJS和FullCalendar。
我尝试使用fullcalendar,使用像this example中的动态导入(更多信息,此示例解决方案来自here)。
成功了,但有个问题.几乎每5次刷新尝试中就有1次以错误Please import the top-level fullcalendar lib before attempting to import a plugin结束(like this,但在我的情况下版本是正确的)
在那之后,我发现next/dynamic的modules选项已被弃用。我认为这是我的问题的来源(我不确定100%,但至少它被弃用,需要更新)。
正如docs所说,处理动态导入的新方法是这样的:

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

但是因为我们需要多个导入,所以我找到了this solution
现在,看起来一切都应该正常工作,但我的代码没有任何效果。

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>;
}

我还找到了另一种使用next transpile modules的方法。但他们说"there is currently no way to transpile only parts of a package, it's all or nothing"
事实上,我在next.config.js中有一些东西。将这个文件编辑成transpile模块是另一个神秘的冒险,充满了问题。
我该怎么做?

k4emjkb1

k4emjkb11#

我知道OP在寻求帮助,让它使用动态导入,但如果有人遇到这个问题,试图让FullCalendar与next.js一起工作(有或没有动态导入),我希望这个答案会有所帮助。我的回答是对@juliomalves的回答的修改。
(1)与@juliomalves和官方示例一样,我安装了next-transpile-modules,并包含了相应的依赖项

// next.config.js

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

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

(2)我没有修改巴别塔,而是让它保持原样。未添加babel.config.js或babel-plugin-transform-require-ignore插件。
(3)我以与官方示例相同的方式添加了适当的CSS。

// _app.tsx

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

(4)我在自定义组件中导入了FullCalendar依赖项。

// components/FullCalendar.tsx

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" />
    );
}

(5)然后,我没有动态导入,而是定期导入到需要日历的页面中。

bfnvny8b

bfnvny8b2#

让FullCalendar与Next.js一起正常工作需要一些初始设置和对初始代码的一些更改。
首先,让我们安装next-transpile-modules来处理fullcalendar的ES模块。确保包含您使用的所有@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
});

接下来,添加自定义Babel配置以忽略fullcalendar中使用的CSS导入-需要安装babel-plugin-transform-require-ignore插件。这会阻止Global CSS cannot be imported from within node_modules error进入Next.js。

// babel.config.js

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

您必须在_app.js中包含fullcalendar的全局CSS来弥补这一点。全局CSS只能从Next.js中的此文件导入。

// _app.js

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

最后,您可以简化和重构FullCalendar组件。在这里,您不必动态导入其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" />
    );
}

然后,动态导入您的自定义组件,无论它在哪里使用。

import dynamic from 'next/dynamic';

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

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

export default SomePage;

作为参考,这是基于fullcalendarofficial example,并进行了一些调整,使其与next-transiple-modules v6.4.0一起工作。

vnjpjtjt

vnjpjtjt3#

其他使用next-transpile-modules的实现可能在NextJS 13中不再工作(或者NextJS 12也可以参考@dikembe-mutombo)。
根据FullCalendar example,以下是如何使其工作(至少在Next 13.2.4和FullCalendar 6.1.6上进行了测试):
1.请确保您安装了@fullcalendar/core沿着其他FullCalendar包。
1.由于我们不再需要next-transpile-modules,(如果您之前添加了它)我们可以从next.config.js中删除它。检查示例here
1.删除所有FullCalendar CSS(通常在_app.jsx / _app.tsx中)。
1.像往常一样使用FullCalendar组件。检查示例here

相关问题