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>

相关推荐
前端呆猿6 小时前
深入解析HTML5中的object-fit属性
前端·css·html5
路灯下的光8 小时前
用scss设计一下系统主题有什么方案吗
前端·css·scss
一只小风华~8 小时前
CSS @media 媒体查询
前端·css·媒体
复苏季风19 小时前
CSS 布局小技巧:用 padding 撑开 div 不香吗?
css
不死鸟.亚历山大.狼崽子19 小时前
Syntax Error: Error: PostCSS received undefined instead of CSS string
前端·css·postcss
今禾21 小时前
前端工程化的范式革命:从 Webpack 的“全量打包”到 Vite 的“按需编译”
前端·webpack·vite
不在了情绪1 天前
CSS 基础语法 + 弹性盒子
前端·css
无羡仙1 天前
Webpack 核心实战:从零搭建支持热更新与 Babel 转译的现代前端环境
前端·webpack·前端框架
狂炫一碗大米饭2 天前
每个前端开发人员都应该知道的 6 大 CSS 框架
css·scss
惜分飞2 天前
ORA-600 kcratr_nab_less_than_odr和ORA-600 2662故障处理---惜分飞
前端·css·less