Webpack 无法修复 CSS 覆盖问题并在 <head> 中捆绑 <style> 元素

Webpack can't fix CSS override issue and bundle <style> elements in <head>

在我的应用程序中,假设我有两个 JS 页面 A 和 B,每个页面都导入不同的样式表 (import '../style/<A or B.css>')。
两个样式表具有相同的 class 名称,但属性不同。

我运行yarn run dev ==> dev: webpack-dev-server --inline --hot ==> webpack -p

这就是我的 html <head> 的样子
https://imgur.com/a/1JVb5
首先加载页面 A 样式表,然后在

之后加载页面 B css 样式

当我转到页面 B 时,css 是正确的
当我转到页面 A 时,css 混淆了,一些 class 样式被页面 B.css 覆盖。

我的项目结构是这样的

public/
 bundle.js
 index.html
src/
 components/
 pages/
 style/
 App.js
 index.js
 package.json
 webpack.config.js

我的webpack.config.js是

const path = require('path');

var config = {
    entry: path.resolve(__dirname, 'src', 'index.js'),
    output: {
        path: path.resolve(__dirname, 'public'),
        filename: 'bundle.js'
    },
    devServer: {
        contentBase: path.resolve(__dirname, 'src'),
        publicPath: path.resolve(__dirname, 'public')
    },
    module: {
        rules: [
        {
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: [
                { loader: 'babel-loader',
                options: { presets: ['react','env'] } }
            ]
        },
        {
            test: /\.css$/,
            use: [
                { loader: "style-loader?singleton", 
                  options: 
                  { singleton: true } 
                },
                { loader: "css-loader" }
            ]
        }
        ]
    }
};
module.exports = config;

我希望 Webpack 合并多个元素并修复 css 覆盖问题
在 Webpack 中,我尝试了 style-loader?singleton{ singleton: true } 但它没有用。

编辑 1: 查看 extract-text-webpack-plugin

编辑 2:

import movieStyle from '../style/MovieDetail.css' 
... 
return (
<div id="CellDetail_right" className={ movieStyle['cell-detail-right'] }>...</div>
) 

好的,我添加了 options: { modules: true } 但它没有用。我的 class 名称带有连字符,编译后浏览器呈现没有任何样式或 classes 的组件。 Div 在浏览器上看起来像 <div id="CellDetail_right">...<div>

一种解决方案是启用局部范围 css 以避免样式 bleeding/overrides。 更新您的 css-loader 选项以包含 modules: true

{
    test: /\.css$/,
    use: [
        {
            loader: "style-loader", 
            options: { singleton: true }
        },
        {
            loader: "css-loader",
            options: {
                modules: true,
                camelCase: 'dashes',
                localIdentName: '[path][name]__[local]'
            }
        }
    ]
}

然后,在您的组件中使用:

import styles from '../style/MovieDetail.css';

function MyComponent() {
    return (
        <div className={styles.container}>
            <div className={styles.cellDetailRight}>Some Content</div>
        </div>
    );
}

这确保尽管您在其他 css 文件中定义了更多 .container 规则,但此特定规则会变成类似于 ._-path-to-component__container.

的内容

在选项中使用 camelCase: 'dashes' 转换您的带连字符的规则。

dashes in class names will be camelized

您还可以查看我的 webpack-demo 项目,其中包含用于处理您的场景的配置。 检查 webpack configurations

阅读更多关于css-loader options