Gatsby 有没有办法将内联样式组件 CSS 导出到 CSS 文件中?

Posted

技术标签:

【中文标题】Gatsby 有没有办法将内联样式组件 CSS 导出到 CSS 文件中?【英文标题】:Is there a way in Gatsby to export inlined styled components CSS into a CSS file? 【发布时间】:2021-10-20 21:06:33 【问题描述】:

我已经完成了我的第一个 Gatsby 应用程序,该应用程序将很快投入生产。这是链接:https://majiid-landing-page.vercel.app/

我在整个应用程序中都使用了样式化组件,我通常采用SCSSBEM 方法,但我想尝试这种CSS in JS 方法。

问题是页面首先在几分之一秒内显示为无样式,然后解析样式,就像注入了JS 一样,而样式实际上在html 中,因为Gatsby 使用s-s-r

这是正常行为吗?

我不确定如何重现整个内容,因为回购是私有的,无论如何我使用GlobalStyles 以及每个组件中的特定样式。

这里有一些sn-ps:

全局样式

import React from "react";

import Abstracts from "./abstracts/abstracts";
import Base from "./base/base";
import Utils from "./utils/utils";

const GlobalStyles = () => 
  return (
    <>
      <Abstracts />
      <Base />
      <Utils />
    </>
  );
;

export default GlobalStyles;

全局样式创建示例:

import  createGlobalStyle  from "styled-components";

export default createGlobalStyle`
  :root 
      // COLORS
    --body-background: #ffffff;
  
`;

盖茨比 s-s-r

// gatsby-s-s-r.js
const React = require("react");
require("./src/scss/index.scss");
const GlobalStyles = require("./src/styles/global-styles").default;
const Layout = require("./src/layout/Layout").default;

exports.wrapRootElement = ( element ) => 
  return (
    <>
      <GlobalStyles />
      <Layout>element</Layout>
    </>
  );
;

gatsby-browser.js

const React = require("react");
require("./src/scss/index.scss");
const GlobalStyles = require("./src/styles/global-styles").default;
const Layout = require("./src/layout/Layout").default;

exports.wrapRootElement = ( element ) => 
  console.log("Running this");
  return (
    <>
      <GlobalStyles />
      <Layout>element</Layout>
    </>
  );
;

盖茨比配置(摘录):

plugins: [
    "gatsby-plugin-styled-components",
...

package.json 依赖项

"dependencies": 
    "@vimeo/player": "^2.16.0",
    "babel-plugin-styled-components": "^1.13.2",
    "bootstrap": "^5.1.0",
    "gatsby": "^3.11.1",
    "gatsby-plugin-image": "^1.11.0",
    "gatsby-plugin-react-helmet": "^4.11.0",
    "gatsby-plugin-sass": "^4.11.0",
    "gatsby-plugin-sharp": "^3.11.0",
    "gatsby-plugin-sitemap": "^4.7.0",
    "gatsby-plugin-styled-components": "^4.11.0",
    "gatsby-plugin-webfonts": "^2.1.1",
    "gatsby-source-contentful": "^5.11.1",
    "gatsby-source-filesystem": "^3.11.0",
    "gatsby-transformer-sharp": "^3.11.0",
    "node-sass": "^6.0.1",
    "normalize.css": "^8.0.1",
    "polished": "^4.1.3",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-helmet": "^6.1.0",
    "react-icons": "^4.2.0",
    "react-responsive": "^9.0.0-beta.3",
    "styled-components": "^5.3.0"
  

【问题讨论】:

【参考方案1】:

它叫做 FOUC(Flash Of Unstyled Content),不,它不是“正常”的行为,但使用 styled-components 很常见。

如果没有更多详细信息,就无法猜测可能出现的问题或配置错误,但通常通过以下方式修复:

安装所有必需的plugins:

npm install gatsby-plugin-styled-components styled-components babel-plugin-styled-components

在您的gatsby-config.js 中添加正确的配置:


   resolve: `gatsby-plugin-styled-components`,
   options: 
      // Add any options here
   ,
,

GlobalStyles 包装在Layout 组件中。比如:

import React from "react"
import  createGlobalStyle  from "styled-components"

const GlobalStyle = createGlobalStyle`
   body 
     color: $props => (props.theme === "purple" ? "purple" : "white");
   
`
export default function Layout( children ) 
   return (
     <>
       <GlobalStyle theme="purple" />
       children
     </>
   )

https://www.gatsbyjs.com/docs/how-to/styling/styled-components/的其他实现细节

除了最后一点,您还可以在gatsby-s-s-r.jsgatsby-browser.js 中使用wrapPageElement API(这两个文件,这很重要)。

【讨论】:

非常感谢!我已更新问题以提高清晰度! 尝试第三种情况(布局),看看你是否获得了任何性能。另外,检查github.com/gatsbyjs/gatsby/issues/20594#issuecomment-675106531 谢谢!我尝试在布局组件中移动全局样式声明,但没有帮助。我尝试在本地提供静态文件,它有同样的问题,所以我不认为 N​​etlify 是问题(正如问题中的人所引用的那样)。你认为我应该使用一些 webpack 插件将内联 css 提取到一个单独的文件中吗? 不,这应该由插件本身管理。 GitHub 线程建议将其包装在一个主题中。在其他情况下,是因为插件重复...仔细检查所有内容以确保,90% 的情况是某个地方的配置错误。 我找到了解决办法:youtube.com/watch?v=G_dVwrhvkBI【参考方案2】:

这已经做到了: https://www.youtube.com/watch?v=G_dVwrhvkBI

基本上,全局样式必须在 wrapPageElement 挂钩中应用,而不是在 wrapRootElement 挂钩中。

如果其他人搜索 SO 来处理此问题,我会留在这里。

【讨论】:

以上是关于Gatsby 有没有办法将内联样式组件 CSS 导出到 CSS 文件中?的主要内容,如果未能解决你的问题,请参考以下文章

在 React 组件中使用 css/scss 变量作为内联样式

用于样式化组件和 Gatsby / Safari 支持的 Gap Polyfill

Gatsby Styled Components , CSS 显示在 <head>

使用内联 CSS 为组件设计样式 - Ionic2、AngularJS

如何在 reactjs 中使用伪元素作为内联样式? [复制]

NextJS Image 组件没有响应我的内联 CSS