Gatsby 无法构建静态页面

Gatsby Failing to build static pages

我一直在使用 Gatsby 构建自定义 Shopify 和 Netlify CMS 页面。开发构建一直很好。但是当我尝试部署到 Netlify 时,它无法加载 /about 页面。我不知道为什么。它一直指向我的 useCart() 函数,这很奇怪,因为关于页面与我的 useCart 函数无关。

我会尽量在下面包含我能想到的所有相关代码。

Netlify 构建错误:

1:00:24 PM: failed Building static HTML for pages - 0.474s
1:00:24 PM: error Building static HTML failed for path "/about"
1:00:25 PM: 
1:00:25 PM:   36 |
1:00:25 PM:   37 | export const useCart = () => {
1:00:25 PM: > 38 |   const [checkout, dispatch] = useContext(CartContext);
1:00:25 PM:      |          ^
1:00:25 PM:   39 |
1:00:25 PM:   40 |   const setCheckout = useCallback(
1:00:25 PM:   41 |     (checkout) => dispatch({ type: 'SET_CHECKOUT', checkout }),
1:00:25 PM: 
1:00:25 PM:   WebpackError: TypeError: Cannot destructure '(0 , react__WEBPACK_IMPORTED_MODU  LE_0__.useContext)(...)' as it is undefined.

购物车-context.js (useCart())

export const useCart = () => {
  const [checkout, dispatch] = useContext(CartContext);

  const setCheckout = useCallback(
    (checkout) => dispatch({ type: 'SET_CHECKOUT', checkout }),
    [dispatch],
  );

  useEffect(() => {
    async function getCheckout() {
      if (checkout) return;

      if (!IS_BROWSER) {
        setCheckout({});
      }

      // check if we already have a cart stored for this browser
      const existingCheckoutID = localStorage.getItem('shopify_checkout_id');
      if (existingCheckoutID && existingCheckoutID !== 'null') {
        try {
          const existingCheckout = await client.checkout.fetch(
            existingCheckoutID,
          );

          // if this cart was already purchased, clear it and start fresh
          if (!existingCheckout.completedAt) {
            setCheckout(existingCheckout);
            return;
          }
        } catch (error) {
          localStorage.removeItem('shopify_checkout_id');
        }
      }

      // if we get here, we need to create a new checkout session
      const newCheckout = await client.checkout.create();
      localStorage.setItem('shopify_checkout_id', newCheckout.id);
      setCheckout(newCheckout);
    }

    getCheckout();
  }, [checkout, setCheckout]);

  const prepItem = ({ variantId, quantity }) => [
    {
      variantId,
      quantity: parseInt(quantity, 10),
    },
  ];

  const addItemToCart = async (item) => {
    dispatch({ type: 'PENDING' });

    try {
      const updatedCheckout = await client.checkout.addLineItems(
        checkout.id,
        prepItem(item),
      );
      setCheckout(updatedCheckout);
    } catch (error) {
      console.error(error);
    }
  };

  const removeItemFromCart = async (variantId) => {
    dispatch({ type: 'PENDING' });

    try {
      const updatedCheckout = await client.checkout.removeLineItems(
        checkout.id,
        [variantId],
      );
      setCheckout(updatedCheckout);
    } catch (error) {
      console.error(error);
    }
  };

  return { checkout, addItemToCart, removeItemFromCart };
};

盖茨比-node.js

const path = require("path")
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions

  const blogList = path.resolve(`./src/templates/blog-list.js`)

  const result = await graphql(`
    {
      allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
        edges {
          node {
            id
            frontmatter {
              slug
              template
              title
            }
          }
        }
      }
    }
  `)

  // Handle errors
  if (result.errors) {
    reporter.panicOnBuild(`Error while running Blog GraphQL query.`)
    return
  }

  // Create markdown pages
  const posts = result.data.allMarkdownRemark.edges
  let blogPostsCount = 0

  posts.forEach((post, index) => {
    const id = post.node.id
    const previous = index === posts.length - 1 ? null : posts[index + 1].node
    const next = index === 0 ? null : posts[index - 1].node

    createPage({
      path: post.node.frontmatter.slug,
      component: path.resolve(
        `src/templates/${String(post.node.frontmatter.template)}.js`
      ),
      // additional data can be passed via context
      context: {
        id,
        previous,
        next,
      },
    })

    // Count blog posts.
    if (post.node.frontmatter.template === "blog-post") {
      blogPostsCount++
    }
  })

  // Create blog-list pages
  const postsPerPage = 9
  const numPages = Math.ceil(blogPostsCount / postsPerPage)

  Array.from({ length: numPages }).forEach((_, i) => {
    createPage({
      path: i === 0 ? `/events` : `/events/${i + 1}`,
      component: blogList,
      context: {
        limit: postsPerPage,
        skip: i * postsPerPage,
        numPages,
        currentPage: i + 1,
      },
    })
  })

  return graphql (`
  {
    allShopifyProduct {
      nodes {
        id
        handle
        images {
          gatsbyImageData
          originalSrc
        }
      }
    }
  }
  `).then(result => {
      const products = result.data.allShopifyProduct.nodes;
      
      products.forEach((product) => {
        if (
          !product ||
          !product.images ||
          !product.images[0] ||
          !product.images[0].gatsbyImageData
        ) {
          return;
        }
          actions.createPage({
            path: `/product/${product.handle}`,
            component: require.resolve('./src/templates/product-page.js'),
            context: {
              productID: product.id,
            },
          });
        });
  })
}

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

盖茨比浏览器:

import React from 'react';
import { CartProvider } from './src/context/cart-context';

export const wrapRootElement = ({ element }) => (
  <CartProvider>{element}</CartProvider>
);

export const onServiceWorkerUpdateReady = () => {
  const answer = window.confirm(
    `This application has been updated. ` +
      `Reload to display the latest version?`
  )

  if (answer === true) {
    window.location.reload()
  }
}

我最终需要一个 gatsby-ssr.js 文件。谢谢 Ferran Buireu 的想法。

盖茨比-ssr.js

export { wrapRootElement } from './gatsby-browser';