在Next.js中将markdown文件作为字符串导入

Rom*_*rez 1 javascript markdown reactjs next.js

如何将Markdown文件作为字符串导入Next.js中以在客户端和服务器端工作?

Cir*_*四事件 11

更新:emit-file-loader不严格要求,不raw-loader推荐使用资产模块

/sf/answers/3356805791/的一些更新可能是由于新的开发:

  • 资产模块被取代raw-loader/sf/answers/3356805791/不再需要安装任何额外的软件包
  • emit-file-loader似乎不再有必要,不确定是否需要它,或者是否是为了更专业的东西

所以我们可以稍微简化一下:

页面/index.js

import world from '../world.md'

export default function IndexPage() {
  return <div>hello {world}</div>
}
Run Code Online (Sandbox Code Playgroud)

next.config.js

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    config.module.rules.push(
      {
        test: /\.md$/,
        // This is the asset module.
        type: 'asset/source',
      }
    )
    return config
  },
}
Run Code Online (Sandbox Code Playgroud)

包.json

{
  "name": "test",
  "version": "1.0.0",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "12.2.0",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  }
}
Run Code Online (Sandbox Code Playgroud)

世界.md

import world from '../world.md'

export default function IndexPage() {
  return <div>hello {world}</div>
}
Run Code Online (Sandbox Code Playgroud)

从 Typescript 开始工作

不幸的是raw-loader,资产模块都需要打字稿做更多的工作:https://github.com/webpack-contrib/raw-loader/issues/56#issuecomment-423640398您必须创建一个文件:

全局.d.ts

declare module '*.md'
Run Code Online (Sandbox Code Playgroud)

否则导入将失败并显示:

Type error: Cannot find module '../world.md' or its corresponding type declarations.
Run Code Online (Sandbox Code Playgroud)

完整示例:

全局.d.ts

declare module '*.md'
Run Code Online (Sandbox Code Playgroud)

页面/index.tsx

import world from '../world.md'

export default function IndexPage() {
  const what: string = 'my'
  // Would fail on build as desired.
  // const what2: int = 'world2'
  return <div>hello {what} {world}</div>
}
Run Code Online (Sandbox Code Playgroud)

next.config.js

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    config.module.rules.push(
      {
        test: /\.md$/,
        type: 'asset/source',
      }
    )
    return config
  },
}
Run Code Online (Sandbox Code Playgroud)

包.json

{
  "private": true,
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start",
    "type-check": "tsc"
  },
  "dependencies": {
    "next": "v12.2.0",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "@types/node": "12.12.21",
    "@types/react": "17.0.2",
    "@types/react-dom": "17.0.1",
    "typescript": "4.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

世界.md

my md world
Run Code Online (Sandbox Code Playgroud)


sid*_*son 9

只需安装raw-loader

npm install --save raw-loader
Run Code Online (Sandbox Code Playgroud)

然后编辑你的 next.config.js

webpack: (config) => {
  config.module.rules.push({
    test: /\.md$/,
    use: 'raw-loader',
  });
  return config;
},
Run Code Online (Sandbox Code Playgroud)

  • 所选答案对我不起作用。但这确实做到了! (2认同)

Rom*_*rez 6

您可以配置Next.js Webpack加载器以加载markdown文件并将其作为字符串返回,例如:

docs/home.md

# Home

This is my **awesome** home!
Run Code Online (Sandbox Code Playgroud)

pages/index.js

import React from 'react';
import markdown from '../docs/home.md';

export default () => {
  return (
    <div>
      <pre>{markdown}</pre>
      <small><i>Import and render markdown using Next.js</i></small>
    </div>
  );
};
Run Code Online (Sandbox Code Playgroud)

package.json

{
  "name": "example",
  "version": "1.0.0",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "file-loader": "^1.1.6",
    "next": "^4.2.1",
    "raw-loader": "^0.5.1",
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

next.config.js

module.exports = {
  webpack: (config) => {
    return Object.assign({}, config, {
      externals: Object.assign({}, config.externals, {
        fs: 'fs',
      }),
      module: Object.assign({}, config.module, {
        rules: config.module.rules.concat([
          {
            test: /\.md$/,
            loader: 'emit-file-loader',
            options: {
              name: 'dist/[path][name].[ext]',
            },
          },
          {
            test: /\.md$/,
            loader: 'raw-loader',
          }
        ]),
      }),
    });
  }
};
Run Code Online (Sandbox Code Playgroud)

运行时:

$ npm run dev
Run Code Online (Sandbox Code Playgroud)

这样的事情会出现:

示例预览

使用markdown字符串,您可以执行任何操作。例如,使用marky处理它。


pie*_*hka 5

更快和“Next.js 方式”是使用插件next-mdx

文档:https : //github.com/zeit/next-plugins/blob/master/packages/next-mdx/readme.md

// next.config.js
const withMDX = require('@zeit/next-mdx')({
  extension: /\.mdx?$/
})
module.exports = withMDX({
  pageExtensions: ['js', 'jsx', 'mdx']
})
Run Code Online (Sandbox Code Playgroud)

  • 文档现在位于 https://github.com/vercel/next.js/tree/canary/packages/next-mdx (2认同)