简体   繁体   English

使用Gatsbyjs包含本地JS和CSS文件

[英]Including local JS and CSS files using Gatsbyjs

I am completely new to the gatsbyjs ecosystem, and at the same time I am learning a bit of reactjs .我是gatsbyjs生态系统的新手,同时我正在学习一些reactjs I recently bought an html template and was trying to use it as a UI in a gatsbyjs application.我最近买了一个 html 模板,并试图将其用作gatsbyjs应用程序中的 UI。 The template has many css and js, whether proprietary or costumized, which implies that there are no plugins in gatsbyjs to replace them.模板有很多css和js,无论是私有的还是定制的,这意味着gatsbyjs中没有插件可以替代它们。 That said, the only option I have left is to add them directly as a link and scripts tags in the gatsbyjs application.也就是说,我剩下的唯一选择是将它们直接添加为gatsbyjs应用程序中的链接脚本标签。 Following some of the tutorials I saw that they suggest importing these files, the issue is that these files are not webpack friendly, resulting in multiple errors and the application does not compile.按照我看到的一些教程,他们建议导入这些文件,问题是这些文件不是webpack友好的,导致多个错误并且应用程序无法编译。 Following this help page Gatsby Server Rendering APIs get to this code in the gatsby-ssr.js file:按照此帮助页面, Gatsby 服务器渲染 API会在gatsby-ssr.js文件中找到此代码:

const React = require("react")
exports.onRenderBody = ({ setBodyAttributes, setPostBodyComponents }) => {
  setBodyAttributes({
    "data-spy":"scroll",
    "data-offset":"73",
    "data-target":"#navbar-demos"
  })
  setPostBodyComponents([
    <script
      key="1"
      type="text/javascript"
      src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.slim.js"
    />,
    <script
      key="2"
      type="text/javascript"
      src="./src/revolution/js/extensions/revolution.extension.actions.min.js"
    />,
  ])
}

the problem is this file revolution.extension.actions.min.js is never exposed to the browser.问题是这个文件revolution.extension.actions.min.js永远不会暴露给浏览器。 when you open the Developer Tools appears to be there, but it definitely isn't:当您打开开发人员工具时,它似乎在那里,但它绝对不是:

在此处输入图像描述

在此处输入图像描述

What do I have to do to render those.js files correctly and the browser can see them?我需要做什么才能正确呈现 those.js 文件并且浏览器可以看到它们? That also applies for.css files这也适用于 .css 文件

After a more extensive search, I found a couple of articles with a solution.经过更广泛的搜索,我找到了几篇提供解决方案的文章。 This was the first approach:这是第一种方法:

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

const IndexPage = () => (
  <div>
    <Helmet>
        <script src={withPrefix('revolution/js/extensions/revolution.extension.actions.min.js')} type="text/javascript" />
    </Helmet>

  </div>
)
export default IndexPage

This is the second approach using the gatsby-ssr.js file:这是使用gatsby-ssr.js文件的第二种方法:

const React = require("react")

exports.onRenderBody = ({setPostBodyComponents}) => {
          setPostBodyComponents([
            <script key="1" src={'js/plugins/plugins.js'} type="text/javascript" />,
            <script type="text/javascript" src={"js/beauty.custom.js"}/>
          ]);
  };

this way the scripts tags will be added at the end of the body instead of the head这样脚本标签将被添加到body的末尾而不是head

I think the second one is the best one, but have to take in count that every time you change something in the gatsby-ssr.js file have to stop the gatsby develop and re-run it.我认为第二个是最好的,但必须考虑到每次更改gatsby-ssr.js文件中的gatsby-ssr.js都必须停止gatsby develop并重新运行它。

In the first case using react-helmet will hot-reload.在第一种情况下,使用react-helmet会热重载。

NOTE : In both approaches, files have to be in the static folder注意:在这两种方法中,文件都必须在static文件夹中

Here are the links to where I found this approach:以下是我找到此方法的链接:

How to include local javascript on a Gatsby page? 如何在 Gatsby 页面上包含本地 javascript?

How do you insert an external script using gatsby-browser?如何使用 gatsby-browser 插入外部脚本?

@ddieppa solution might not work if you demand your script must only be executed after the component/page is completely loaded , because:如果您要求脚本只能在组件/页面完全加载后执行, @ddieppa 解决方案可能不起作用,因为:

  • React-Helmet always put your tag on top of the page inside the <head> tag, no matter where you put it. React-Helmet总是将你的标签放在页面顶部的<head>标签内,无论你把它放在哪里。
  • Gatsby Server Rendering API - setPostBodyComponents via ( gatsby-ssr.jsx/tsx ) will append your <script> tag at the end of the body nicely, but watch out because your script file might actually executed before React completely finishes rendering your component. Gatsby 服务器渲染setPostBodyComponents - 通过 ( gatsby-ssr.jsx/tsx ) setPostBodyComponents 将 append 你的<script>标签很好地放在主体的末尾,但要小心,因为你的脚本文件可能会在 React 完全完成渲染你的组件之前实际执行。 If your js file is referring to any specific object in the component, you might end up seeing a bunch of null pointer exception, undefined exception.如果您的 js 文件引用组件中的任何特定 object,您可能最终会看到一堆 null 指针异常,未定义异常。

So if you want to make sure your script file get executed/loaded right after the component is completely rendered, you might need to use either React useEffect hook (if your React component is a functional component) orReact componentDidMount (if your component is a class component)因此,如果你想确保你的脚本文件在组件完全呈现后立即执行/加载,你可能需要使用React useEffect hook (如果你的 React 组件是功能组件)或React componentDidMount (如果你的组件是class 分量)

The idea will be simple, after the component is fully rendered, we will append a <script> at the bottom of it.这个想法很简单,在组件完全渲染后,我们将 append 一个<script>放在它的底部。

With useEffect hook (for functional component)使用 useEffect 钩子(用于功能组件)

(It's the same for componentDidMount) (对于 componentDidMount 也是一样的)

import React, { useEffect } from 'react'

const MyComponent = () => {

    useEffect(() => {
        const mainJsTag = document.createElement('script')
        // given the js/main.js file is put in the static folder
        mainJsTag.src = 'assets/js/main.js'
        document.body.appendChild(mainJsTag)
        console.log('Component Rendered!')
    });

    return (
        <main>
          <text>Pretty much the component's body here...</text>
        </main>
    )
}

export default MyComponent

(The snippet above assuming that you put your script file under the Gatsby static folder, see Gatsby - Using the Static Folder in case you don't know about this concept in Gatsby) (上面的代码片段假设您将脚本文件放在 Gatsby static文件夹下,请参阅Gatsby - 使用 Static 文件夹以防您不知道 Gatsby 中的这个概念)

You can put a bunch of console.log in both of your script file and in the useEffect/componentDidMount functions to confirm which one get executed first.您可以在脚本文件和 useEffect/componentDidMount 函数中放置一堆console.log以确认先执行哪个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM