【问题标题】:Nextjs with Material UI and custom global stylesheetNextjs 与 Material UI 和自定义全局样式表
【发布时间】:2020-08-23 10:36:46
【问题描述】:

我使用 Nextjs 9.3 和 export 来生成一个静态站点。 Material UI 是根据这个参考实现 (https://github.com/mui-org/material-ui/tree/master/examples/nextjs) 设置的。

除了 Material UI,我还有一个全局样式表 style.css,根据文档 (https://nextjs.org/docs/basic-features/built-in-css-support),它是 imported 到 _app.js。

但是在运行 export 之后,index.html 不包含来自 styles.css 的任何 CSS,仅包含 Material UI 的 CSS。 styles.css 仅作为普通样式表加载,而不是内联。有什么方法可以将styles.css 注入index.html 以避免FOUC?

编辑 @Dekel 要求的文件夹结构的相关部分:

├── pages
│   ├── _app.js
│   ├── _document.js
│   ├── index.js
├── public
└── src
    ├── components
    └── styles.css

【问题讨论】:

标签: material-ui next.js server-side-rendering


【解决方案1】:

如果您正在寻找的是以这种方式在 index.html 中连接和缩小您的 css 文件:

案例 0

// index.html
...
<head>
  <style>
    <!-- your css concat + minified here -->
  </style>
</head>
...

不是这样

案例一

// index.html
<head>
  <link rel="stylesheet" href="path/to/bundle.min.css"/>
</head>

我认为您无法使用 NextJS 开箱即用的解决方案“内置 CSS 支持全局样式表”来实现这一点。

阅读 9.2 版本 (https://nextjs.org/blog/next-9-2#built-in-css-support-for-global-stylesheets) 的文档,它说:

In production, all CSS files will be automatically concatenated into a single minified .css file. This CSS file will be loaded via a &lt;link&gt; tag and automatically injected into the default HTML markup Next.js generates.

因此,在我看来,您无法使用该解决方案实现Case 0。


我遇到了与FOUC 相同的问题,这就是我使用 Next 管理我的 SSR 解决方案的方式:

  1. 连接和缩小我需要的文件的辅助函数称为prepareInPageCss.js,它保存一个js模块,该模块返回一个带有捆绑css的字符串,如下所示:
const minify = require('@node-minify/core');
const cleanCSS = require('@node-minify/clean-css');
const fs = require('fs');
const bootstrapOutPutPathName = './static/css/_tempBootstrap.min.js';
const commonOutPutPathName = './static/css/_tempCommon.min.js';
const outputnameCss = './static/css/InPageCssBundle.css';

(async () => {
 try {
   await minify({
     compressor: cleanCSS,
     input: './static/css/bootstrap.min.css',
     output: bootstrapOutPutPathName,
     options: {
       keepSpecialComments: '0'
     }
   });

   await minify({
     compressor: cleanCSS,
     input: './static/css/common.css',
     output: commonOutPutPathName,
     options: {
       keepSpecialComments: '0'
     }
   });

   let bootstrapTempCss = fs.readFileSync(bootstrapOutPutPathName, "utf-8");
   let commonTempCss = fs.readFileSync(commonOutPutPathName, "utf-8");

   fs.writeFileSync(outputnameCss, bootstrapTempCss + commonTempCss);
   fs.writeFileSync(outputname, "const bundledCss=String.raw`" + bootstrapTempCss + commonTempCss + "`; export default bundledCss;");
 } catch (e) {
   console.log(e);
 }
})()
  1. 在您的项目文件中,我以这种方式完成的head 结构在哪里:
   import commonCss from '../static/css/InPageCssBundle.js';
   const isDev = ENV === 'development';

   ...
    <title>{title}</title>
    <meta name='description' content={description}/>
    <meta charSet="utf-8"/>
    {isDev ? <>
       <link rel="stylesheet" href="/static/css/bootstrap.min.css"/>
       <link rel="stylesheet" href="/static/css/common.css"/>
     </> :
     <style>
       {commonCss}
     </style>
   }
   ...

每次创建新版本时,我都会运行 node path/to/file/prepareInPageCss.js。

现在,我不能 100% 确定这是唯一的方法(我在 Next 版本为 9.0 时实现了这个),我还没有尝试静态导出,但希望我至少给了你一个备用解决方案。

干杯

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多