我在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/olwier/webDev/olwierpodrozy/pages/ballcany/1.mdx'。
BTWrecRead
是这个吗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);
- 显示:/pages/wielka brytania/1.mdx,它是一个字符串
- 这个有效
- 但这个没有。显示错误:错误:找不到模块".."/pages/wielka brytania/1.mdx'
这不是常数问题。它是为测试而写的,我知道同时使用2(和3(会引起问题。对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>
);
}