[英]Including local JS and CSS files using Gatsbyjs
我是gatsbyjs生态系统的新手,同时我正在学习一些reactjs 。 我最近买了一个 html 模板,并试图将其用作gatsbyjs应用程序中的 UI。 模板有很多css和js,无论是私有的还是定制的,这意味着gatsbyjs中没有插件可以替代它们。 也就是说,我剩下的唯一选择是将它们直接添加为gatsbyjs应用程序中的链接和脚本标签。 按照我看到的一些教程,他们建议导入这些文件,问题是这些文件不是webpack友好的,导致多个错误并且应用程序无法编译。 按照此帮助页面, 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"
/>,
])
}
问题是这个文件revolution.extension.actions.min.js
永远不会暴露给浏览器。 当您打开开发人员工具时,它似乎在那里,但它绝对不是:
我需要做什么才能正确呈现 those.js 文件并且浏览器可以看到它们? 这也适用于 .css 文件
经过更广泛的搜索,我找到了几篇提供解决方案的文章。 这是第一种方法:
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
这是使用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"}/>
]);
};
这样脚本标签将被添加到body
的末尾而不是head
我认为第二个是最好的,但必须考虑到每次更改gatsby-ssr.js
文件中的gatsby-ssr.js
都必须停止gatsby develop
并重新运行它。
在第一种情况下,使用react-helmet
会热重载。
注意:在这两种方法中,文件都必须在static
文件夹中
以下是我找到此方法的链接:
如果您要求脚本只能在组件/页面完全加载后执行, @ddieppa 解决方案可能不起作用,因为:
<head>
标签内,无论你把它放在哪里。setPostBodyComponents
- 通过 ( gatsby-ssr.jsx/tsx
) setPostBodyComponents 将 append 你的<script>
标签很好地放在主体的末尾,但要小心,因为你的脚本文件可能会在 React 完全完成渲染你的组件之前实际执行。 如果您的 js 文件引用组件中的任何特定 object,您可能最终会看到一堆 null 指针异常,未定义异常。因此,如果你想确保你的脚本文件在组件完全呈现后立即执行/加载,你可能需要使用React useEffect hook (如果你的 React 组件是功能组件)或React componentDidMount (如果你的组件是class 分量)
这个想法很简单,在组件完全渲染后,我们将 append 一个<script>
放在它的底部。
(对于 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
(上面的代码片段假设您将脚本文件放在 Gatsby static
文件夹下,请参阅Gatsby - 使用 Static 文件夹以防您不知道 Gatsby 中的这个概念)
您可以在脚本文件和 useEffect/componentDidMount 函数中放置一堆console.log
以确认先执行哪个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.