【问题标题】:How to include local javascript on a Gatsby page?如何在 Gatsby 页面上包含本地 javascript?
【发布时间】:2019-02-22 20:48:27
【问题描述】:

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

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

我想要实现的是反应忽略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>
)

【问题讨论】:

    标签: javascript reactjs gatsby


    【解决方案1】:

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

    遇到同样情况的其他人,请尝试如下操作:

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

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

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

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

    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 构建中未正确包含文件。请问有什么建议吗?
    • 和我一样
    • 非常感谢。有谁知道是否可以在 标签之外包含脚本?我通常更喜欢将脚本放在正文的末尾而不是顶部以提高加载速度(或者这几乎不会影响任何事情?)
    • @Mayron 如果您希望脚本始终在导航时加载,一种解决方案是在 componentDidMount 期间加载它,例如:github.com/gatsbyjs/gatsby/issues/13136。您也可以使用 gatsby-ssr 将它们加载到身体的底部,但也请阅读:gatsbyjs.org/docs/using-client-side-only-packages
    • @Mayron 另请参阅此答案:stackoverflow.com/questions/60066579/…
    【解决方案2】:

    只需在根文件夹中创建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 的末尾看到脚本的链接

    【讨论】:

      【解决方案3】:

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

      在特定页面上执行脚本

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

      • 在您的scriptComponent.js 中使用require() 执行useEffect() 中的脚本,如下所示:

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

         if(typeof window !== 'undefined' && window.document) {
            // Your script here...
         }
        
      • 最后,进入你要在其中执行脚本的页面(例如/pages/myPage.js),并添加组件&lt;scriptComponent /&gt;

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

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

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

      • 在您的 html.js 文件中:
      <script dangerouslySetInnerHTML= {{ __html:`
        // your script here...
      `}} />
      

      【讨论】:

      • 这是否适用于外部 js? IE。公共 jqueryurl?
      • 感觉这就是 React 的做法。
      【解决方案4】:

      如果你想使用 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();
      }, []}
      

      【讨论】:

        【解决方案5】:

        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,
        }
        

        用于在src/html.js 中使用dangerouslySetInnerHTML 添加自定义Javascript:

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

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

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

        【讨论】:

          【解决方案6】:

          您可以使用 Gatsby 插件 "gatsby-plugin-load-script." 轻松完成此操作

          只需这样做:

          1. 在 gatsby 应用的根目录下创建一个名为 static 的文件夹
          2. 将您的脚本放入其中
          3. gatsby-config.js中添加如下配置
              {
                resolve: 'gatsby-plugin-load-script',
                options: {
                  src: '/test-script.js', // Change to the script filename
                },
              },
          

          【讨论】:

            【解决方案7】:

            我不确定是否还有人需要这个答案,但它就是这样:

            Elliot Marques 的回答非常好。如果您需要它作为本地文件,请将脚本上传到 Github 并使用 JSDelivr 之类的服务。它可以节省大量时间和压力。

            【讨论】:

              【解决方案8】:

              React 适用于动态 DOM。但是为了通过浏览器渲染它,你的 Web 服务器应该发送一个静态索引页面,其中 React 将作为另一个 script 标签包含在内。

              因此,请查看您的 index.html 页面,您可以在 public 文件夹中找到该页面。例如,您可以在标题部分插入script 标签。

              【讨论】:

                猜你喜欢
                • 2019-02-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-02-15
                • 2020-06-04
                • 2016-09-18
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多