Gatsby.js未按gatsby-node.js中GraphQL查询规则生成动态页面求助
问题说明
我执行完gatsby clean之后再运行npm run develop,问题依旧没有解决。
熟悉Gatsby框架的其他开发者也检查过我的gatsby-node.js文件,同样找不到问题根源。
问题排查与修复方案
代码中存在两处核心配置错误,直接导致运行异常:
- gatsby-node.js中重复定义了
onCreateWebpackConfig钩子,后定义的内容会覆盖先定义的内容,针对react-spring-3d-carousel的SSR兼容配置完全未生效 - gatsby-ssr.js中错误添加了window对象判断,SSR阶段本身不存在window对象,导致服务端渲染时根组件包裹逻辑未执行,触发服务端与客户端渲染内容不匹配的hydration错误
具体修复步骤
- 合并gatsby-node.js中的重复配置
删除gatsby-node.js中重复的exports.onCreateWebpackConfig定义,合并为以下内容:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => { if (stage === 'build-html') { actions.setWebpackConfig({ module: { rules: [ { test: /react-spring-3d-carousel/, use: loaders.null() }, { test: /bad-module/, use: loaders.null() }, ], }, }) } }
- 修正gatsby-ssr.js的根组件包裹逻辑
删除gatsby-ssr.js中的window判断,调整为以下内容:
import RootWrapper from './src/components/ui/root-wrapper' export const wrapRootElement = RootWrapper
- 重启开发服务
修改完成后执行gatsby clean && npm run develop重新启动服务即可。
关联代码文件
gatsby-node.js
/** * Implement Gatsby's Node APIs in this file. * * See: https://www.gatsbyjs.org/docs/node-apis/ */ // You can delete this file if you're not using it exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions const result = await graphql( ` { products: allStrapiProduct { edges { node { name strapiId description category { name } variants { id color size style price images { localFile { childImageSharp { gatsbyImageData } } } } } } } categories: allStrapiCategory { edges { node { strapiId name description filterOptions { Size { checked label } Style { checked label } Color { checked label } } } } } } ` ) if (result.errors) { throw result.errors } const products = result.data.products.edges const categories = result.data.categories.edges products.forEach(product => { createPage({ path: `/${product.node.category.name.toLowerCase()}/${ product.node.name.split(' ')[0] }`, component: require.resolve('./src/templates/ProductDetail.js'), context: { name: product.node.name, id: product.node.strapiId, category: product.node.category.name, description: product.node.description, variants: product.node.variants, product, }, }) }) categories.forEach(category => { createPage({ path: `/${category.node.name.toLowerCase()}`, component: require.resolve('./src/templates/ProductList.js'), context: { name: category.node.name, description: category.node.description, id: category.node.strapiId, filterOptions: category.node.filterOptions, }, }) }) }
gatsby-config.js
require("dotenv").config() module.exports = { siteMetadata: { title: `VAR-X`, description: `The premier developer clothing line. By developers, for developers. High quality, custom-designed shirts, hats, and hoodies.`, author: `Zachary Reece`, keywords: [ "clothing", "developer", "programmer", "coding", "code", "websites", "web developer", "hats", "shirts", "hoodies", ], siteUrl: "https://formstorm.design", twitterUsername: "@zacharydreece", defaultImage: "", }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-material-ui`, `gatsby-plugin-sitemap`, `gatsby-plugin-image`, { resolve: `gatsby-plugin-robots-txt`, options: { host: "https://formstorm.design", sitemap: "https://formstorm.design/sitemap.xml", policy: [{ userAgent: "*", allow: "/" }], }, }, { resolve: `gatsby-plugin-loadable-components-ssr`, options: { useHydrate: true, }, }, { resolve: "gatsby-plugin-web-font-loader", options: { google: { families: [ "Philosopher:700:latin", "Montserrat:700,600,500,400,300:latin", ], }, }, }, { resolve: `gatsby-source-strapi`, options: { apiURL: process.env.GATSBY_STRAPI_URL, queryLimit: 1000, collectionTypes: [`product`, `category`, `variant`], }, }, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images`, }, }, `gatsby-transformer-sharp`, { resolve: `gatsby-plugin-sharp`, options: { defaults: { formats: [`auto`, `webp`], placeholder: "blurred", breakpoints: [300, 600, 960, 1280, 1920], }, }, }, { resolve: `gatsby-plugin-manifest`, options: { name: `VAR-X`, short_name: `VAR-X`, start_url: `/`, background_color: `#99B898`, theme_color: `#99B898`, display: `minimal-ui`, icon: `src/images/favicon.png`, }, }, `gatsby-plugin-offline`, ], }
gatsby-browser.js
/** * Implement Gatsby's Browser APIs in this file. * * See: https://www.gatsbyjs.org/docs/browser-apis/ */ // You can delete this file if you're not using it import RootWrapper from "./src/components/ui/root-wrapper" export const wrapRootElement = RootWrapper
root-wrapper.js(被gatsby-browser.js和gatsby-ssr.js引用)
import React from "react" import { ThemeProvider } from "@material-ui/core/styles" import { ApolloWrapper } from "../../apollo/ApolloWrapper" import { UserWrapper, FeedbackWrapper, CartWrapper } from "../../contexts" import theme from "./theme" export default ({ element }) => { return ( <ThemeProvider theme={theme}> <ApolloWrapper> <UserWrapper> <FeedbackWrapper> <CartWrapper>{element}</CartWrapper> </FeedbackWrapper> </UserWrapper> </ApolloWrapper> </ThemeProvider> ) }
gatsby-ssr.js
/** * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. * * See: https://www.gatsbyjs.org/docs/ssr-apis/ */ import RootWrapper from './src/components/ui/root-wrapper' export const wrapRootElement = RootWrapper
package.json
{ "name": "JAMstack-Course", "private": true, "description": "The frontend of a JAMstack e-commerce platform built for a Udemy course.", "version": "1.0.0", "author": "Zachary Reece <jamstack.course@gmail.com>", "dependencies": { "@apollo/client": "^3.2.9", "@loadable/component": "^5.15.0", "@material-ui/core": "^4.11.0", "@material-ui/data-grid": "^4.0.0-alpha.21", "@material-ui/lab": "^4.0.0-alpha.56", "@stripe/react-stripe-js": "^1.2.2", "@stripe/stripe-js": "^1.12.1", "axios": "^0.21.0", "cross-fetch": "^3.0.6", "gatsby": "^3.14.0", "gatsby-plugin-image": "^1.6.0", "gatsby-plugin-loadable-components-ssr": "^3.4.0", "gatsby-plugin-manifest": "^3.14.0", "gatsby-plugin-material-ui": "^2.1.10", "gatsby-plugin-offline": "^3.2.28", "gatsby-plugin-react-helmet": "^3.3.11", "gatsby-plugin-robots-txt": "^1.6.2", "gatsby-plugin-sharp": "^3.14.0", "gatsby-plugin-sitemap": "^4.10.0", "gatsby-plugin-web-font-loader": "^1.0.4", "gatsby-source-filesystem": "^2.3.30", "gatsby-source-strapi": "^1.0.2", "gatsby-transformer-sharp": "^3.14.0", "prop-types": "^15.7.2", "react": "^16.12.0", "react-dom": "^16.12.0", "react-helmet": "^6.1.0", "react-lottie": "^1.2.3", "react-resize-aware": "^3.1.1", "react-spring": "^9.2.4", "react-spring-3d-carousel": "^1.2.1", "uuid": "^8.3.2" }, "devDependencies": { "@babel/eslint-parser": "^7.15.7", "@babel/preset-react": "^7.14.5", "@types/node": "^16.10.2", "@typescript-eslint/eslint-plugin": "^4.32.0", "@typescript-eslint/parser": "^4.32.0", "eslint": "^7.32.0", "eslint-config-airbnb": "^18.2.1", "eslint-config-airbnb-typescript": "^14.0.0", "eslint-config-prettier": "^8.3.0", "eslint-config-wesbos": "^2.0.1", "eslint-plugin-html": "^6.2.0", "eslint-plugin-import": "^2.24.2", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.26.0", "eslint-plugin-react-hooks": "^4.2.0", "prettier": "^2.4.1", "typescript": "^4.4.3" }, "keywords": [ "gatsby" ], "license": "0BSD", "scripts": { "build": "gatsby build", "develop": "gatsby develop", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", "start": "npm run develop", "serve": "gatsby serve", "clean": "gatsby clean", "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1" } }
内容的提问来源于stack exchange,提问作者ThisIsShayan
相关产品推荐
相关产品推荐

