Webpack如何配置scss的模块化?

新手上路,请多包涵

在学习webpack的过程中,想要使用style-loader,sass-loader与css-loader来配置一下css模块化的环境,但是当我开启了css-loader里面的modules为true时,可能是与style-loader存在冲突,发现无法正常使用模块化导入css资源,下面是webpack.config.js的配置

const { resolve } = require('path');
// 会帮你创建一个html 直接引用入口文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const cssLoader = {
    loader: 'css-loader',
    options: {
        modules: {
            localIdentName: '[local]-[hash:5]',
        }
    }
};

module.exports = {
    entry: {
        index: resolve(__dirname, './index.js')
    },
    output: {
        path: resolve(__dirname, '../../../', 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /\.s[ac]ss$/i,
                use: [
                    // 将 JS 字符串生成为 style 节点
                    { loader: 'style-loader' },
                    // 将 CSS 转化成 CommonJS 模块
                    cssLoader,
                    // 将 Sass 编译成 CSS
                    { loader: 'sass-loader' },
                ]
            },
            {
                test: /\.css$/i,
                use: [
                    {
                        loader: 'style-loader',
                    },
                    cssLoader,
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'scss-module',
            template: resolve(__dirname, '../../../public', 'index.html')
        }),
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: ['dist']
        })
    ]
}

我在js文件中这样导入并且使用css

import styles from './index.css';
console.log(styles);
const divElement = document.createElement('div');
divElement.className = styles['box'];
document.body.appendChild(divElement);

然后在浏览器中发现styles打印的内容为undefined,样式也没有正确的出现,这是为什么呢各位大佬?

当我将style-loader去除,发现可以正常获取styles的内容,并且内容也经过模块化的处理了,但是肯定是需要style-loader来做添加标签的处理的

阅读 1k
2 个回答

分开处理试试:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: {
        index: resolve(__dirname, './index.js')
    },
    output: {
        path: resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            // 处理 SCSS 模块
            {
                test: /\.module\.s[ac]ss$/i,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            modules: {
                                localIdentName: '[local]-[hash:5]',
                            },
                            esModule: true
                        }
                    },
                    'sass-loader',
                ]
            },
            // 处理普通 SCSS
            {
                test: /\.s[ac]ss$/i,
                exclude: /\.module\.s[ac]ss$/i,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader',
                ]
            },
            // 处理 CSS 模块
            {
                test: /\.module\.css$/i,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            modules: {
                                localIdentName: '[local]-[hash:5]',
                            },
                            esModule: true
                        }
                    },
                ]
            },
            // 处理普通 CSS
            {
                test: /\.css$/i,
                exclude: /\.module\.css$/i,
                use: [
                    'style-loader',
                    'css-loader',
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'scss-module',
            template: resolve(__dirname, 'public', 'index.html')
        }),
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: ['dist']
        })
    ]
};

引入的时候:

import styles from './index.module.css'; // 用 .module.css
console.log(styles); 
const divElement = document.createElement('div');
divElement.className = styles.box; 
document.body.appendChild(divElement);

加载器的执行顺序是从右到左的,所以 style-loader 应该在最左边,css-loader 在中间,sass-loader 在最右边

例如:

module: {
  rules: [
    {
      test: /\.s[ac]ss$/i,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: {
              localIdentName: '[local]-[hash:5]',
            }
          }
        },
        'sass-loader'
      ]
    },
    {
      test: /\.css$/i,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            modules: {
              localIdentName: '[local]-[hash:5]',
            }
          }
        }
      ]
    }
  ]
}

或者使用 MiniCssExtractPlugin:在生产环境中,使用 MiniCssExtractPlugin 提取 CSS,可以避免一些潜在的问题

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    // 其他配置...
    module: {
        rules: [
            {
                test: /\.s[ac]ss$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            modules: {
                                localIdentName: '[local]-[hash:5]',
                            }
                        }
                    },
                    'sass-loader'
                ]
            },
            {
                test: /\.css$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            modules: {
                                localIdentName: '[local]-[hash:5]',
                            }
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'scss-module',
            template: resolve(__dirname, '../../../public', 'index.html')
        }),
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: ['dist']
        }),
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[id].css'
        })
    ]
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏