Javascript 在下一个JS中使用“next mdx remote”时,如何在“public/”文件夹之外的“.mdx”文件中使用图像?
我正在用Javascript 在下一个JS中使用“next mdx remote”时,如何在“public/”文件夹之外的“.mdx”文件中使用图像?,javascript,reactjs,next.js,mdxjs,Javascript,Reactjs,Next.js,Mdxjs,我正在用public/文件夹外的.mdx文件中的图像创建博客,并希望使用这些图像 这是我博客项目的完整代码→ 我有以下文件夹结构: . ├── package-lock.json ├── package.json ├── pages │ ├── _app.js │ ├── blog │ │ └── [slug].js │ ├── dark.css │ ├── index.js │ └── new.css ├── posts │ ├── blog │ │
public/
文件夹外的.mdx
文件中的图像创建博客,并希望使用这些图像
这是我博客项目的完整代码→
我有以下文件夹结构:
.
├── package-lock.json
├── package.json
├── pages
│ ├── _app.js
│ ├── blog
│ │ └── [slug].js
│ ├── dark.css
│ ├── index.js
│ └── new.css
├── posts
│ ├── blog
│ │ ├── hello-world
│ │ │ ├── Rustin_Cohle.jpg
│ │ │ └── index.mdx
│ │ └── shit-world
│ │ └── index.mdx
│ └── tutorials
│ └── console-log-in-javascript
│ └── index.mdx
└── utils
└── mdxUtils.js
我的所有内容都在posts/
文件夹中
我有两个文件夹:blog/
&tutorials/
每篇文章都在blog/
或tutorials/
中各自的文件夹中&这些文件夹中的每一篇都包含在该特定文章中使用的图像
例如,在hello world
文件夹中,有一个名为Rustin_Cohle.jpg
的图像
我想在hello world/index.mdx
文件中使用此图像,但无法执行此操作
我不能使用导入
或要求
,因为这是下一个mdx远程
的限制
我尝试使用一个名为Image
的自定义组件,该组件在下面使用了img
,并将其传递给hydrate
,但它也不起作用
组件/Image.js
export const Image=({src,alt})=>(
)
pages/blog/[slug].js
从“下一个mdx远程/水合物”导入水合物
从“../components/Image”导入{Image}
常量组件={Image}
const Blog=({source,frontMatter})=>{
常量含量=水合物(来源,{components})
返回(
{frontMatter.title}
{content}
)
}
以下MDX文件使用通过hydrate
传递的上述图像组件
hello world/index.mdx
那么我如何使用图像呢?我希望它们只出现在特定帖子的文件夹中,比如hello world
博客将只在hello world/
文件夹中包含其图像。不幸的是,这是不可能的,因为next mdx remote
将标记内容视为数据,根本不通过网页包:(在这种情况下,我能够加载图像。我的想法是使用webpack文件加载器来完成这一点,并向组件映射添加更多信息,告知当前帖子的位置(注意组件功能)
我的页面[slug].js如下:
import renderToString from 'next-mdx-remote/render-to-string'
import hydrate from 'next-mdx-remote/hydrate'
import matter from 'gray-matter'
import { getAllPostSlugs, getPostdata } from '../lib/posts'
const components = (slug) => ({
h1: ({ children }) => <h1>{children}</h1>,
img: ({ src, alt }) => {
return (
<p>
<img
alt={alt}
src={require('../content/' + slug + '/' + src).default}
/>
</p>
)
}
})
const Post = ({ source, frontMatter, slug }) => {
const content = hydrate(source, {
components: components(slug)
})
return (
<>
<h1>Post</h1>
<p>{content}</p>
</>
)
}
export async function getStaticPaths() {
const paths = getAllPostSlugs()
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }) {
const postContent = await getPostdata(params.slug)
const { data, content } = matter(postContent)
const mdxSource = await renderToString(content, {
components: components(params.slug),
scope: data
})
return {
props: {
slug: params.slug,
source: mdxSource,
frontMatter: data
}
}
}
export default Post
Ps:next/image:)很有魅力。Hi,我是next mdx remote的作者——只是确认这是真的。我的建议是在公共文件夹中使用图像。该死的,这是一个巧妙的技巧,请投我的赞成票。但是,我确实认为我不应该把这个标记为答案,因为这看起来像是一个黑客,但它有效,所以我会投赞成票:)非常感谢。我们将在盖茨比项目迁移到NextJS的过程中使用这种方法。这将有助于保持内容不变:)您好,这里是下一个mdx remote的作者。只是顺便说一下,这是一个非常酷的想法和实现。伟大的工作图里奥!嘿@Jeffescalate我应该将此标记为答案吗?@Jeffescalate@TulioFaria是否也可以导入在mdx文件中对组件进行反应?这是唯一阻止我从next mdx enhanced
切换到next mdx remote
。我的所有mdx文件都是本地文件。
import renderToString from 'next-mdx-remote/render-to-string'
import hydrate from 'next-mdx-remote/hydrate'
import matter from 'gray-matter'
import { getAllPostSlugs, getPostdata } from '../lib/posts'
const components = (slug) => ({
h1: ({ children }) => <h1>{children}</h1>,
img: ({ src, alt }) => {
return (
<p>
<img
alt={alt}
src={require('../content/' + slug + '/' + src).default}
/>
</p>
)
}
})
const Post = ({ source, frontMatter, slug }) => {
const content = hydrate(source, {
components: components(slug)
})
return (
<>
<h1>Post</h1>
<p>{content}</p>
</>
)
}
export async function getStaticPaths() {
const paths = getAllPostSlugs()
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }) {
const postContent = await getPostdata(params.slug)
const { data, content } = matter(postContent)
const mdxSource = await renderToString(content, {
components: components(params.slug),
scope: data
})
return {
props: {
slug: params.slug,
source: mdxSource,
frontMatter: data
}
}
}
export default Post
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.(svg|png|jpe?g|gif|mp4)$/i,
use: [
{
loader: 'file-loader',
options: {
publicPath: '/_next',
name: 'static/media/[name].[hash].[ext]'
}
}
]
})
return config
}
}