Netlify 在我的 Gatsby JS 上抛出关于 jQuery 的错误

Netlify throwing errors on my Gatsby JS about jQuery

正在尝试在 netlify 上部署我的 Gatsby 应用程序。基本上,我为某些特定目的添加了一些 jQuery,但是当我上传它时,我收到了 ff 错误:

11:52:55 AM: failed Building static HTML for pages - 5.342s
11:52:55 AM: error Building static HTML failed
11:52:55 AM: 
11:52:55 AM:   4 |   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
11:52:55 AM:   5 |   */
11:52:55 AM: > 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?

[jQuery snippet here]

11:52:56 AM: npm ERR! errno 1
11:52:56 AM: npm ERR! gatsby-portfolio@0.1.0 build: `gatsby build`
11:52:56 AM: npm ERR! Exit status 1
11:52:56 AM: npm ERR!
11:52:56 AM: npm ERR! Failed at the gatsby-portfolio@0.1.0 build script.
11:52:56 AM: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
11:52:56 AM: npm ERR! A complete log of this run can be found in:
11:52:56 AM: npm ERR!     /opt/buildhome/.npm/_logs/2021-01-19T03_52_56_065Z-debug.log

在这些错误之间显示:

我只在一个地方添加了 jQuery,它在我的 Layout 组件上:

import React from "react"
import "bootstrap/dist/css/bootstrap.min.css"
import "jquery/dist/jquery.min.js"
import "popper.js/dist/popper.min"
import "bootstrap/dist/js/bootstrap.min.js"
import "../assets/css/owl.carousel.min.css"
import "../assets/css/style.css"
import 'aos/dist/aos.css'

import Helmet from "react-helmet"
import AOS from 'aos'
import { withPrefix } from "gatsby"
import Navbar from '../components/Navbar'
import Footer from '../components/Footer'

AOS.init();

const Layout = ({ children }) => {
  return (
     <>
      <Helmet>
          <script src={withPrefix('owl.carousel.min.js')} type="text/javascript" />
          <script src={withPrefix('sticky-menu.js')} type="text/javascript" />
          <script src={withPrefix('script.js')} type="text/javascript" />
      </Helmet>
     <Navbar />
     { children }
     <Footer />
     </>
  )
  
}


export default Layout

您实际上可以在我的 package.json 上看到它是添加的:

"dependencies": {
    "@popperjs/core": "^2.5.3",
    "aos": "^3.0.0-beta.6",
    "bootstrap": "^4.5.3",
    "gatsby": "^2.24.76",
    "gatsby-image": "^2.4.21",
    "gatsby-plugin-prefetch-google-fonts": "^1.4.3",
    "gatsby-source-strapi": "0.0.12",
    "gatsby-transformer-sharp": "^2.5.17",
    "jquery": "^3.5.1",
    "jquery-nav-scroll": "^1.4.1",
    "popper.js": "^1.16.1",
    "react": "^16.12.0",
    "react-anchor-link-smooth-scroll": "^1.0.12",
    "react-dom": "^16.12.0",
    "react-helmet": "^6.1.0",
    "react-icons": "^3.11.0",
    "react-markdown": "^4.3.1",
    "react-scrollspy": "^3.4.3"
  },

不确定如何解决这个问题,过去几个小时一直在这里。知道我该如何解决这个问题吗?

正如我所说,这不是 Netlify 的错,因为该项目不是在本地构建的。您应该始终确保您的项目在两种环境(构建和开发)中都正确编码,因为它们之间存在很大差异。在 gatsby develop 下工作的项目并不意味着它编码完美,只意味着它在某些条件下工作。您可以在 Gatsby's docs 中查看运行时和构建时之间的概述,主要区别依赖于 gatsby build 的 Gatsby Server-S ide R渲染(SSR)。请记住,您正在使用 jQuery,它直接指向真实的 DOM,对站点具有高性能影响,而 React,创建和操作虚拟 DOM (v DOM) 避免那种高成本的行为。使用这两种方法很奇怪。

此外,您正在导入 <Layout> 组件中的所有内容,该组件将在多个 components/pages 中用于您的项目。如果重新渲染组件,这可能会导致多个脚本 rendering/loading。

表示,您的问题可能是由于:

  • AOS.init();
  • 脚本导入:因为不是promise,所以会同时导入。如果出于某种原因首先加载其中一个(较轻的)并且它依赖于另一个,它将破坏您的项目,因为它将无法加载。您没有加载 jQuery,除非它在 ​​scripts.js.

你有很多方法,从改变方法和使用基于 React 的方法,到尝试 async 脚本导入(并加载 jQuery 之前),但所有的解决方法都需要通过一些试验和错误进行测试:

加载 jQuery 之前:

  <Helmet>
      <script
    src="https://code.jquery.com/jquery-3.4.1.min.js"
    integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
    crossorigin="anonymous"/>
      <script async src={withPrefix('owl.carousel.min.js')} type="text/javascript" />
      <script async src={withPrefix('sticky-menu.js')} type="text/javascript" />
      <script async src={withPrefix('script.js')} type="text/javascript" />
  </Helmet>

使用async 属性 尝试等待其他脚本。或者,您可以下载 jQuery 并像处理其余依赖项一样静态添加它。

使用基于 async/await 的方法:

  import * as loadScript from 'simple-load-script';
  import 'babel-polyfill'; // must be imported for async/await to work, see e.g. https://github.com/gatsbyjs/gatsby/pull/3369#issuecomment-354599985


    const Layout = ({ children }) => {

     useEffect(()=>{
        await loadScript('https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js', { inBody: true });
        await loadScript('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js', { inBody: true });
     }, [])   

      return (
         <>
         <Navbar />
         { children }
         <Footer />
         </>
      )
      
    }

注:来自https://github.com/gatsbyjs/gatsby/issues/3182

使用这种方法,您正在等待 useEffect 挂钩中的脚本加载 loadScript(来自 simple-load-script)库,与空 deps[]) 就像将它用作 componentDidMount 生命周期,或者换句话说,一旦 DOM 树被加载(异步)。

使用SSR:

在你的gatsby-ssr.js中:

import React from 'react';

export const onRenderBody = ({ setHeadComponents }, pluginOptions) => {
  setHeadComponents([
    <script
      src="https://code.jquery.com/jquery-3.4.1.min.js"
      integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
      crossOrigin="anonymous">
    </script>,
  ])
}

那个,在你的gatsby-browser.js中:

const $ = require("jquery")

export const onInitialClientRender = () => {
  $(document).ready(function () {
    console.log("The answer is don't think about it!")
  });
}

这将使用 onRenderBody API across with onInitialClientRender(客户端的第一次渲染)在 SSR 上加载 jQuery,避免后续渲染,因为您的方法可能会导致。