简体   繁体   English

Next.js 全局 CSS 无法从自定义文件以外的文件导入<app></app>

[英]Next.js Global CSS cannot be imported from files other than your Custom <App>

My React App was working fine, using global CSS also.我的 React App 运行良好,也使用全局 CSS。

I ran npm i next-images , added an image, edited the next.config.js , ran npm run dev , and now I'm getting this message我运行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

I've checked the docs, but I find the instructions a little confusing as I am new to React.我已经检查了文档,但由于我是 React 的新手,所以我发现这些说明有点令人困惑。

Also, why would this error happen now?另外,为什么现在会发生这个错误? Do you think it has anything to do with the npm install?您认为它与 npm 安装有什么关系吗?

I've tried to remove new files I've added along with their code, but this doesn't fix the problem.我试图删除我添加的新文件及其代码,但这并不能解决问题。 I've also tried what the Read more: suggests.我还尝试了阅读更多:建议的内容。

My highest tier component.我的最高层组件。

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;

My next.config.js我的 next.config.js

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

My main.scss file我的 main.scss 文件

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

my global.scss我的 global.scss

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

The thing I find the weirdest is that this error came without changing anything to do with CSS, or Layout.js, and it was previously working?我觉得最奇怪的是,这个错误并没有改变任何与 CSS 或 Layout.js 相关的东西,而且它以前是有效的?

I've moved my main.scss import to the pages/_app.js page, but the styles still aren't coming through.我已将我的 main.scss 导入移动到 pages/_app.js 页面,但 styles 仍然没有通过。 This is what the _app.js page looks like这是 _app.js 页面的样子

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

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

Use the built-in Next.js CSS loader (see here ) instead of legacy @zeit/next-sass .使用内置的 Next.js CSS 加载器(参见此处)而不是旧版@zeit/next-sass

  1. Replace @zeit/next-sass package with sass .sass替换@zeit/next-sass包。
  2. Remove next.config.js .删除next.config.js Or do not change CSS loading in it.或者不要更改其中的 CSS 加载。
  3. Move the global CSS as suggested in the error message.按照错误消息中的建议移动全局 CSS。

Since Next.js 9.2 global CSS must be imported in Custom <App> component.由于 Next.js 9.2 必须在自定义<App>组件中导入全局 CSS。

// pages/_app.js

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

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

To add styles only to a specific component or page you can use built-in support of CSS modules.要将样式仅添加到特定组件或页面,您可以使用CSS 模块的内置支持。 (see here ) (见这里

For example, if you have a component Button.js you can create a Sass file button.module.scss and include it in the component.例如,如果您有一个组件Button.js ,您可以创建一个 Sass 文件button.module.scss并将其包含在组件中。

Next.js stops complaining when your file has module in naming, eg, changing import '../global-styles/main.scss';当您的文件在命名中有module时, Next.js停止抱怨,例如,更改import '../global-styles/main.scss'; to import '../global-styles/main.module.scss'; import '../global-styles/main.module.scss'; would fix the warning and you could have your styles in the global-styles , or for example, in your component .将修复警告,您可以将样式放在global-styles中,或者例如在您的component中。

No extra dependencies/configurations in next.config.js is required. next.config.js中不需要额外的依赖项/配置。

You can replace the opinionated (and overly-complex?) NextJs CSS loaders with your own.你可以用你自己的替换那些固执己见(而且过于复杂?)的 NextJs CSS 加载器。 Here's a simple one for global 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
  },
}

For me the problem was because I had used two module.exports in my next.config.js file like this对我来说,问题是因为我在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 I modified it to change the export module like this. 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 then I deleted the second module.exports 2然后我删除了第二个module.exports

This node package provides a perfect solution for it.本节点package为其提供了完美的解决方案。 You can find it here你可以在这里找到它

Steps to fix it:修复步骤:

1. Add package: 1 、添加package:

npm install next-remove-imports
or
yarn add next-remove-imports

2. Add this wrapper variable inside your next.config.js 2.在你的next.config.js 中添加这个包装器变量

const removeImports = require('next-remove-imports')({
   test: /node_modules([\s\S]*?)\.(tsx|ts|js|mjs|jsx)$/,
   matchImports: "\\.(less|css|scss|sass|styl)$"
 });

All it is doing is re-enabling global styling import rule for tsx|ts|js|mjs|jsx files它所做的只是为tsx|ts|js|mjs|jsx文件重新启用全局样式导入规则

3. Wrap your next config export with this next-remove-imports wrapper. 3.用这个next-remove-imports包装器包装你的下一个配置导出。 Something like this:像这样:

module.exports = removeImports((nextConfig)

4. Now restart your react app and you will be able to import CSS files inside any ts|js|js|jsx|mjs file or component. 4.现在重新启动你的 React 应用程序,你将能够在任何ts|js|js|jsx|mjs文件或组件中导入 CSS 个文件。

You did not need to do anything inside of next.config.js .你不需要在next.config.js中做任何事情。

Let's assume you are using a global css like Bootstrap, meaning it contains css that is meant to be applied to your entire application and all the different pages inside of it.假设您正在使用像 Bootstrap 这样的全局 css,这意味着它包含的 css 旨在应用于您的整个应用程序以及其中的所有不同页面。

Global css files have to be wired up to NextJS in a very particular fashion.全局 css 文件必须以一种非常特殊的方式连接到 NextJS。

So inside of the pages/ directory you need to create _app.js .因此,您需要在pages/目录中创建_app.js

It's critical that the file be named _app.js .将文件命名为_app.js

Then at the top of that file you would import Bootstrap css in the following manner:然后在该文件的顶部,您将按以下方式导入 Bootstrap css:

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

Then you would add the following:然后,您将添加以下内容:

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

So what is going on in that code?那么该代码中发生了什么?

Well, behind the scenes, whenever you try to navigate to some distinct page with NextJS, NextJS will import your component from one of the different files inside your pages/ directory.好吧,在幕后,每当您尝试使用 NextJS 导航到某个不同的页面时,NextJS 都会从您pages/目录中的不同文件之一导入您的组件。

NextJS does not just take your component and show it on the screen. NextJS 不只是将您的组件显示在屏幕上。

Instead it wraps it up inside of its own custom default component and that is referred to inside of NextJS as the App.相反,它将它包装在自己的自定义默认组件中,并在 NextJS 内部称为 App。

What you are doing by defining the _app.js is to define your own custom app component.您通过定义_app.js的是定义您自己的自定义应用程序组件。

So whenever you try to visit a route inside a browser or your root route, NextJS is going to import that given component and pass it into the AppComponent as the Component prop.因此,每当您尝试访问浏览器内的路由或根路由时,NextJS 都会导入该给定组件并将其作为Component属性传递给AppComponent

So Component there is equal to whatever components you have in the pages/ directory.因此,那里的Component等于您在pages/目录中拥有的任何组件。 And then pageProps is going to be the set of components that you are intending to pass to your files inside of pages/ .然后pageProps将成为您打算传递给pages/内文件的组件集。

So long story short, this thing is like thin wrapper around the component that you are trying to show on the screen.长话短说,这个东西就像你试图在屏幕上显示的组件的薄包装。

Why do you have to define this at all?为什么你必须定义这个?

Well, if you ever want to include some global css to the project, Bootstrap being a global css for example, you can only import global css into the _app.js file.好吧,如果你想在项目中包含一些全局 css,例如 Bootstrap 是一个全局 css,你只能将全局 css 导入到_app.js文件中。

It turns out that if you try to visit other components or other pages, NextJS does not load up or even parse those files.事实证明,如果您尝试访问其他组件或其他页面,NextJS 不会加载甚至解析这些文件。

So any css you may have imported inside there will not be included in the final HTML file.因此,您可能在其中导入的任何 css 都不会包含在最终的 HTML 文件中。

So you have a global css that must be included on every single page, it has to be imported into the app file because it's the only file that is guaranteed to be loaded up every single time a user goes to your application.所以你有一个必须包含在每个页面上的全局 css,它必须被导入到应用程序文件中,因为它是唯一保证每次用户访问你的应用程序时都会加载的文件。

Don't forget that in addition to importing the css inside of _app.js , you also have to run an npm install bootstrap in your terminal.不要忘记,除了在_app.js中导入 css 之外,您还必须在终端中运行npm install bootstrap

You can read more on this here: https://nextjs.org/docs/messages/css-global您可以在此处阅读更多信息: https ://nextjs.org/docs/messages/css-global

将此添加到您的_app.js

import '../styles/globals.css'

Try to include ".module" in your scss file name.尝试在您的 scss 文件名中包含“.module”。

Change main.scss to main.module.scssmain.module.scss更改为main.scss

Example:例子:

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

For me, i got this error because I had used improper naming for my project's parent folder, had used special characters in it,对我来说,我收到了这个错误,因为我对项目的父文件夹使用了不正确的命名,在其中使用了特殊字符,

like project#1,project#1,

after removing special chars, and changing the folder name to like project-1, the error got away.删除特殊字符并将文件夹名称更改为类似project-1,错误就消失了。

you must for every component css/scss write navbar.module.css/scss/sass.Next js doesnt compile navbar.css/scss/sass.你必须为每个组件 css/scss 编写 navbar.module.css/scss/sass.Next js 不会编译 navbar.css/scss/sass。 If hope my answer helps you !.如果希望我的回答对你有帮助!。

In my case there was typo in navbar.module.css I've written navbar.moduile.css就我而言,navbar.module.css 中有错字我写过 navbar.moduile.css

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM