ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Gatsby 常见错误排查实战指南:从本地开发到构建部署的完整故障处理手册

Gatsby 常见错误排查实战指南:从本地开发到构建部署的完整故障处理手册 Gatsby 常见错误排查实战指南从本地开发到构建部署的完整故障处理手册【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby本指南以 Gatsby 官方文档《Troubleshooting Common Errors》为核心系统梳理了使用gatsby develop与gatsby build过程中最常见的故障类型包括缓存问题、插件配置缺失、样式渲染不一致、GraphQL 数据层报错、图像处理sharp安装冲突以及构建部署期的浏览器全局对象与文件系统问题。文中每一类错误均给出可复现的现象描述、根因分析、可执行的修复命令与配置片段并结合本仓库源码packages/gatsby、packages/gatsby-cli、packages/gatsby-plugin-image等佐证底层原理帮助你快速定位问题、准确修复并理解错误背后的工作机制。Gatsby 是 React 生态中把构建时数据层GraphQL、静态资源优化与服务端渲染深度耦合的框架这意味着其错误面也比普通 SPA 更广很多问题只在gatsby build时出现很多问题源于插件之间的依赖顺序还有一些问题源自 Node.js 环境与浏览器环境的差异。本文按故障域分组逐一给出排查路径。缓存相关问题gatsby clean是万能的“重来一次”gatsby develop会在本地启动开发服务器并启用热模块替换Hot-Module ReplacementHMR。为了不重复处理已经优化过的资源Gatsby 会把数据与渲染产物的缓存放在站点根目录下的.cache文件夹中。当你看到“无法在缓存中找到某个资源”之类的错误时最直接的手段就是清空缓存并重启服务器gatsby clean这条命令会同时删除.cache与public两个目录之后再运行gatsby develop就会重新创建缓存并重新处理全部资源。在源码层面gatsby clean由 packages/gatsby-cli/src/create-cli.ts 注册为 CLI 子命令其核心清理逻辑位于 packages/gatsby/src/commands/clean.ts本质上是对.cache与public目录的递归删除。值得注意的是如果你通过GATSBY_PRESERVE_CACHE或相关标志开启了缓存保留策略gatsby clean的清理范围会受到影响因此当怀疑“清理不彻底”时也可以手动删除这两个目录后重试。如果错误与缓存持久化有关例如增量构建场景可进一步参考 Debugging Cache Issues 专项指南以及仓库中与此对应的 umbrella issue 讨论串。插件配置导致的构建失败插件用于扩展 Gatsby 的功能参见 什么是插件但新行为也意味着新错误。最典型的一类问题是只安装了插件却没有安装插件所依赖的配套库。安装样式类插件后报Generating SSR bundle failed如果在安装某个插件后运行gatsby develop或gatsby build时看到 webpack 错误Generating SSR bundle failed很可能是有依赖包没有装齐。对于 emotion、styled-components、Sass 这类插件官方安装说明通常会引导你装齐所有库但一些第三方教程或博客可能漏掉了这一步。以下插件就要求你安装的不止插件本身gatsby-plugin-emotion还需安装emotion/react、emotion/styledgatsby-plugin-styled-components还需安装styled-components、babel-plugin-styled-componentsgatsby-plugin-sass还需安装node-sass或sass二选一gatsby-plugin-material-ui还需安装material-ui/stylesgatsby-plugin-image还需安装gatsby-source-filesystem、gatsby-transformer-sharp、gatsby-plugin-sharp这些插件之所以不把依赖库一起打包是为了在发布时保持体积更小并且能够兼容不同的底层实现。以gatsby-plugin-sass为例它可以选用 Node.js 或 Dart 两种 Sass 实现。从源码也能印证这一点packages/gatsby-plugin-image/package.json 把gatsby-plugin-sharp与gatsby-source-filesystem声明为peerDependencies且标记为 optional即插件运行时需要它们存在但不强制替你安装——这正是错误发生的根源。当依赖缺失时错误信息通常长这样... success run queries - 0.095s - 8/8 84.63/s ERROR #98123 WEBPACK Generating SSR bundle failed Cant resolve emotion/react in /Users/you/tmp/gatsby-site/.cache // highlight-line File: .cache/develop-static-entry.js错误代码#98123的格式化逻辑可以在 packages/gatsby-cli/src/structured-errors/error-map.ts 中找到它属于WEBPACK类别消息主体由具体阶段develop / develop-html / build-javascript / build-html与底层错误信息拼接而成。换言之“Generating SSR bundle failed”只是外层包装真正的线索在Cant resolve xxx那一行——它直接告诉你是哪个模块没装。本例中gatsby-plugin-emotion已加入gatsby-config但 emotion 库本身没装于是npm install emotion/react或者把emotion/react换成实际缺失的库名。装齐插件、所需库并把插件写入gatsby-config后错误即可消除。fs模块无法解析Cannot resolve module fsfs是 Node.js 的文件系统库用于访问本机文件。但当打包后的 Gatsby 代码在浏览器/SSR 环境运行时Node.js 环境并不存在。如果你在 React 组件里直接使用了fs或者在使用mdx-js/runtime时就可能看到顶层报错Cannot resolve module fs或 webpack 错误Cant resolve fs。有些包如 Babel会顺带把fs带进来。为了阻止它引发错误可以在gatsby-node.js中加入exports.onCreateWebpackConfig ({ actions }) { actions.setWebpackConfig({ resolve: { fallback: { fs: false // highlight-line } } }) }在 Gatsby 源码中webpack 配置构建于 packages/gatsby/src/utils/webpack.config.js当构建阶段为build-html时Gatsby 会显式跟踪fs、http、http2、https、child_process等 Node 内建模块见 packages/gatsby/src/utils/webpack.config.js把这些内建模块标记为外部依赖而非打包进 bundle。你在onCreateWebpackConfig中通过resolve.fallback把fs置为false就是告诉 webpack“遇到fs直接返回空模块”从而避免解析失败。样式相关错误develop 与 build 样式不一致以下错误都与站点样式CSS、预处理器或 CSS-in-JS有关。使用 styled-components 或 emotion 时develop 与 build 样式不一致这是非常常见的一类问题安装了 styled-components 或 emotion却在gatsby-config.js里忘了加入对应插件。由于gatsby develop默认不执行服务端渲染如果缺少插件告知 Gatsby 对所用 CSS-in-JS 方案做服务端样式渲染最终 build 出来的页面样式就会与开发时不一致。解决办法把gatsby-plugin-styled-components针对 styled-components或gatsby-plugin-emotion针对 emotion加入gatsby-config.js让 Gatsby 在服务端处理样式保证最终构建产物样式正确。你还可以在gatsby-config中开启DEV_SSR特性开关让gatsby develop期间也启用 SSR从而在开发阶段就发现这类 SSR 相关的样式/渲染问题参见 Debugging HTML BuildsSSR during gatsby develop。在源码层面DEV_SSR定义于 packages/gatsby/src/utils/flags.ts对应环境变量GATSBY_EXPERIMENTAL_DEV_SSR描述为“在 develop 全量刷新时对页面执行服务端渲染帮助你在不跑完整构建的情况下发现 SSR bug”同时FAST_DEV标志会默认包含它见 packages/gatsby/src/utils/flags.ts。GraphQL 数据层错误Gatsby 的 GraphQL 数据层提供构建期数据访问。当你实现数据源插件或自行向 schema 添加节点时可能会遇到以下错误。Unknown field A on type B当 GraphQL 查询请求的字段与 数据接入 后生成的 schema 不一致时就会出现Unknown field A on type B。正如错误字面意思你请求的某个字段在报错所列出的类型下并不存在。如果站点还能正常构建可以打开http://localhost:8000/___graphql检查 schema——它包含该类型上全部字段的定义能帮你确认哪些字段没被创建以及这些字段应当由插件还是你的代码创建。如果错误是Unknown field X on type Query说明你要接入的内容类型很可能没有被正确处理。Query类型代表 GraphQL schema 中的顶层根查询源插件通常会创建可查询的根节点例如mdx由gatsby-plugin-mdx创建或根节点集合如allFile由gatsby-source-filesystem创建。排查此类错误可以按以下思路逐项核对是否用 transformer 插件处理了数据如果用了 transformer如gatsby-transformer-yaml必须确认数据已由源插件如gatsby-source-filesystem拉取。配置示例{ plugins: [ gatsby-transformer-yaml, { resolve: gatsby-source-filesystem, options: { path: ./src/data/, // location of yaml files }, }, ] }内容结构与 schema、查询方式是否一致把 GraphQL 查询与http://localhost:8000/___graphql中的 schema以及你用来接入数据的插件/代码三者放在一起比对——它们应当以相同的形状表达数据。源插件或自定义的sourceNodesAPI 是否配置正确任何一方的配置错误都可能导致字段缺失。gatsby-plugin-image 与 sharp 的错误Gatsby 的图像处理被拆分成多个包需要它们协同工作才能把图片源转换成不同优化版本。以下是最常见的组合问题。Field image must not have a selection since type String has no subfields这个报错意味着GraphQL 查询试图访问某字段的子字段但该字段本身不存在任何子字段。这通常是因为gatsby-config中协同使用的插件顺序错误或者根本没有添加某些插件。查询之所以访问不到子字段是因为这些字段在构建期没有被创建。下面这段查询试图访问image字段的childImageSharp子字段正如错误信息所指问题 schema 长这样allMdx { nodes { id title image } }而期望的 schema 应该是allMdx { nodes { id title image { childImageSharp { gatsbyImageData } } } }在第一个示例中image字段没有被任何插件转换修改以添加子字段所以它只会返回字符串。把gatsby-plugin-sharp和gatsby-transformer-sharp放在其他会操作或创建图片节点的插件如gatsby-source-filesystem、gatsby-source-contentful之前可以确保这些插件在 Gatsby 修改图片节点、添加childImageSharp等字段之前就已就位。更多关于图片如何进入 GraphQL schema 的内容参见 处理外部图片 指南。另一个可能的诱因是站点某处把图片路径写成了空字符串此时 Gatsby 构建 schema 时可能推断出错误类型因为空字符串看起来不像文件路径。安装sharp报gyp ERR! build error如果在安装依赖时看到与 sharp 相关的报错如gyp ERR! build error和npm ERR! Failed at the sharpx.x.x install script通常可以通过删除项目根目录下的node_modules并重新安装来解决# be careful as this command will delete all files recursively in # the folder you provide, in this case, node_modules rm -rf node_modules # this command will install libraries from your package.json file # and place them in the node_modules folder npm install其原理在于安装 sharp 所用 Node.js 的版本必须与运行时 Node.js 版本一致。sharp 属于原生模块安装时会针对当前 Node ABI 编译二进制node-gyp负责该过程因此清空node_modules重新安装往往能解决版本不匹配问题。关于 sharp 安装与图像处理问题的更多讨论可参考 相关 issue。Incompatible library version: sharp.node requires version X or later, but Y provides version Z该错误表示node_modules中安装了多个互不兼容的 sharp 版本。报错可能长这样Something went wrong installing the sharp module dlopen(/Users/you/gatsby-site/node_modules/sharp/build/Release/sharp.node, 1): Library not loaded: rpath/libglib-2.0.dylib Referenced from: /Users/you/gatsby-site/node_modules/sharp/build/Release/sharp.node Reason: Incompatible library version: sharp.node requires version 6001.0.0 or later, but libglib-2.0.dylib provides version 5801.0.0修复方法是更新当前项目中所有依赖sharp的 Gatsby 插件。官方插件中可能涉及的有gatsby-plugin-sharpgatsby-plugin-manifestgatsby-remark-images-contentfulgatsby-source-contentfulgatsby-transformer-sharpgatsby-transformer-sqip执行npm install gatsby-plugin-sharp gatsby-plugin-manifest gatsby-remark-images-contentful gatsby-source-contentful gatsby-transformer-sharp gatsby-transformer-sqip如果更新后仍未解决说明项目里可能还有其他社区插件依赖了不同版本的 sharp。运行npm list sharp或yarn why sharp查看当前项目中所有使用 sharp 的包并一并更新。构建与部署阶段的错误构建站点与开发过程略有差异参见 Gatsby 构建流程概览。如果在代码中引用了浏览器相关对象构建时就可能报错——不过绝大多数问题其实在 develop 模式下就会暴露。构建期常见问题的完整讨论见 Debugging HTML Builds 指南。ReferenceError: window is not defined运行gatsby build时如果你在代码中引用了window、document这类浏览器全局对象可能会遇到开发时没见过、构建时才出现的Error: ReferenceError: window is not defined。原因很简单构建并不运行在浏览器里自然没有浏览器可访问window也就未定义。具体修复步骤见 Debugging HTML Builds如何检查 window 是否已定义 一节核心思路是在访问浏览器全局之前先做存在性判断。Field browser doesnt contain a valid alias configuration如果你看到类似报错Module not found: Error: Cant resolve ../..SomeFile.svg Field browser doesnt contain a valid alias configuration ...说明构建在解析../..SomeFile.svg这个文件时失败。这种情况很容易让人困惑本地gatsby develop一切正常本地gatsby buildgatsby serve也正常但部署后就失败。最可能的原因是本地操作系统与部署环境不同——部署目标通常运行某个 Linux 发行版。最常见的元凶是文件路径大小写混用。以上述报错为例请检查文件实际是否叫SomeFile.svg而不是Somefile.svg或somefile.svg。某些操作系统会自动帮你纠正大小写差异并找到文件但部署环境不一定。最佳做法是检查构建日志中输出文件的大小写修正后重新部署。ENOSPC: System limit for number of file watchers reached这个错误表示你的系统达到了可监视文件数量的上限即运行期间监视站点文件变化进程的数量上限。修复方式是调高系统文件监视器上限echo fs.inotify.max_user_watches524288 | sudo tee -a /etc/sysctl.conf sudo sysctl -p这条命令将 inotify 的用户级文件监视数量上限调整为 524288并立即生效。不同环境可能有差异更多信息可参考 对应的 GitHub issue。总结一份故障排查速查表错误现象根因首选修复缓存中找不到资源.cache/public缓存损坏或过期gatsby clean后重启gatsby developGenerating SSR bundle failed/Cant resolve xxx插件依赖库未安装按报错补装缺失库如npm install emotion/reactCannot resolve module fs浏览器/SSR 环境引用了 Node 内建模块在gatsby-node.js的onCreateWebpackConfig中设置resolve.fallback: { fs: false }develop 与 build 样式不一致CSS-in-JS 插件未加入gatsby-config加入gatsby-plugin-styled-components/gatsby-plugin-emotion可用DEV_SSR在开发期复现Unknown field A on type B查询字段与 schema 不一致检查http://localhost:8000/___graphql核对源插件/transformer 配置与查询结构Field image must not have a selection...图片处理插件缺失或顺序错误将gatsby-plugin-sharp、gatsby-transformer-sharp放在图片源插件之前gyp ERR! build errorsharp 安装失败Node ABI 与 sharp 编译版本不匹配rm -rf node_modules后重新npm installIncompatible library version: sharp.node...存在多个不兼容 sharp 版本更新所有依赖 sharp 的官方插件必要时用npm list sharp排查window is not defined构建期无浏览器环境访问window/document前先判断其是否存在Field browser doesnt contain a valid alias configuration文件路径大小写与部署环境不符核对文件名大小写重新构建部署ENOSPC: ... file watchers reached系统文件监视上限不足调高fs.inotify.max_user_watches并sysctl -p生效排查这类错误时请记住三个原则一是先看最外层错误之下的原始 message如Cant resolve行它往往直接指向缺失的依赖二是善用http://localhost:8000/___graphql对照 schemaGraphQL 相关的字段类错误基本都能由此定位三是区分 develop 与 build 两个环境凡涉及浏览器全局、服务端渲染与原生模块的问题几乎都与环境差异有关。按此思路绝大多数 Gatsby 报错都可以在几分钟内解决。【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进