Next.js 全局 CSS 不能从自定义 <App> 以外的文件导入

IT技术 css reactjs import sass next.js
2021-04-03 09:38:08

我的 React 应用程序运行良好,也使用全局 CSS。

我跑了npm i next-images,添加了一张图片,编辑了next.config.js, ran npm run dev,现在我收到了这条消息

Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to pages/_app.js.
Read more: https://err.sh/next.js/css-global

我已经检查了文档,但我发现这些说明有点令人困惑,因为我是 React 的新手。

另外,为什么现在会发生这个错误?你认为这与 npm install 有什么关系吗?

我试图删除我与他们的代码一起添加的新文件,但这并不能解决问题。我也尝试了阅读更多:建议的内容。

我的最高层组件。

import Navbar from './Navbar';
import Head from 'next/head';
import '../global-styles/main.scss';

const Layout = (props) => (
  <div>
    <Head>
      <title>Bitcoin Watcher</title>
    </Head>
    <Navbar />
    <div className="marginsContainer">
      {props.children}
    </div>
  </div>
);

export default Layout;

我的下一个.config.js

// next.config.js
  const withSass = require('@zeit/next-sass')
  module.exports = withSass({
  cssModules: true
})

我的 main.scss 文件

@import './fonts.scss';
@import './variables.scss';
@import './global.scss';

我的 global.scss

body {
  margin: 0;
}
:global {
  .marginsContainer {
    width: 90%;
    margin: auto;
  }
}

我觉得最奇怪的是这个错误没有改变任何与 CSS 或 Layout.js 相关的东西,而且它以前是有效的?

我已将 main.scss 导入移至 pages/_app.js 页面,但样式仍未通过。这是 _app.js 页面的样子

import '../global-styles/main.scss'

export default function MyApp({ Component, props }) {
  return <Component {...props} />
}
6个回答

使用内置 Next.js CSS 加载器(参见此处)而不是 legacy @zeit/next-sass

  1. 更换@zeit/next-sass用包sass
  2. 删除next.config.js或者不要更改其中的 CSS 加载。
  3. 按照错误消息中的建议移动全局 CSS。

由于 Next.js 9.2 全局 CSS 必须在自定义<App>组件中导入

// pages/_app.js

import '../global-styles/main.scss'

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

要仅向特定组件或页面添加样式,您可以使用CSS module的内置支持(见这里

例如,如果您有一个组件,Button.js您可以创建一个 Sass 文件button.module.scss并将其包含在组件中。

这绝对有所作为。全局 css 现在在 _app.js 中工作。最后一件尚未工作的事情,以前工作过,是: :global { .marginsContainer { width: 90%; 保证金:自动;} }
2021-05-22 09:38:08
嘿,我之前创建了 main.scss 并将其移动到该文件,但它不起作用。我又试了一次,但仍然没有应用它。我在那里有以下代码: import '../global-styles/main.scss' export default function MyApp({ Layout, props }) { return <Layout {...props} /> }
2021-06-08 09:38:08
@IndustryDesigns,尝试使用node-sass而不是@zeit/next-sass,我只是对其进行了测试并更新了答案。如果您在命令行或浏览器的控制台中有任何特定错误,请告诉我。
2021-06-11 09:38:08
我来到这个答案是因为我试图在组件中使用 scss。显然现在我需要将我的 scss 文件与 components/my-component/ 文件夹分开并将其放在页面中?我糊涂了..
2021-06-19 09:38:08
@AntonDozortsev,从 Next.js 9.2 开始(参见Next.js 9.2 博客文章)。
2021-06-19 09:38:08

你可以用你自己的替换那些过于自以为是和坦率地过度设计的 NextJs CSS 加载器。这是一个简单的全局 css:

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  reactStrictMode: true,
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Find and remove NextJS css rules.
    const cssRulesIdx = config.module.rules.findIndex(r => r.oneOf)
    if (cssRulesIdx === -1) {
      throw new Error('Could not find NextJS CSS rule to overwrite.')
    }
    config.module.rules.splice(cssRulesIdx, 1)

    // Add a simpler rule for global css anywhere.
    config.plugins.push(
      new MiniCssExtractPlugin({
        experimentalUseImportModule: true,
        filename: 'static/css/[contenthash].css',
        chunkFilename: 'static/css/[contenthash].css',
      })
    )

    config.module.rules.push({
      test: /\.css$/i,
      use: !isServer ? ['style-loader', 'css-loader'] : [MiniCssExtractPlugin.loader, 'css-loader'],
    })
    return config
  },
}

对我来说,问题是因为我在我的next.config.js文件中使用了两个 module.exports

const withPlugins = require('next-compose-plugins')
const sass = require('@zeit/next-sass')
const css = require('@zeit/next-css')

const nextConfig = {
    webpack: function(config){
    config.module.rules.push({
        test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
        use: {
        loader: 'url-loader',
            options: {
            limit: 100000,
            name: '[name].[ext]'
        }}
    })
    return config
    }
}

module.exports = withPlugins([
    [css],
    [sass, {
        cssModules: true
    }]
], nextConfig)

module.exports = {
    env: {
        MONGO_URI = 'your uri'
    }
}

. 1我修改了它以像这样更改导出module。

const nextConfig = {
    webpack: function(config){
    config.module.rules.push({
        test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
        use: {
        loader: 'url-loader',
            options: {
            limit: 100000,
            name: '[name].[ext]'
        }}
    })
    return config
    },
    env: {
        MONGO_URI: "your uri"
    }
}

2然后我删除了第二个 module.exports

请阅读 common.js module如何工作。第二个module.exports覆盖第一个。你的第一个 NextJS 配置实际上没有得到应用。
2021-06-10 09:38:08

你不需要在里面做任何事情next.config.js

假设您正在使用像 Bootstrap 这样的全局 css,这意味着它包含的 css 旨在应用于您的整个应用程序及其内部的所有不同页面。

全局 css 文件必须以一种非常特殊的方式连接到 NextJS。

因此,pages/您需要目录中创建_app.js.

将文件命名为_app.js.

然后在该文件的顶部,您将按以下方式导入 Bootstrap css:

import 'bootstrap/dist/css/bootstrap.css';

然后,您将添加以下内容:

export default ({ Component, pageProps }) => {
  return <Component {...pageProps} />;
};

那么这段代码中发生了什么?

好吧,在幕后,每当您尝试使用 NextJS 导航到某个不同的页面时,NextJS 都会从您pages/目录中的不同文件之一导入您的组件

NextJS 不只是获取您的组件并将其显示在屏幕上。

相反,它将它包装在自己的自定义默认组件中,并且在 NextJS 内部称为应用程序。

您通过定义_app.js来定义您自己的自定义应用程序组件。

因此,每当您尝试访问浏览器中的路由或根路由时,NextJS 都会导入该给定组件并将其AppComponent作为Componentprop传递给

因此Component,您在pages/目录中拥有的任何组件都相等然后pageProps将是您打算传递给pages/.

长话短说,这个东西就像你试图在屏幕上显示的组件周围的薄包装。

你为什么要定义这个?

好吧,如果你想在项目中包含一些全局 css,例如 Bootstrap 是一个全局 css,你只能将全局 css 导入到_app.js文件中。

事实证明,如果您尝试访问其他组件或其他页面,NextJS 不会加载甚至解析这些文件。

因此,您可能在其中导入的任何 css 都不会包含在最终的 HTML 文件中。

所以你有一个必须包含在每个页面上的全局 css,它必须被导入到 app 文件中,因为它是唯一保证每次用户访问你的应用程序时加载的文件。

不要忘记,除了在 中导入 css 之外_app.js,您还必须npm install bootstrap在终端中运行 an

您可以在此处阅读更多相关信息:https : //nextjs.org/docs/messages/css-global

Next.js当您的文件module命名时停止抱怨,例如,更改import '../global-styles/main.scss';import '../global-styles/main.module.scss';将修复警告,并且您可以global-stylescomponent.

不需要额外的依赖项/配置next.config.js