将 css 个模块与提取文本插件一起使用

Using css modules with Extract Text Plugin

使用 css-loader 中带有 extract-text-webpack-plugin 的 css 模块选项,Webpack 2 构建在生产模式下无法按预期工作。

正确生成的 类 是在 html 元素上创建的,这意味着 css-loader 按预期工作,但提取的 css 文件来自 extract- text-webpack-plugin 缺少 css 标识符。

我正在使用一种方法同时实现全局 css 和 css 模块,如下所述:https://github.com/css-modules/css-modules/pull/65 在这里:https://github.com/kitze/custom-react-scripts/issues/29.

我对以 .css 结尾的文件和以 .cssm.css 结尾的文件使用不同的加载程序测试,表明它们应该使用模块加载。

配置的相关部分:

const extractTextPlugin = new ExtractTextPlugin({filename: '[name].[id].[contenthash].css', allChunks: true});

return {
    module: {
        rules: [
            {
                test: /\.cssm.(css|less)$/,
                loader: extractTextPlugin.extract({
                    fallbackLoader: 'style-loader',
                    loader: [
                        {
                            loader: 'css-loader',
                            query: {
                                importLoaders: 1,
                                modules: true,
                                localIdentName: '[name]_[local]_[hash:base64:5]'
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            query: {
                                ident: 'postcss',
                                plugins: function() {
                                    return [
                                            require('autoprefixer')
                                    ];
                                }
                            }
                        },
                        {
                            loader: 'less-loader'
                        }
                    ]
                })
            },
            {
                test: /\.(css|less)$/,
                include: paths,
                loader: extractTextPlugin.extract({
                    fallbackLoader: 'style-loader',
                    loader: [
                        {
                            loader: 'css-loader',
                            query: {
                                importLoaders: 1
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            query: {
                                ident: 'postcss',
                                plugins: function() {
                                    return [
                                            require('autoprefixer')
                                    ];
                                }
                            }
                        },
                        {
                            loader: 'less-loader'
                        }
                    ]
                })
            }
        ]
    },
    plugins: [
        extractTextPlugin
    ]
};

我已经尝试过建议的解决方案,例如使用 webpack 1 风格编写加载器,但这没有帮助。

我使用的webpack版本:2.6.1 和 extract-text-webpack-plugin: 2.1.2.

我也尝试了其他版本,但似乎也没有帮助。

我的全局 css 文件工作正常,只有导入的 .cssm.css 文件在与 extract-text-webpack-plugin 一起使用时被忽略。

如何解决 css 模块文件无法与其他全局 css 正确提取的问题?

显然我的设置没问题。问题是我没有在 "entry" webpack 配置中包含我所有的样式 (css/less) 文件。配置通过了构建阶段,但没有处理我在尝试将 css 模块与常规全局 css.

一起使用时添加的新 .cssm.less 文件

现在一切正常!为了将来参考,我将包括我更新的配置,以便将 css 模块与全局 css(用于生产和开发)一起使用。显然在较新版本的 webpack 和 extractTextPlugin 中,确切的语法("use" vs "loader"、"options" vs "query" 等...)不再重要并且可以双向工作.

为了生产,我在 "localIdentName" 属性 中的所有 css 模块 class 名称上添加前缀 cssm 以便稍后我可以使用 PurifyCSSPlugin 并将每个包含 cssm:

的 class 列入白名单
exports.setupSeparateStyles = function(paths, cssModulesPaths) {
    const extractTextPlugin = new ExtractTextPlugin({
            filename: '[name].[contenthash].css', 
            allChunks: true
        });

    return {
        module: {
            rules: [
                {
                    test: /\.(css|less)$/,
                    include: paths,
                    exclude: /\.cssm\.(css|less)$/,
                    use: extractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: [
                            {
                                loader: 'css-loader',
                                options: {
                                    importLoaders: 1
                                }
                            },
                            'postcss-loader',
                            'less-loader'
                        ]
                    })
                },
                {
                    test: /\.(css|less)$/,
                    include: cssModulesPaths,
                    use: extractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: [
                            {
                                loader: 'css-loader',
                                options: {
                                    importLoaders: 1,
                                    modules: true,
                                    localIdentName: 'cssm-[name]_[local]_[hash:base64:5]',
                                }
                            },
                            'postcss-loader',
                            'less-loader'
                        ]
                    })
                }
            ]
        },
        plugins: [
            new webpack.LoaderOptionsPlugin({
                options: {
                    postcss: [
                        require('autoprefixer')
                    ]
                }
            }),
            extractTextPlugin
        ]
    };
};

对于开发来说要简单得多:

exports.setupInlineStyles = function (paths, cssModulesPaths) {
    return {
        module: {
            rules: [
                {
                    test: /\.(css|less)$/,
                    include: paths,
                    exclude: /\.cssm\.(css|less)$/,
                    use: [
                        'style-loader',
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1
                            }
                        },
                        'postcss-loader',
                        'less-loader'
                    ]
                },
                {
                    test: /\.(css|less)$/,
                    include: cssModulesPaths,
                    use: [
                        'style-loader',
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                modules: true,
                                localIdentName: '[name]_[local]_[hash:base64:5]'
                            }
                        },
                        'postcss-loader',
                        'less-loader'
                    ]
                }
            ]
        },
        plugins: [
            new webpack.LoaderOptionsPlugin({
                options: {
                    postcss: [
                        require('autoprefixer')
                    ]
                }
            })
        ]
    };
};