如何在 React 应用程序中使用 CSS 模块应用全局样式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39805537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 12:10:01  来源:igfitidea点击:

How to apply global styles with CSS modules in a react app?

cssreactjscss-modulesreact-css-modules

提问by hidace

I'm currently using CSS Modules with React for my styling. So each of my components is importing in it's component specific css file, like so:

我目前正在使用带有 React 的 CSS 模块来设计我的样式。所以我的每个组件都在它的组件特定的 css 文件中导入,如下所示:

import React from 'react';
import styles from './App.css';

const example = () => (
  <div className={styles.content}>
    Hello World!
  </div>
);

export default example;

This works fine when styling individual components, but how do I apply global styling (html, body, header tags, divs, etc.) that isn't component specific?

这在为单个组件设置样式时效果很好,但是如何应用非组件特定的全局样式(html、正文、标题标签、div 等)?

回答by felixyadomi

Since you're using the ES6 import syntax you may use the same syntax to import your stylesheet

由于您使用的是 ES6 导入语法,因此您可以使用相同的语法来导入您的样式表

import './App.css'

Also, you can wrap your class with :globalto switch to the global scope (this mean CSS Module won't modulify it, eg: adding a random id next to it)

此外,您可以将您的类包装起来:global以切换到全局范围(这意味着 CSS 模块不会对其进行模块化,例如:在它旁边添加一个随机 id)

:global(.myclass) {
  background-color: red;
}

回答by hidace

This can be done by simply adding:

这可以通过简单地添加:

require('./App.css');

(thanks @elmeister who correctly answered this question.)

(感谢正确回答这个问题的@elmeister。)

回答by Manolo

The only way I found for importing styles globally, but only for a specific route is adding:

我发现全局导入样式但仅用于特定路由的唯一方法是添加:

<style dangerouslySetInnerHTML={{__html: `
  body { max-width: 100% }
`}} />

inside the return of rendermethod.

render方法的返回里面。

Otherwise, the styletag would be added to the <head>, and the styles would be applied for all next routes.

否则,style标签将被添加到<head>,并且样式将应用于所有下一条路线。

From https://medium.learnreact.com/the-style-tag-and-react-24d6dd3ca974

来自https://medium.learnreact.com/the-style-tag-and-react-24d6dd3ca974

Maybe the styles could be imported as a string from a file to have the code more organized.

也许样式可以从文件中作为字符串导入,以使代码更有条理。

回答by ksankar

I had encountered the same problem and found the following ways to address the issue, you may choose what applies to you best

我遇到了同样的问题,并找到了以下解决问题的方法,您可以选择最适合您的方法

  1. Define two sets of rules in your webpack config for parsing css/less files.
    • The first rule should be to include all global styles, assuming it's kept in /styles/ or similar directory.
    • The second rule is to process all locally scoped css styles, these should ideally be next to their components.
    • You can do this by using the include and excludeoption while defining a rule
    • or by enforcing a naming convention and writing rule accordingly, for example all css modules will be [name].module.cssand your test would check for /.module.(less|css)$/and parse it.
  1. 在 webpack 配置中定义两组规则来解析 css/less 文件。
    • 第一条规则应该是包含所有全局样式,假设它保存在 /styles/ 或类似目录中。
    • 第二条规则是处理所有本地范围的 css 样式,这些样式最好放在它们的组件旁边。
    • 您可以通过在定义规则时使用包含和排除选项来完成此操作
    • 或者通过强制执行命名约定和相应的编写规则,例如所有 css 模块都将是[name].module.css并且您的测试将检查/.module.(less|css)$/并解析它。

A sample is given below:

下面给出了一个示例:

      // exclude all global styles for css modules
      {
        test: /\.(less|css)$/,
        exclude: path.resolve(__dirname, './src/styles'),
        use: [
          {
            loader: CssExtractPlugin.loader,
            options: { hot: is_dev, reloadAll: is_dev }
          },
          {
            loader: "css-loader",
            options: { 
                modules: { 
                    localIdentName: '[local]___[hash:base64:5]'
                }
            }
          },
          "postcss-loader",
          "less-loader"
        ]
      },
      // process global styles without css modules
     {
        test: /\.(less|css)$/,
        include: path.resolve(__dirname, './src/styles'),
        use: [
          {
            loader: CssExtractPlugin.loader,
            options: { hot: is_dev, reloadAll: is_dev }
          },
          "css-loader",
          "postcss-loader",
          "less-loader"
        ]
      }
  1. Use :local and :globalwhile writing css/less. If css modules is enabled it will default to local mode, you can specify the mode in options as below:
  1. 在编写 css/less 时使用:local 和 :global。如果启用了 css 模块,它将默认为本地模式,您可以在选项中指定模式,如下所示:
          {
            loader: "css-loader",
            options: { 
                modules: { 
                    localIdentName: '[local]___[hash:base64:5]', 
                    mode: 'global',
                }
            }
          },

If you are defining mode as global then all your included css classes will not be replaced with hashed names, instead only the ones you specify as :local will be given unique names. For example:

如果您将 mode 定义为 global,则所有包含的 css 类都不会被替换为散列名称,而只会为您指定为 :local 的那些提供唯一名称。例如:

/* this will remain as is */
.header {
   color: blue;
}

:local {
  /* this will become something like item_xSH2sa */
  .item {
   color: yellow;
  }
}

  1. Define a function which checks your file to decide if it's css module or global, done using getLocalIdentoption. This is the method that I'm currently using in my setup. This also requires your files to have some naming convention, [name].module.lessfor css modules and [name].less for regular files. See example below:
  1. 定义一个函数来检查您的文件以确定它是 css 模块还是全局的,使用getLocalIdent选项完成。这是我目前在设置中使用的方法。这也要求你的文件有一些命名约定,[name].module.less用于 css 模块,[name].less 用于常规文件。请参阅下面的示例:
// regex to test for modules, loaderUtils is part of webpack dependencies
const cssModuleRegex = new RegExp(/\.module\.(less|css)$/);
const loaderUtils = require("loader-utils");

// inside webpack rules
      {
        test: /\.(less|css)$/,
        use: [
          {
            loader: CssExtractPlugin.loader,
            options: { hot: is_dev, reloadAll: is_dev }
          },
          {
            loader: "css-loader",
            options: { 
                modules: { 
                    localIdentName: '[local]___[hash:base64:5]', 
                    getLocalIdent: getLocalIdent
                }
            }
          },
          "postcss-loader",
          "less-loader"
        ]
      }

// this is a copy of the default function, modified slightly to achieve our goal
function getLocalIdent(loaderContext, localIdentName, localName, options) {

    // return local name if it's a global css file
    if (!cssModuleRegex.test(loaderContext.resourcePath)) {
        return localName;
    }

    if (!options.context) {
      // eslint-disable-next-line no-param-reassign
      options.context = loaderContext.rootContext;
    }

    const request = path
      .relative(options.context, loaderContext.resourcePath)
      .replace(/\/g, '/');

    // eslint-disable-next-line no-param-reassign
    options.content = `${options.hashPrefix + request}+${localName}`;

    // eslint-disable-next-line no-param-reassign
    localIdentName = localIdentName.replace(/\[local\]/gi, localName);

    const hash = loaderUtils.interpolateName(
      loaderContext,
      localIdentName,
      options
    );

    return hash
      .replace(new RegExp('[^a-zA-Z0-9\-_\u00A0-\uFFFF]', 'g'), '-')
      .replace(/^((-?[0-9])|--)/, '_');
  }

回答by Naveen Jain

Solution 1 :

解决方案1:

Import global styles in starting point of reactapp.
where the whole react app has been wrappedin a rootcomponent .
it can be index.jsor app.jsor index.html

reactapp.
整个 react 应用程序都wrapped组件中。
它可以是index.jsapp.jsindex.html

Solution 2 :

解决方案2:

use scssand create main.scssfile and importall other specifically needed custom scssfiles in main.scss

使用scss和创建main.scss文件并导入所有其他特别需要的custom scss文件main.scss