webpack配置css-loader让scss文件支持模块化引入

1. webpack部分:

重点: modules: true, // 为false引入就是空对象, 无法使用

复制代码
const path = require('path')
const webpack = require('webpack')
const webpackCommonConf = require('./webpack.common.js')
const { smart } = require('webpack-merge')
const { srcPath, distPath } = require('./paths.js')
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin')
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')

module.exports = smart(webpackCommonConf, {
    mode: 'development',
    module: {
        rules: [
            // 直接引入图片 url
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: 'file-loader'
            },
            {
                test: /\.css$/,
                // loader 的执行顺序是:从后往前
                loader: ['style-loader', {
                    loader: "css-loader",
                    options: {
                        sourceMap: true,
                        modules: true
                    },
                }, 'postcss-loader'] // 加了 postcss
            },
            {
                test: /\.scss$/,
                // 增加 'less-loader' ,注意顺序
                loader: ['style-loader',  {
                    loader: "css-loader",
                    options: {
                        sourceMap: true,
                        modules: true,
                    }
                }, {
                    loader: "sass-loader",
                }]
            }
        ]
    },
    // 输出source-map, 方便直接调试es6源码
    devtool: 'source-map',
    plugins: [
        new webpack.DefinePlugin({
            // window.ENV = 'development'
            'process.env': {
                NODE_ENV: JSON.stringify(process.env.NODE_ENV)
            }
        }),
        // 热更新
        new HotModuleReplacementPlugin(),
        new DllReferencePlugin({
            // 描述react动态链接库的文件内容(告知webpack索引的位置)
            manifest: require(path.join(distPath, 'react.manifest.json')),
        }),
    ],
    devServer: {
        hot: true,
        port: 8111,
        progress: true,  // 显示打包的进度条
        contentBase: distPath,  // 根目录
        open: false,  // true:自动打开浏览器
        compress: true,  // 启动 gzip 压缩
        // 设置代理
        proxy: {
            '/api': 'http://localhost:8000',
            '/api2': {
                target: 'http://localhost:8111',
                pathRewrite: {
                    '/api2': ''
                }
            }
        }
    }
})

2. 组件使用:

import styles from 'xx/path';

然后在标签的className使用styles.xxx或者styles['xxx'], 有中划线或者下划线的需要使用style['xxx-xxx']

复制代码
import React, { useState } from "react";
import connect from './connect';
import { mapStateTotProps } from "./mapStateToProps";
import { mapDispatchToProps } from "./mapDispatchToProps";
import styles from './TodoInput.scss'

// 子组件
const TodoInput = (props) => {
  console.log(styles, 'styles')
  const [text, setText] = useState("");
  const {
    addTodo,
    showAll,
    showFinished,
    showNotFinish,
  } = props;

  const handleChangeText = (e: React.ChangeEvent) => {
    setText((e.target as HTMLInputElement).value);
  };

  const handleAddTodo = () => {
    if (!text) return;
    addTodo({
      id: new Date().getTime(),
      text: text,
      isFinished: false,
    });
    setText("");
  };

  return (
    <div className={styles["todo-input"]}>
      <input
        type="text"
        placeholder="请输入代办事项"
        onChange={handleChangeText}
        value={text}
      />
      <button className={styles.btn} onClick={handleAddTodo}>+添加</button>
      <button className={styles.btn} onClick={showAll}>show all</button>
      <button className={styles.btn} onClick={showFinished}>show finished</button>
      <button className={styles.btn} onClick={showNotFinish}>show not finish</button>
    </div>
  );
};

export default connect(mapStateTotProps, mapDispatchToProps)(TodoInput);

注意事项:

  1. 作为模块化引入使用相当于vue的style标签加scope的效果, 因为会对class类解析生成唯一性字符串, 而标签是不会解析的, 如果class类的名称不想被改变使用:global{...}

scss文件:

复制代码
// :global写在里面, 因为外面的类的关系, 不会被全局样式影响
.todo-input {
    :global {
        .aaa {
            color: red;
        }
    }
}


// 写在最外层作用域, class名称是aaa的, 全局都会被影响
:global {
        .aaa {
            color: red;
        }
    }

组件使用:

import styles from './TodoInput.scss'

<input

type="text"

placeholder="请输入代办事项"

onChange={handleChangeText}

value={text}

className="aaa"

/>

  1. 也支持import 'xxx.scss'语法, 不过就没有styles对象了, scss里面的类名叫什么写什么

组件使用:

import './TodoInput.scss'

<input

type="text"

placeholder="请输入代办事项"

onChange={handleChangeText}

value={text}

className="aaa"

/>

<button className="btn" onClick={handleAddTodo}>+添加</button>

相关推荐
Misnice1 小时前
Webpack、Vite、Rsbuild区别
前端·webpack·node.js
RFCEO2 小时前
前端编程 课程十六、:CSS 盒子模型
css·前端基础课程·css盒子模型·css盒子模型的组成·精准控制元素的大小和位置·css布局的基石·内边距(padding)
EHagSJVNpTY3 小时前
基于樽海鞘算法(SSA)的极限学习机(ELM)回归预测对比:BP、GRNN、ELM与SSA - ELM
scss
夏幻灵9 小时前
CSS三大特性:层叠、继承与优先级解析
前端·css
会编程的土豆1 天前
新手前端小细节
前端·css·html·项目
珹洺1 天前
Bootstrap-HTML(二)深入探索容器,网格系统和排版
前端·css·bootstrap·html·dubbo
BillKu1 天前
VS Code HTML CSS Support 插件详解
前端·css·html
1024小神1 天前
用css的clip-path裁剪不规则形状的图片展示
前端·css
GGGG寄了1 天前
CSS——文字控制属性
前端·javascript·css·html
HWL56791 天前
在网页中实现WebM格式视频自动循环播放
前端·css·html·excel·音视频