如何在 Gatsby 页面上包含本地 javascript?

IT技术 javascript reactjs gatsby
2021-03-02 20:18:57

我是一个完全的 React 新手,我想这里有一些我不太了解的基本知识。默认的 Gatsby 页面如下所示。有没有办法像这样使用本地 .js 文件?

<script src="../script/script.js"></script>

我想要实现的是让react忽略script.js但仍然让客户端使用它。默认的 Gatsby 页面看起来像这样,是否可以在那里做类似的事情?

import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

const IndexPage = () => (
  <Layout>
    <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
      <Image />
    </div>
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)
6个回答

经过几个小时的沮丧之后,我终于偶然发现了GitHub上的讨论,为我解决了这个问题。在 Gatsby 中,有一个叫做static folder的东西,一个用例是在捆绑代码之外包含一个小脚本。

遇到相同情况的其他人,请尝试按以下步骤操作:

  1. static在项目的根目录下创建一个文件夹

  2. 将您的脚本script.js放在文件夹中static

  3. 使用 react-helmet将脚本包含在您的 react dom 中

因此,对于我在原始问题中发布的代码,例如:

import React from "react"
import Helmet from "react-helmet"
import { withPrefix, Link } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

const IndexPage = () => (
  <Layout>
    <Helmet>
        <script src={withPrefix('script.js')} type="text/javascript" />
    </Helmet>
    <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
      <Image />
    </div>
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)

注意进口

import Helmet from "react-helmet"
import { withPrefix, Link } from "gatsby"

和脚本元素。

<Helmet>
    <script src={withPrefix('script.js')} type="text/javascript" />
</Helmet>

这会节省我几个小时的时间,希望这对其他人有用。

它适用于 gatsby 开发模式,但未在 gatsby 构建中正确包含文件。请问有什么建议吗?
2021-04-27 20:18:57
非常感谢。有谁知道是否可以在 <head> 标签之外包含脚本?我通常更喜欢在正文的末尾而不是在顶部有一个脚本以提高加载速度(或者这几乎不会影响任何事情?)
2021-05-09 20:18:57
和我一样
2021-05-19 20:18:57
@Mayron 如果您希望脚本始终在导航时加载,一个解决方案是在 componentDidMount 期间加载它,例如,请参见:github.com/gatsbyjs/gatsby/issues/13136您也可以使用 gatsby-ssr 将它们加载到身体的底部,但也可以阅读以下内容:gatsbyjs.org/docs/using-client-side-only-packages
2021-05-20 20:18:57
@Mayron 另请参阅此答案:stackoverflow.com/questions/60066579/...
2021-05-21 20:18:57

只需gatsby-ssr.js在根文件夹中创建文件

并为您的脚本文件夹添加以下模式

import React from 'react'

export const onRenderBody = ({ setPostBodyComponents }) => {
  setPostBodyComponents([
    <script
      key="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
      integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
      crossOrigin="anonymous"
      defer
    />,
    <script
      key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossOrigin="anonymous"
      defer
    />
  ])
}

然后,在 dom 的末尾,您将看到脚本的链接 在此处输入图片说明

在 GatsbyJS 中添加脚本的方法有很多种...

在特定页面上执行脚本

  • 创建一个无状态scriptComponent.js文件并将其放在您的/src文件夹中。

  • scriptComponent.js使用require()中执行脚本里面useEffect()是这样的:

     useEffect(() => {
       // This runs the script
       const myScript = require('../script.js')
     }, [])
    
     return <div />
    
  • 要在客户端运行它,您可以检查文件中window对象script.js

     if(typeof window !== 'undefined' && window.document) {
        // Your script here...
     }
    
  • 最后,转到要执行其中的脚本的页面(例如/pages/myPage.js),并添加组件<scriptComponent />

如果您想在(每个组件/页面)中全局执行脚本您可以使用该html.js文件。

  • 首先,您必须通过运行来提取文件(以防万一):

cp .cache/default-html.js src/html.js

  • 在您的html.js文件中:
<script dangerouslySetInnerHTML= {{ __html:`
  // your script here...
`}} />
这对外部 js 是否有效?IE。公共jqueryurl?
2021-04-28 20:18:57
感觉这就是 React 的做法。
2021-05-21 20:18:57

如果你想使用 Gatsby 插件,对我来说这与使用 Helmet 这样的外部库没有什么不同(插件毕竟是 npm 包),你可以使用gatsby-plugin-load-script

您可以提供src属性的 url或本地路径。如果您要将 JS 存储在本地文件中,例如some-minified-js.min.js- 请确保存储在static项目根目录下的目录中。

完成此操作后,您可以通过全局对象访问:

global.<object or func name here>

例如,我试图通过一个缩小的文件包含一个非常小的 JS 库,所以我将文件存储在其中/static/my-minified-library.min.js,然后:

  1. 安装了插件: npm i --save gatsby-plugin-load-script
  2. 将此添加到我的 gatsby-config.js
plugins: [
    {
      resolve: "gatsby-plugin-load-script",
      options: {
        src: "/my-minified-library.min.js",
      },
    },
  ],
  1. 在我的react组件中访问,如下所示:
useEffect(() => {
  const x = new global.MyImportedLibraryObject();
}, []}

Gatsby 在 src 文件夹中使用 html.js。不像大多数react项目那样 index.html 。

示例 html.js 文件:

import React from "react"
import PropTypes from "prop-types"

export default class HTML extends React.Component {
  render() {
    return (
      <html {...this.props.htmlAttributes}>
        <head>
          <meta charSet="utf-8" />
          <meta httpEquiv="x-ua-compatible" content="ie=edge" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1, shrink-to-fit=no"
          />
          {this.props.headComponents}
        </head>
        <body {...this.props.bodyAttributes}>
          {this.props.preBodyComponents}
          <div
            key={`body`}
            id="___gatsby"
            dangerouslySetInnerHTML={{ __html: this.props.body }}
          />
          {this.props.postBodyComponents}
        </body>
      </html>
    )
  }
}

HTML.propTypes = {
  htmlAttributes: PropTypes.object,
  headComponents: PropTypes.array,
  bodyAttributes: PropTypes.object,
  preBodyComponents: PropTypes.array,
  body: PropTypes.string,
  postBodyComponents: PropTypes.array,
}

使用dangerouslySetInnerHTMLinside添加自定义 Javascript src/html.js

<script
  dangerouslySetInnerHTML={{
    __html: `
            var name = 'world';
            console.log('Hello ' + name);
        `,
  }}
/>

您可以尝试在那里添加您的 js,但请注意,您的 js 可能无法按预期工作。您可以随时查看 react-helmet 以获取更多动态应用程序并将脚本添加到<head>.

盖茨比文档:https : //www.gatsbyjs.org/docs/custom-html/