Next.js - 引入 CSS 文件无效

38

我正在使用react、redux和next.js创建一个项目,并希望在js中导入CSS文件。

我按照next.js/#cssnext-css的说明操作,但发现CSS样式不起作用。

我的代码如下:

pages/index.js:

import React from 'react'
import "../style.css"

class Index extends React.Component {
    render() {
        return (
            <div className="example">Hello World!</div>
        );
    }
}

export default Index

next.config.js:

const withCSS = require('@zeit/next-css')
module.exports = withCSS()

style.css:

.example {
    font-size: 50px;
    color: blue;
}

package.json:

{
    "name": "my-app",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@zeit/next-css": "^0.1.5",
        "next": "^6.0.0",
        "react": "^16.3.2",
        "react-dom": "^16.3.2",
        "react-redux": "^5.0.7",
        "react-scripts": "1.1.4",
        "redux": "^4.0.0",
        "redux-devtools": "^3.4.1"
    },
    "scripts": {
        "test": "react-scripts test --env=jsdom",
        "eject": "react-scripts eject",
        "dev": "next",
        "build": "next build",
        "start": "next start"
    }
}

问题:

1. 在Chrome中出现了“未捕获的SyntaxError”,但似乎不影响页面的渲染。但我仍然想知道原因和解决方案。index.js在Chrome中的错误如下图所示:

2. 如Chrome所示,没有“example”类,这意味着style.css文件未加载。我是否遗漏了什么?在chrome中没有CSS文件。

提前致谢。


嗨,@ArgentBarbie,你在pages目录中创建了_document.js文件吗?如果有的话,你能把代码粘贴在这里吗? - mtl
@mtl 抱歉,我没有创建 _document.js。它是必要的吗?文件里应该包含什么内容? - ArgenBarbie
嗨@ArgentBarbie,以后请尽量一次只问一个问题:)。如果您有两个问题,请分别提出两个问题。这样可以更容易地回答两个不同的人可能只有一个问题的答案。而且它使单独的问题可搜索,帮助其他遇到相同问题的人。祝您在Next.js中好运! - mtl
9个回答

28

编辑2:自Next.js > 10起,您可以将全局CSS文件导入_app.js,并且您可以在组件中使用CSS模块。更多信息请参见Next.js文档


编辑:自Next.js 7起,支持导入.css文件的所有操作都是在您的next.config.js中注册withCSS插件。首先按照插件作为开发依赖项进行安装:

npm install --save-dev @zeit/next-css

然后在你的项目根目录下创建 next.config.js 文件,并将以下内容添加到其中:

// next.config.js
const withCSS = require('@zeit/next-css')
module.exports = withCSS({/* my next config */})

您可以通过创建一个简单的页面并导入一些 CSS 来测试这是否有效。首先创建一个 CSS 文件:

// ./index.css
div {
    color: tomato;
}

然后创建一个带有 index.js 文件的 pages 文件夹。接下来您可以在组件中执行以下操作:

// ./pages/index.js
import "../index.css"
export default () => <div>Welcome to next.js 7!</div>

你还可以使用几行配置与CSS模块一起使用。想要深入了解,请查看nextjs.org/docs/#css的文档。


已过时: Next.js < 7:

你还需要在pages文件夹中创建一个_document.js文件并链接到编译后的CSS文件。请尝试以下内容:

// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document'

export default class MyDocument extends Document {
  render() {
    return (
      <html>
        <Head>
          <link rel="stylesheet" href="/_next/static/style.css" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

样式表被编译为.next/static/style.css,这意味着CSS文件是从/_next/static/style.css提供的,这是上面代码中link标记中href属性的值。

至于第一个问题,可能是Chrome不理解导入语法。尝试在chrome:flags中启用实验性Web平台标志,看看是否解决了问题。


仅仅导入.css文件就会影响开发模式下next/router的行为。一些函数,如Router.pushreplace会挂起并且无法正常工作。 - Pavindu
2
这不就是他代码里的内容吗?我找不到任何区别。我按照相同的步骤操作,但是它对我不起作用。 - Jonas
@Jonas 我同意,他确实有这个问题。我也有同样的问题,它也没有起作用。 - Master117

12

对于任何来到这里的人,新的Next JS支持CSS开箱即用。但是有个问题是,对于模块(组件),它们必须以组件名称命名。因此,如果您在components目录中有一个标题,则必须将其命名为header.module.css

内置的CSS模块支持组件级样式


谢谢伙计!正是我所需要的。 - Ofir Hadad
对我来说,如果CSS模块文件名与组件名称不匹配也可以正常工作。所以我可以在两个不同的组件中使用同一个模块 :) - Diego Frehner

4

对于版本大于等于9.3的Next.js,全局CSS写在“styles/globals.css”中,您可以将其导入到_app.js中。

    import "../styles/globals.css";

对于每个组件,您可以编写自己的 CSS 并将其导入到组件中。要注意命名:文件名.module.css

假设您有 "product.js" 组件和 "product.module.css" 文件。您想将 "product.css" 中的 CSS 加载到 "product.js" 中

import classes from "./product.module.css" // assuming it's in the same directory

你需要把所有的类名放到product.module.css中。假设你在product.module.css中有一个.main-product。在product.js中,假设你有一个要样式化的div
<div className={classes.main-product}  > </div>

使用 CSS 模块功能,您可以在其他组件中使用相同的 className,并且不会发生冲突。因为当 Next.js 编译时,它将哈希化类名的名称,使用它的模块。因此,来自不同模块的相同类名的哈希值将是相同的。


3

{name}.css添加到src/static/styles/中。

然后在src/pages/_document.js中修改Head,包含以下link

<Head>
    <link href="/static/styles/{name}.css" rel="stylesheet">
</Head>

1

全局CSS必须在您的自定义中 为什么会出现这个错误 尝试从除了pages/_app.js以外的文件导入全局CSS。

由于其副作用和排序问题,全局CSS不能在除Custom之外的文件中使用。

修复方法 将所有全局CSS导入重定位到您的pages/_app.js文件中。

或者,更新您的组件以使用本地CSS(组件级别CSS)通过CSS模块。这是首选方法。

示例:

// pages/_app.js
import '../styles.css'

export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}

1

正如Zeit所说:

  1. 在与/pages文件夹同级别的位置创建一个/static文件夹。
  2. 在该文件夹中放置您的.css文件。
  3. 在页面组件中导入Head并将标签添加到您的CSS中。

import Head from 'next/head'

function IndexPage() {
  return (
    <div>
      <Head>
        <title>My page title</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <p>Hello world!</p>
    </div>
  )
}

export default IndexPage

就是这样,这样做Next.js应该会在页面头部呈现链接标签,浏览器将下载CSS并应用它。

感谢Github上的Sergiodxa提供了这个清晰的解决方案。


1

您需要创建自定义的_document.js文件。

当添加CSS时,自定义文档将如下所示:

import React from "react";

import Document, { Head, Main, NextScript } from "next/document";

export default class MyDocument extends Document {

  render() {
    const { buildManifest } = this.props;
    const { css } = buildManifest;
    return (
      <html lang="fa" dir="rtl">
        <Head>
          {css.map(file => (
            <link rel="stylesheet" href={`/_next/${file}`} key={file} />
          ))}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}


1
如果您使用next.js,请执行以下操作。
在项目根目录下创建next.config.js
const withCSS = require('@zeit/next-css');

function HACK_removeMinimizeOptionFromCssLoaders(config) {
    console.warn(
        'HACK: Removing `minimize` option from `css-loader` entries in Webpack config',
    );
    config.module.rules.forEach(rule => {
        if (Array.isArray(rule.use)) {
            rule.use.forEach(u => {
                if (u.loader === 'css-loader' && u.options) {
                    delete u.options.minimize;
                }
            });
        }
    });
}

module.exports = withCSS({
    webpack(config) {
        HACK_removeMinimizeOptionFromCssLoaders(config);
        return config;
    },
});

请勿忘记重启服务器。

0

如果您的应用程序直接使用Web 5包,请将其设置为false。

module.exports = {
  // Webpack 5 is enabled by default
  // You can still use webpack 4 while upgrading to the latest version of 
  // Next.js by adding the "webpack5: false" flag
  webpack5: false,
}

你可以使用webpack 4。

yarn add webpack@webpack-4


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接