将css模块与Extract Text Plugin一起使用

时间:2017-07-09 15:46:10

标签: reactjs webpack-2 css-loader extract-text-plugin extracttextwebpackplugin

使用带有extract-text-webpack-plugin的css-loader中的css modules选项,Webpack 2 build在生产模式下无法正常工作。

在html元素上创建了正确的生成类,这意味着css-loader正在按预期工作,但是extract-text-webpack-plugin中提取的css文件缺少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文件工作正常,当与extract-text-webpack-plugin一起使用时,只会忽略导入的.cssm.css文件。

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

1 个答案:

答案 0 :(得分:5)

显然我的设置很好。问题是我没有在"条目"中包含我的所有样式(css / less)文件。 webpack配置。配置通过了构建阶段,但没有处理我在尝试将css模块与常规全局css一起使用时添加的新.cssm.less文件。

现在一切正常!为了将来参考,我将包括我使用css模块和全局css(用于生产和开发)的更新配置。显然在较新版本的webpack和extractTextPlugin中,确切的语法("使用" vs" loader"," options" vs" query"等等...)不再重要,并且两种方式都有效。

对于制作,我在" localIdentName"中的所有css模块类名称上添加了前缀cssm。属性,以便我以后可以使用PurifyCSSPlugin并将每个包含cssm的类列入白名单:

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')
                    ]
                }
            })
        ]
    };
};