Next.js: 使用外部 css 和 scss 文件

创建于 2017-10-19  ·  38评论  ·  资料来源: vercel/next.js

我知道这是一个多余的问题,但我故意打开了这个问题。 我花了三天时间设置 next.js 样板(使用 redux、redux-saga 等),两天时间我一直在设置加载外部 css 和 scss 文件。 我已经检查了with-global-stylesheetwith-scoped-stylesheet-and-postcss示例,但它们中的每一个都有在先前问题中提到的主要问题。 我已经看到太多开放和封闭的问题都在用 hacks 解决这个问题……我认为最好不要让问题去寻找最佳解决方案,而是使用当前可用的解决方案来解决它,直到找到更好的解决方案。 因为现在很多人都有这个问题,希望现在就解决!

最有用的评论

我还想指出,我个人不喜欢人们在这个问题上的语气。
我完全理解你想导入 css。 我们非常清楚这一要求。 这就是为什么我花了一周的时间研究最好的解决方案👍
很快就会有更多的介绍。 到那时,请大家节日快乐🎅😄

所有38条评论

我同意,只有 styled-jsx 有干净的(包括热重载)支持,这就是阻止我将 Next.js 用于任何事情的原因,但当我需要一些快速原型设计时。

我认为 CSS 的 CSS Modules 范围问题的解决方案是一个更清晰的解决方案,加上 CSS Modules 仍然可以将类传递给子组件(尝试在使用babel-plugin-inline-react-svg导入的 SVG 上放置一个非全局类带有样式的 jsx)。

那和我更喜欢标准化.css文件以尽可能防止框架锁定,并在生产中使用外部 CSS 文件进行缓存(如果您不幸还是要支持IE8)。

海量 +1
使用 next.js 几乎不可能实现像外部 css/scss 这样简单的事情,这让我感到非常沮丧,这使得它对我 90% 的应用程序毫无用处。

我正在使用引导程序,我需要一个配置,其中将有一个全局引导程序 css 导入,并添加外部范围的 css。

虽然我们设法使用样式化 jsx 1(用于处理编译的 webpack)使用外部手写笔,但由于引入了处理单独 css 文件的中断更改,因此很难在样式化 jsx 2 上弄清楚。
目前的做法:

import ComponentStyles from './footer.styl';
...
      <style jsx>
        {ComponentStyles}
      </style>

很高兴看到https://github.com/zeit/next.js/tree/master/examples/with-styled-jsx-scss使用外部 scss 文件。

我们在设置环境时经历了同样的磨难。
最终我们解决了一个带有 scss+post css 和丢失网格的全局样式表。
热重载有效,所以虽然它不是一个理想的解决方案(由于全局样式表被一次性加载),但它是一个不错的折衷方案。

依赖关系

"autoprefixer": "^7.1.6",
"babel-plugin-module-resolver": "^2.7.1",
"babel-plugin-wrap-in-js": "^1.1.1",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"pixrem": "^4.0.1",
"postcss-easy-import": "^3.0.0",
"postcss-loader": "^2.0.8"

package.json

  ...
  "postcss": {
    "plugins": {
      "lost": {},
      "postcss-easy-import": {
        "prefix": "_"
      },
      "autoprefixer": {},
      "pixrem": {}
    }
  }
  ...

next.config.js

webpack: (config, { dev }) => {
    config.module.rules.push(
      {
        test: /\.(css|scss)/,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]'
        }
      }
    ,
      {
        test: /\.css$/,
        use: ['babel-loader', 'raw-loader', 'postcss-loader']
      }
    ,
      {
        test: /\.s(a|c)ss$/,
        use: ['babel-loader', 'raw-loader', 'postcss-loader',
          { loader: 'sass-loader',
            options: {
              includePaths: ['styles', 'node_modules']
                .map((d) => path.join(__dirname, d))
                .map((g) => glob.sync(g))
                .reduce((a, c) => a.concat(c), [])
            }
          }
        ]
      }
    )
    return config
  }

pages/_document.js

...

import stylesheet from 'styles/main.scss'

   ...
        <Head>
          <style dangerouslySetInnerHTML={{ __html: stylesheet }} />
        </Head>
   ...

然后您可以从 /styles/main.scss 开始管理您的样式
希望能帮助到你

我对这两个样式示例( with-global-stylesheetwith-scoped-stylesheets-and-postcss )中的每一个的问题是,它们都不容易与 Jest 和 Snapshot 测试与快照中的 CSS 集成。 已经有人成功地让 Jest 与 Webpack 一起工作,但那是通过专门跳过 CSS。

运行babel-jest预处理器文件,如this SO answer中所述,似乎是一个糟糕的黑客攻击。

似乎获得外部 CSS 就像with-global-stylesheet你必须使用 Webpack,但要使用 Jest 你不能依赖 Webpack,只能依赖 Babel。

有人在这个空间有想法吗?

我面临着类似的问题。 我是 nextjs 的新手,我无法使示例“with-external-scoped-css”正常工作。 有时,我的 css 已加载,有时未加载。 不知道是不是你说的这个问题。

https://github.com/zeit/next.js/issues/3276

解决了此加载器的外部样式问题https://github.com/coox/styled-jsx-css-loader

@ilionic我已经检查过你的解决方案。 这很棒! 谢谢 :)

@arefaslani我不认为这个问题已经结束。

从 HTTP v1 开始,加载大量 CSS 仍然是一个可怕的性能负担,它显着增加了首次绘制的时间。

适当的外部样式支持将允许导入 CSS 并导致不是内联