首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Next JS中使用`next-mdx-remote`时,如何使用` `public/`文件夹以外的`.mdx`文件中的镜像?

在Next JS中使用`next-mdx-remote`时,如何使用` `public/`文件夹以外的`.mdx`文件中的镜像?
EN

Stack Overflow用户
提问于 2020-09-18 21:47:42
回答 2查看 1.3K关注 0票数 5

我正在用next-mdx-remote写博客,我想在public/文件夹之外的.mdx文件中使用图片。

下面是我的博客项目https://github.com/deadcoder0904/blog-mdx-remote→的完整代码

我有以下文件夹结构:

代码语言:javascript
运行
复制
.
├── 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文件中使用此图像,但我无法这样做。

我不能使用importrequire,因为它是next-mdx-remote的一个限制。

我尝试使用一个名为Image的自定义组件,该组件在底层使用img,并将其传递给hydrate,但也不起作用。

组件/Image.js

代码语言:javascript
运行
复制
export const Image = ({ src, alt }) => (
    <img style={{ backgroundColor: 'red' }} src={src} alt={alt} />
)

pages/blog/slug.js

代码语言:javascript
运行
复制
import hydrate from 'next-mdx-remote/hydrate'
import { Image } from '../components/Image'

const components = { Image }

const Blog = ({ source, frontMatter }) => {
  const content = hydrate(source, { components })
  return (
    <div>
      <h1>{frontMatter.title}</h1>
      {content}
    </div>
  )
}

下面的MDX文件使用通过hydrate传递的上述Image组件。

hello-world/index.mdx

代码语言:javascript
运行
复制
---
title: Hello World
date: '2019-09-06T14:54:37.229Z'
tags: ['hello', 'world']
author: John Doe
description: This is the first post
---

Hey this is my first post

![Rustin Cohle](./Rustin_Cohle.jpg)

<img src="./Rustin_Cohle.jpg" alt="Rust Cohle" />

<Image src="./Rustin_Cohle.jpg" alt="Rust Cohle" />

This is the end of the first post

我甚至尝试过使用MDXProvider &它也不起作用。

pages/index.js

代码语言:javascript
运行
复制
import { MDXProvider } from '@mdx-js/react'

const components = { Image }

const HomePage = ({ posts }) => {
    return (
        <MDXProvider components={components}>
         ...
        </MDXProvider>
    )
}

那我该怎么使用图片呢?我希望它们只在特定的帖子的文件夹中,就像hello-world博客只在hello-world/文件夹中包含它的图像一样。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-18 22:17:49

不幸的是,这是不可能的,因为next-mdx-remote将markdown内容视为数据&根本不会通过Webpack传递:(

票数 1
EN

Stack Overflow用户

发布于 2021-01-12 18:08:29

在这个场景中,我能够加载图像。我的想法是使用webpack file-loader来实现这一点,并将更多信息添加到组件映射中,以告知当前帖子的位置(请注意组件函数)。

我的页面slug.js是这样的:

代码语言:javascript
运行
复制
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

和我的next.config.js:

代码语言:javascript
运行
复制
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
  }
}

Ps:它与next/image :类似于护身符。)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63957018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档