React中css、css模块化、css-loader3版本配置模块化

521 阅读3分钟

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

一、 CSS内联样式

内联样式需要用json格式来定义

json格式中使用驼峰命名: fontSize

<div style={{width: '100%',height:'50px',background:'#0000FF',fontSize:'16px',color:'#FFF'}}></div>

二、 使用class和className

  1. 外部引用需要使用className, react默认不支持class
  2. 如果想使用传统的class来获取样式,需要下载安装react-html-atts插件
npm i babel-plugin-react-html-attrs  --save-dev
  1. 在package.josn中安装好插件

image.png 2. 在webpack.config.js中配置插件

image.png 3. 例子- 把我们之前写的删除弹框confirm组件的className全改成class

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

export default class Confirm extends React.Component {
    constructor() {
        super();
        this.state = {
            title: '',
            btnList: []
        }
        this.div = null
    }

    // 设置数据
    setData(title,btnList,div) {
        this.div = div
        this.setState({title,btnList})
    }

    // 确认弹框点击事件
    handleBtnClick(index) {
        console.log(index)
        // 关闭确认弹
        document.body.removeChild(this.div)
        let cb = this.state.btnList[index].onPress
        if(cb && typeof cb === 'function' && index === 1) {
            cb()
        }
    }

    render() {
        return (
            <div class='my-confirm'>
                <div class={'message'}>
                    <div class={'title'}>{this.state.title}</div>
                    <div class={'btn-group'}>
                        {
                            this.state.btnList.length > 0 && this.state.btnList.map((item,index) => {
                                return (
                                    <div class={'btn'} key={index} onClick={this.handleBtnClick.bind(this,index)}>{item.text}</div>
                                )
                            })
                        }
                    </div>
                </div>
            </div>
        )
    }
}

运行样式依然有效, 配置成功

CPT2106030750-610x888.gif

三、CSS模块化

  • React是单页面应用, 应用CSS样式默认是全局的, 这样会引起样式冲突, 降低性能
  • Vue里面的解决方案是使用Scoped:
<style scoped>
</style>

例如在app.css中定义的颜色是pink, 而在header组件的css中定义的颜色是yellow, yellow会覆盖pink

2021-06-04-05-40-35.gif

解决方案module模块化

其实在webpack.config.js中已经帮我们配置了模块化, 我们命名符合他的标准就可以了

image.png 在header组件中css module后样式就不会冲突了

image.png

image.png

如何使用模块css中的样式

image.png

效果

image.png

四、如何自定义模块化后css的命名

css模块化后发现命名方式是文件名 + 类名 + hash值 看webpackconfig中的源码 image.png

image.png

image.png 自定义改成 类名 + hash值的形式

{
              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction
                  ? shouldUseSourceMap
                  : isEnvDevelopment,
                modules: {
                  // getLocalIdent: getCSSModuleLocalIdent,
                  localIdentName: '[local]_[hash:base64:6]'
                },
              }),
            },

效果

image.png

五. 按文件夹模块化

 {
              // css 全部模块化
              test: cssRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction
                  ? shouldUseSourceMap
                  : isEnvDevelopment,
                modules: {
                  // getLocalIdent: getCSSModuleLocalIdent,
                  localIdentName: '[local]_[hash:base64:6]'
                },
              }),
              exclude: [
                  // 排序文件夹下面的css
                path.join(__dirname,'..','node_modules'),
                path.join(__dirname,'..','src/assets/css/common'),
                path.join(__dirname,'..','src/component')
              ],
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },

效果如下样式不生效全被模块化了

image.png

公共样式不模块化

{
              test: cssRegex,
              // exclude: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                modules: {//1、开启css模块化
                  //[path]-[name]-[local]-[hash:base64:6]
                  localIdentName: '[local]_[hash:base64:6]', //2、自动生成模块化后的名称
                },
                sourceMap: isEnvProduction && shouldUseSourceMap,
              }),
              exclude:[//3、排除文件夹下面的css文件
                path.join(__dirname, '..', 'node_modules'),
                path.join(__dirname, '..','src/assets/css/common'),
                path.join(__dirname, '..','src/components')
              ],
              // Don't consider CSS imports dead code even if the
              // containing package claims to have no side effects.
              // Remove this when webpack adds a warning or an error for this.
              // See https://github.com/webpack/webpack/issues/6571
              sideEffects: true,
            },
            {
              test:cssRegex,
              use:['style-loader','css-loader'],
              include:[//4、样式只应用到文件夹下面的css文件中
                path.join(__dirname, '..', 'node_modules'),
                path.join(__dirname, '..','src/assets/css/common'),
                path.join(__dirname, '..','src/components')
              ]
            },

            // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
            // using the extension .module.css
            {
              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: {
                  // getLocalIdent: getCSSModuleLocalIdent,
                  localIdentName: '[local]__[hash:base64:6]', //自动生成模块化后的名称
                },

              }),
            },

image.png

注意: css-loader 2.1.1以前的版本 css模块化是这样配置的

              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: true,
                localIdentName: '[local]__[hash:base64:6]', //自动生成模块化后的名称
              }),
            },