【问题标题】:fullcalendar - NextJS - Dynamic import doesn't show calendarfullcalendar - NextJS - 动态导入不显示日历
【发布时间】:2021-06-19 08:13:43
【问题描述】:

我正在使用 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 中有一些东西。将此文件编辑为转译模块是另一种神秘的冒险,充满了问题。

我该怎么办?

【问题讨论】:

    标签: reactjs fullcalendar next.js fullcalendar-5 react-loadable


    【解决方案1】:

    我知道 OP 正在寻求帮助以使其与动态导入一起工作,但如果有人遇到这个问题,试图让 FullCalendar 与 next.js 一起工作(有或没有动态导入)我希望这个答案会有所帮助。我的回答是修改@juliomalves' answer

    (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,而是保持原样。没有添加 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) 然后我没有动态导入,而是定期导入到需要日历的页面中。

    【讨论】:

    • 提供的解决方案似乎不适用于 Typescript 和 Next.js,但该解决方案对我有用。非常感谢!!!他们确实需要更新站点以拥有 Next 和 TS 示例。如果觉得它越来越普遍,我不知道有什么理由不使用 TS。
    • 这在 NextJS 11.1.2 中对我有用。注意组件名称。当要使用的组件称为“日历”时,我一直在尝试“FullCalendar”。
    【解决方案2】:

    要使 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 插件。这可以防止来自 Next.js 的 Global CSS cannot be imported from within node_modules error

    // 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 一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-28
      • 2017-10-21
      • 2020-01-24
      • 1970-01-01
      相关资源
      最近更新 更多