【问题标题】:Next.js Global CSS cannot be imported from files other than your Custom <App>Next.js 全局 CSS 不能从自定义 <App> 以外的文件导入
【发布时间】:2020-07-11 11:44:18
【问题描述】:

我的 React 应用运行良好,还使用了全局 CSS。

我运行了npm i next-images,添加了一张图片,编辑了next.config.jsran 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;

我的 next.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} />
}

【问题讨论】:

    标签: css reactjs import sass next.js


    【解决方案1】:

    尝试在你的 scss 文件名中包含“.module”。

    main.scss 更改为main.module.scss

    例子:

    import styles from './todolist-profile-info.module.scss'
    

    【讨论】:

      【解决方案2】:

      Next.js 停止抱怨当您的文件命名为 module 时,例如,将 import '../global-styles/main.scss'; 更改为 import '../global-styles/main.module.scss'; 将修复警告,您可以将您的样式放在 global-styles 中,或者例如,在您的component.

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

      【讨论】:

        【解决方案3】:

        将此添加到您的_app.js

        import '../styles/globals.css'
        

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        【解决方案4】:

        您无需在 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。

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

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

        所以Component 等于您在pages/ 目录中拥有的任何组件。然后pageProps 将成为您打算传递给pages/ 内部文件的一组组件。

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

        你为什么要定义这个?

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

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

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

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

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

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

        【讨论】:

          【解决方案5】:

          使用内置的 Next.js CSS 加载器(参见here) 而不是旧版@zeit/next-sass

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

          由于 Next.js 9.2 全局 CSS 必须在 Custom &lt;App&gt; 组件中导入。

          // pages/_app.js
          
          import '../global-styles/main.scss'
          
          export default function MyApp({ Component, pageProps }) {
            return <Component {...pageProps} />
          }
          

          要仅将样式添加到特定组件或页面,您可以使用对CSS 模块的内置支持。(请参阅here

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

          【讨论】:

          • 嘿,我之前创建了 main.scss 并将其移动到该文件,但它不起作用。我又试了一次,还是没有应用。我有以下代码: import '../global-styles/main.scss' export default function MyApp({ Layout, props }) { return }
          • @IndustryDesigns,尝试使用node-sass 而不是@zeit/next-sass,我刚刚对其进行了测试并更新了答案。如果您在命令行或浏览器的控制台中有任何特定错误,请告诉我。
          • 这肯定有所作为。全局 css 现在在 _app.js 中工作。最后一件还没有工作的事情,以前工作的,是::global { .marginsContainer { width: 90%;边距:自动; } }
          • 我来这个答案是因为我试图在组件中使用 scss。显然现在我需要将我的 scss 文件与 components/my-component/ 文件夹分开并将其放在页面中?我很困惑..
          • @AntonDozortsev,从 Next.js 9.2 开始(参见Next.js 9.2 Blog Post)。
          【解决方案6】:

          您可以用您自己的替换过于固执己见且坦率地过度设计的 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
            },
          }
          

          【讨论】:

            【解决方案7】:

            对我来说,问题是因为我在我的 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我修改了它,将导出模块改成这样。

            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.exports 覆盖第一个。您的第一个 NextJS 配置实际上没有得到应用。
            猜你喜欢
            • 2021-11-04
            • 2021-07-03
            • 2019-05-08
            • 2018-10-13
            • 2020-12-09
            • 2021-06-02
            • 2021-08-31
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多