Gatsby/React如何导入代码文件为源字符串 避开Webpack处理 用于Prism高亮
Gatsby 项目导入代码文件原始内容实现方案
核心实现思路
Webpack 5 原生支持 asset/source 资源模块类型,可以直接将匹配的文件以原始字符串的形式导出,完全绕过模块编译逻辑,不需要依赖额外第三方插件。Gatsby 底层基于 Webpack 5 构建,直接修改 Webpack 配置即可实现需求。
具体配置步骤
- 单独创建用于存放待展示代码片段的目录,比如
src/code-samples/,把所有需要在页面里高亮展示的.ts/.tsx/.js/.jsx文件放到这个目录下,和正常业务代码做物理隔离,避免配置冲突。 - 在项目根目录的
gatsby-node.js中添加 Webpack 配置钩子:exports.onCreateWebpackConfig = ({ actions }) => { actions.setWebpackConfig({ module: { rules: [ { // 匹配专门代码片段目录下的所有代码文件 test: /src\/code-samples\/.*\.(ts|tsx|js|jsx)$/, // 用asset/source模式处理,导出值为文件原始内容字符串 type: 'asset/source', }, ], }, }) } - 配置完成后,直接在组件中导入目标代码文件,拿到的导入值就是和编辑器内完全一致的原始文件字符串:
import * as React from "react" // 直接导入,无模块包装、无Webpack注入代码 import functionACode from "../code-samples/functionA.ts" export function MyComponent() { return ( <> <h1>Here is your code block:</h1> // 直接将拿到的字符串传入PrismJS高亮组件即可 <pre> <code className="language-typescript"> {functionACode} </code> </pre> </> ) }
关键注意事项
- 绝对不要全局匹配所有目录下的代码文件走
asset/source规则:如果把正常业务逻辑的.ts/.tsx文件也标记为原始字符串,Webpack 会直接跳过编译,导致项目完全无法运行。一定要通过目录隔离、文件特殊后缀标记的方式,只把需要展示的非执行代码纳入规则匹配范围。 - 之前尝试通过
functionA.toString()拿代码的方案本质上是利用模块加载的副产物,Webpack在编译模块时会自动注入模块标识、导出包装逻辑、热更新钩子,导致toString输出的内容和原始文件存在差异,从原理上就无法拿到完全一致的原始代码,不推荐使用。 - 用
asset/source拿到的内容是文件磁盘上的原始文本,包括所有缩进、空行、注释,和编辑器内显示的内容1:1一致,满足PrismJS高亮的输入要求。 - 不需要额外安装
raw-loader这类旧版Webpack生态的插件,asset/source是Webpack5原生能力,没有额外依赖成本。
内容的提问来源于stack exchange,提问作者fullStackChris
相关产品推荐
相关产品推荐

