[vercel/next.js]需要更新有关外部样式表的示例代码

2024-05-15 824 views
9

在有关外部样式表https://github.com/zeit/next.js/tree/master/examples/with-global-stylesheet的示例代码中,它仍然具有dangerouslySetInnerHTML.根据这个styled-jsx改进` https://github.com/zeit/styled-jsx/pull/148,我们现在可以引用导入的样式表了。

我尝试更改代码并且它有效。

 export default () =>
   <div>
-    <style dangerouslySetInnerHTML={{ __html: stylesheet }} />
+    <style jsx global>{stylesheet}</style>
     <p>ciao</p>
   </div>

看起来dangerouslySetInnerHTML不正确,可能会触发 eslint 错误。如果我的理解是正确的,我会为此提交一个 PR。

回答

1

@giuseppeg 这行不通吗?因为它不是 JS 导出

7

就我而言,使用<style jsx global>样式表会导致以下结果:

模块构建失败:语法错误:标识符stylesheetundefined或者不是外部样式表引用,即它不是来自importorrequire语句

7

@timneutkens 正确,styled-jsx 转换仅导出 js 字符串/模板文字。也许使用像 webpack raw-loader 这样的东西你可以让它工作,但据我所知,只有客户端代码通过 webpack 捆绑,所以它不适用于 SSR。

@eliot-akira 在你的情况下,错误可能是由于你没有导入stylesheet.

0

@giuseppeg 感谢您的确认?

4

@giuseppeg @timneutkens 很抱歉打扰您,但它确实可以在 SSR 中工作。

通过此提交https://github.com/moheng/next.js/commit/7ac857aac79b360b95becd92a3cb3a416ddb76ac,服务器端渲染的 HTML的标签.foo{color:green}中包含.<style id="__jsx-style-14162456061"><head>

我知道 @giuseppeg 的观点是 webpack 配置仅影响浏览器端捆绑。但是,这一更改通过将样式注入内联样式来证明它在 SSR 中有效。

6

据我所知,只有客户端代码通过 webpack 捆绑,因此它不适用于 SSR @moheng,这更像是“我认为......”,我正在寻找某人来确认:)

在示例中,webpack 似乎发挥了魔力,但如果这也适用于 ssr,那就太酷了。您是否也尝试过不使用标签global上的属性style

7

@giuseppeg 如果没有global,内联样式标签将具有类似于.foo[data-jsx-ext~="24162456061"]{color:green}作用域样式的内容。

有了global,内联样式标签就会有.foo{color:green}

1

这真的很酷吗?

8

我会尝试一下,如果这有效的话那就太棒了,因为这意味着人们可以在单独的 .css 文件中编写常规 CSS 并从工具等中受益。

1

好吧@moheng,它确实有效!显然,结合使用babel-plugin-wrap-in-jswebpackraw-loader就可以解决问题。但我还不会在生产中使用它,因为 babel 插件没有测试,并且在进行服务器端渲染时 styled-jsx 将 css 写入style页面中的标签中,这意味着它永远不会被缓存,因此如果你有很多css 和大的外部文件,您的页面大小可能会大大增加。

既然有一个解决方案,尽管我们可能会探索以高性能方式实现这一点的方法 - 也许我们应该在实际.css文件中为 SSR 编写外部编译文件,然后使用常规link标签而不是内联加载它们style

1

@giuseppeg我曾经尝试利用将CSS/SCSS提取到捆绑CSS文件中以在标签ExtractTextPugin中引用,但是通过自定义webpack配置很难(如果不是不可能)做到这一点。我敢打赌,如果 next.js 本身提供这样的功能,事情会更容易。stylehead

3

我认为我们可以在 styled-jsx 中做到这一点,我会考虑一下并写一个提案。 API 可以是<style jsx as="link">

7

注意到styles/index.scss在 commons.js 中捆绑了基本上相同的 css 重复 - 内联到页面和部分app.js 任何提示如何将其从 app.js 中排除? 图像

7

对于常规的全局样式文件,我只需提供它们/static并将它们包含在带有标签的页面中link。您可以使用prebuild脚本将它们复制或构建到static.

8

那么这是捆绑的正常行为吗?就我而言,我有.styl导入和注入的基于外部组件的文件<style jsx>,因此它并不是真正的常规全局样式。

import ComponentStyles from 'components/my-component.styl';
...
<style jsx>{ComponentStyles}</style>
3

@ilionic,当您进行服务器端渲染时,它将内联在页面中;如果您在客户端上加载该页面(通过路由器/ajax),它将内联在捆绑包中

3

好吧,我明白了,这是关于在性能、页面大小和开发体验之间找到折衷方案。目前使用两种方法的组合 - 全局 css 文件,在折叠上方使用link标签以非渲染阻塞方式加载一些主题依赖项(如 bootstrap )。它很少改变并且可缓存。

首屏上的关键 css 是内联的(使用style jsx),并且具有基于组件的样式和热重载也是更好的开发体验。它有效,但正如您所指出的@giuseppeg页面大小开始大幅增长(包括js包)所以直到我们可以从全局css迁移到css-in-js解决方案寻找可能的优化。