构建 Gatsby 后损坏的组件
Broken components after building Gatsby
站点在构建后失去所有功能。在开发模式下,一切正常,但当我构建网站时,似乎所有脚本都丢失了。 Bootstrap (Carousel DropDowns) 没有响应,leflet 地图和背景图片没有加载,react-multi-carousel 不工作。我在浏览器控制台中没有看到任何错误,当然我 运行 gatsby clean
在构建之前。我将项目上传到 netlify。下面我附上 json 包:
{
"name": "Website",
"private": true,
"description": "Description",
"version": "0.1.0",
"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"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"bootstrap": "^4.6.0",
"gatsby": "^3.2.1",
"gatsby-background-image": "^1.5.0",
"gatsby-image": "^3.2.0",
"gatsby-link": "^3.2.0",
"gatsby-plugin-image": "^1.2.0",
"gatsby-plugin-postcss": "^4.2.0",
"gatsby-plugin-react-helmet": "^4.2.0",
"gatsby-plugin-react-leaflet": "^3.0.0",
"gatsby-plugin-recaptcha": "^1.0.5",
"gatsby-plugin-robots-txt": "^1.5.5",
"gatsby-plugin-sass": "^4.2.0",
"gatsby-plugin-sharp": "^3.2.0",
"gatsby-plugin-sitemap": "^3.2.0",
"gatsby-remark-images": "^4.2.0",
"gatsby-source-filesystem": "^3.2.0",
"gatsby-transformer-remark": "^3.2.0",
"gatsby-transformer-sharp": "^3.2.0",
"gbimage-bridge": "^0.1.2",
"leaflet": "^1.7.1",
"node-sass": "^5.0.0",
"postcss": "^8.2.9",
"react": "^17.0.2",
"react-animations": "^1.0.0",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.2",
"react-helmet": "^6.1.0",
"react-leaflet": "^3.1.0",
"react-multi-carousel": "^2.6.2",
"react-scripts": "^4.0.3",
"styled-components": "^5.2.3"
},
"devDependencies": {
"http-proxy-middleware": "^1.1.0",
"netlify-lambda": "^2.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1"
}
}
问题中没有太多调试,但是,对我来说,您似乎在 React 范围之外使用了一些依赖项,这可能会阻塞 React's hydration process, which may explain the problem described. For example, using Leaflet instead of React's Leaflet or (depending on its implementation) Bootstrap instead of React's Boostrap.
您应该能够毫不费力地将所有对 React 不友好的模块更改为 React 的模块,这应该可以解决您的问题。
请记住,如果您的项目“在 develop
中工作并在 build
中中断”并不意味着您的项目在工作或停止工作,它只是意味着它在某些和具体情况。基本上,总结一下(为了避免扩展答案),gatsby develop
使用浏览器作为解释器,其中有 window
或 document
等全局对象。但是,gatsby build
发生在节点服务器中,在构建时,没有全局对象,因为甚至还没有创建,这是您可能在两种情况下面临不同行为但没有的主要原因意味着该项目神奇地停止工作。
您可以在 Overview of Gatsby Build Process 中阅读更多详细信息。
与阻塞 React 的水合作用相关的另一种选择是,某些组件可能由于其自身的行为而阻塞了该过程。使用 window
或 document
之类的全局对象(或导入使用它的模块时)时要小心,它们的使用应始终包含在以下条件中,正如您从 [=24= 中看到的那样]:
When referencing window in a React component.
import * as React from "react"
// Check if window is defined (so if in the browser or in node.js).
const isBrowser = typeof window !== "undefined"
export default function MyComponent() {
let loggedIn = false
if (isBrowser) {
window.localstorage.getItem("isLoggedIn") === "true"
}
return <div>Am I logged in? {loggedIn}</div>
}
或者需要模块时:
// Requiring a function causes an error during builds
// as the code tries to reference window
const module = require("module") // Error
// Wrap the require in check for window
if (typeof window !== `undefined`) {
const module = require("module")
}
可以使用文档建议的可加载组件来完成相同的方法,但如果不提供任何代码,就不可能猜出它的实现应该是什么。
我通过将传单地图包装在 Loadable 中解决了这个问题
import React from 'react';
import Loadable from "@loadable/component"
const LoadableMap = Loadable(() => import("./map.js"))
export default LoadableMap;
站点在构建后失去所有功能。在开发模式下,一切正常,但当我构建网站时,似乎所有脚本都丢失了。 Bootstrap (Carousel DropDowns) 没有响应,leflet 地图和背景图片没有加载,react-multi-carousel 不工作。我在浏览器控制台中没有看到任何错误,当然我 运行 gatsby clean
在构建之前。我将项目上传到 netlify。下面我附上 json 包:
{
"name": "Website",
"private": true,
"description": "Description",
"version": "0.1.0",
"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"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"bootstrap": "^4.6.0",
"gatsby": "^3.2.1",
"gatsby-background-image": "^1.5.0",
"gatsby-image": "^3.2.0",
"gatsby-link": "^3.2.0",
"gatsby-plugin-image": "^1.2.0",
"gatsby-plugin-postcss": "^4.2.0",
"gatsby-plugin-react-helmet": "^4.2.0",
"gatsby-plugin-react-leaflet": "^3.0.0",
"gatsby-plugin-recaptcha": "^1.0.5",
"gatsby-plugin-robots-txt": "^1.5.5",
"gatsby-plugin-sass": "^4.2.0",
"gatsby-plugin-sharp": "^3.2.0",
"gatsby-plugin-sitemap": "^3.2.0",
"gatsby-remark-images": "^4.2.0",
"gatsby-source-filesystem": "^3.2.0",
"gatsby-transformer-remark": "^3.2.0",
"gatsby-transformer-sharp": "^3.2.0",
"gbimage-bridge": "^0.1.2",
"leaflet": "^1.7.1",
"node-sass": "^5.0.0",
"postcss": "^8.2.9",
"react": "^17.0.2",
"react-animations": "^1.0.0",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.2",
"react-helmet": "^6.1.0",
"react-leaflet": "^3.1.0",
"react-multi-carousel": "^2.6.2",
"react-scripts": "^4.0.3",
"styled-components": "^5.2.3"
},
"devDependencies": {
"http-proxy-middleware": "^1.1.0",
"netlify-lambda": "^2.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1"
}
}
问题中没有太多调试,但是,对我来说,您似乎在 React 范围之外使用了一些依赖项,这可能会阻塞 React's hydration process, which may explain the problem described. For example, using Leaflet instead of React's Leaflet or (depending on its implementation) Bootstrap instead of React's Boostrap.
您应该能够毫不费力地将所有对 React 不友好的模块更改为 React 的模块,这应该可以解决您的问题。
请记住,如果您的项目“在 develop
中工作并在 build
中中断”并不意味着您的项目在工作或停止工作,它只是意味着它在某些和具体情况。基本上,总结一下(为了避免扩展答案),gatsby develop
使用浏览器作为解释器,其中有 window
或 document
等全局对象。但是,gatsby build
发生在节点服务器中,在构建时,没有全局对象,因为甚至还没有创建,这是您可能在两种情况下面临不同行为但没有的主要原因意味着该项目神奇地停止工作。
您可以在 Overview of Gatsby Build Process 中阅读更多详细信息。
与阻塞 React 的水合作用相关的另一种选择是,某些组件可能由于其自身的行为而阻塞了该过程。使用 window
或 document
之类的全局对象(或导入使用它的模块时)时要小心,它们的使用应始终包含在以下条件中,正如您从 [=24= 中看到的那样]:
When referencing window in a React component.
import * as React from "react" // Check if window is defined (so if in the browser or in node.js). const isBrowser = typeof window !== "undefined" export default function MyComponent() { let loggedIn = false if (isBrowser) { window.localstorage.getItem("isLoggedIn") === "true" } return <div>Am I logged in? {loggedIn}</div> }
或者需要模块时:
// Requiring a function causes an error during builds // as the code tries to reference window const module = require("module") // Error // Wrap the require in check for window if (typeof window !== `undefined`) { const module = require("module") }
可以使用文档建议的可加载组件来完成相同的方法,但如果不提供任何代码,就不可能猜出它的实现应该是什么。
我通过将传单地图包装在 Loadable 中解决了这个问题
import React from 'react';
import Loadable from "@loadable/component"
const LoadableMap = Loadable(() => import("./map.js"))
export default LoadableMap;