【问题标题】:Cannot import meta data from mdx file in getStaticProps nextjs无法从 getStaticProps nextjs 中的 mdx 文件导入元数据
【发布时间】:2021-08-29 06:39:19
【问题描述】:

我在尝试从 Next.js 项目中的 mdx 文件中获取元数据时遇到问题。

MDX 文件示例:

export const meta = {
  title: 'title',
  date: new Date('May 09, 2019'),
};

Content

export const getStaticProps = async context => {
  const postFilenames = await recRead(process.cwd() + '/pages', ['*.tsx']);
  const postMetadata = await Promise.all(
    postFilenames.map(async p => {
      const { meta } = require(p);
      return meta;
    }),
  );

  return {
    props: {
      postMetadata: postMetadata,
    },
  };
};

这是它的修改版本:https://sarim.work/blog/dynamic-imports-mdx。访问网站时出现错误:

找不到模块“/home/oliwier/webDev/oliwierwpodrozy/pages/balkany/1.mdx”。

顺便说一句,recRead 是这个https://www.npmjs.com/package/recursive-readdir

发生了什么事?在getStaticProps之外我可以导入数据。

我在尝试解决问题时发现了一些可笑的东西。

  // 1)console.log(postFilenamesToImport[0]); 
  // 2) const meta = await import('../pages/wielka-brytania/1.mdx'); 
  // 3) const meta = await import(postFilenamesToImport[0]);

  // console.log(meta.meta);
  1. 显示:../pages/wielka-brytania/1.mdx 这是一个字符串
  2. 这个有效
  3. 但是这个没有。显示错误:错误:找不到模块 '../pages/wielka-brytania/1.mdx'

这不是 const 问题。它是为测试而编写的,我知道同时使用 2) 和 3) 会导致问题。注释 1) 时会出现此错误。

【问题讨论】:

    标签: node.js next.js mdxjs


    【解决方案1】:

    您可以像下面这样导入元数据。

    首先,我们从 .mdx 文件中导出元数据

    // in /pages/posts/example.mdx
    import Layout from "../../components/layout";
    
    export const meta = {
      title: "example",
      date: "2021-12-27",
      slug: "example",
    };
    
    Lorem ipsum.
    
    export default ({ children }) => (
      <Layout subtitle={meta.title}>{children}</Layout>
    );
    

    然后我们使用getStaticProps 在运行时扫描文件系统,将每个 .mdx 文件作为一个模块导入,然后映射出它们的元数据导出。由于我们在索引页面上显示元数据,我们将从数组中弹出index.js

    // in /pages/posts/index.js
    export const getStaticProps = async (context) => {
      const postDirectory = path.join(process.cwd(), "src/pages/posts");
      let postFilenames = fs.readdirSync(postDirectory);
      postFilenames = removeItemOnce(postFilenames, "index.js");
      const postModules = await Promise.all(
        postFilenames.map(async (p) => import(`./${p}`))
      );
      const postMetadata = postModules.map((m) => (m.meta ? m.meta : null));
      return {
        props: {
          postMetadata: postMetadata,
        },
      };
      // thanks https://sarim.work/blog/dynamic-imports-mdx
    };
    
    
    function removeItemOnce(arr, value) {
      var index = arr.indexOf(value);
      if (index > -1) {
        arr.splice(index, 1);
      }
      return arr;
      // thanks https://stackoverflow.com/a/5767357/13090245
    }
    

    这是使用道具呈现帖子列表的一种方式

    // in /pages/posts/index.js
    export default function PostsIndex({ postMetadata }) {
      return (
        <Layout subtitle="blog index">
          <ul>
            {postMetadata.map(({ slug, date, title }) => (
              <li key={slug}>
                <Link href={`/posts/${slug}`} a={title} />
                <br />
                {date}
              </li>
            ))}
          </ul>
        </Layout>
      );
    }
    
    

    【讨论】:

      猜你喜欢
      • 2022-10-22
      • 2023-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 2021-10-03
      • 2020-02-03
      • 1970-01-01
      相关资源
      最近更新 更多