首页 > 解决方案 > 在 Gatsby / React 中将文件作为字符串(或源资产)导入

问题描述

我想将 .ts、.tsx、.js 和 .jsx 文件导入到反应组件中,并在 PrismJS 突出显示块中呈现它们。例如,假设我有一个带有 functionA 的 TypeScript 文件,我想在我的实际网站中突出显示:

functionA.ts

export function functionA() {
    console.log("I am function A!");
}

我想将其包含在不同的组件中。问题是,当我导入它时,我显然是在导入它的 webpack 模块版本。我试图让我的函数在反应组件中呈现的弱尝试如下所示:

MyComponent.tsx

import * as React from "react"
import { functionA } from "./functionA"

export function MyComponent() {
    return (
        <>
            <h1>Here is your code block:</h1>
            <pre>
                <code>
                    {functionA.toString()}
                </code>
            </pre>
        </>
    )
}

在代码块所在的页面上实际呈现的内容将如下所示:

Here is your code block:

WEBPACK__IMPORT.functionA() {
    console.log("I am function A!")
}

我不完全记得.toString()函数输出是什么样子的,但关键是它不仅仅是文件的内容,例如它在代码编辑中的显示方式——它已经被 WebPack 模块化。

那么,在 Gatsby 项目中,我如何才能让这些不同的代码片段直接作为字符串导入,纯粹按照它们的编写方式,而不需要 WebPack 在其上执行其导入内容?是否有插件或某种方式告诉 Webpack 使用导入的文件作为其asset/source模块类型?我知道 MD 或 MDX 文件有gatsby-remark-embed-snippet,但我正在构建一个基于组件的 HTML 页面,不能使用 MD 或 MDX 文件!

已经很晚了,也许我只是从树上看不到森林,我知道一定有办法做到这一点......

标签: reactjswebpackmoduleembed

解决方案


您需要require使用 webpack 的文件raw-loader,即:

const functionA = require("!!raw-loader!./functionA");

这适用于create-react-app就像这里讨论的解决方案一样,这也适用于 Gatsby!

在这样的文件上使用后require,文件内容可以在组件中呈现为:

<pre>{functionA.default.toString()}</pre>

然后由您使用 prism 或类似工具添加语法突出显示。

请注意,此解决方案仅在 Gatsby V3 继续使用 WebPack v4 时才有效,正如raw-loader在 WebPack v5 中已弃用的那样,并且将逐步淘汰asset/source类型模块。


推荐阅读