0

我在尝试从 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”

这不是一个常量问题。它是为测试而编写的,我知道同时使用 2) 和 3) 会导致问题。注释 1) 时会发生此错误。

4

1 回答 1

0

您可以导入元数据,如下所示。

首先,我们从 .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>
  );
}

于 2021-12-27T20:24:14.507 回答