Webpack - scss/css 模块样式未在产品中应用 [英] Webpack - scss/css modules styles not being applied in prod

查看:95
本文介绍了Webpack - scss/css 模块样式未在产品中应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 scss 模块,所以我在我的 React 组件中使用了 styleName,并且一切都在 dev 中工作.prod 中的元素看起来像 <div class="row" stylename="table"></div> 但没有对 应用任何样式表格.

I'm using scss modules so I'm using styleName in my react components and everything works in dev. The elements in prod looks like <div class="row" stylename="table"></div> but no styles have been applied to table.

webpack 配置被拆分成多个文件(webpack.profile.jswebpack.base.jswebpack.dev.js>, webpack.prod.js)

The webpack configs are split up into multiple files (webpack.profile.js, webpack.base.js, webpack.dev.js, webpack.prod.js)

旁注:我还注意到某些 jenkins 工作无法处理 @ 变量,不确定它是否与 webpack/sass-loader 相关.

Side note: I'm also noticing that certain jenkins job can't process @ variables, not sure if it's related to webpack/sass-loader.

webpack.profile.js

webpack.profile.js

const path = require('path')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CompressionPlugin = require('compression-webpack-plugin')
const VisualizerPlugin = require('webpack-visualizer-plugin')

module.exports = require('./webpack.base')({
    mode: 'production',
    devServer: {
        port: 3000,
        contentBase: path.join(process.cwd(), 'dist/')
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true
            }),
            new OptimizeCSSAssetsPlugin()
        ]
    },
    module: {
        rules: [
            {
                test: /\.(sc|sa|c)ss$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                        {
                        loader: "css-loader",
                        options: {
                                modules: true,
                                sourceMap: true,
                                localIdentName: "[name]_[local]_[hash:base64:5]"
                        }
                        }
                ]
            }
        ]
    },
    plugins: [
        new CompressionPlugin({
            test: /\.(js|css|html)$/
        }),
        new VisualizerPlugin({
            filename: '../stats/bundleStats.html'
        }),
        new MiniCssExtractPlugin({
            filename: '[name].[hash].css',
            chunkFilename: '[id].[hash].css'
        })
    ]
})

webpack.base.js

webpack.base.js

const path = require('path')
const Dotenv = require('dotenv-webpack')
const HtmlWebPackPlugin = require('html-webpack-plugin')

module.exports = options => {
    let envPath = '.env'
    process.argv.forEach(val => {
        if (val.includes('--env=')) {
            const curEnv = val.slice(6)
            if (['dev', 'stg'].includes(curEnv)) {
                envPath = `.env.${curEnv}`
            }
        }
    })
    return {
        mode: options.mode,
        devServer: options.devServer,
        entry: [path.join(process.cwd(), 'src/main.js')],
        output: {
            path: path.join(__dirname, '../dist/'),
            publicPath: '/',
            filename: '[name].[hash].js',
            chunkFilename: '[id].[hash].js'
        },
        resolve: {
            extensions: ['.js', '.jsx'],
            modules: [
                path.join(__dirname, '../src'),
                path.join(__dirname, '../node_modules')
            ],
            alias: {
                '@constants': path.join(__dirname, '../src/constants'),
                '@c': path.join(__dirname, '../src/components'),
                '@C': path.join(__dirname, '../src/containers')
            }
        },
        plugins: options.plugins.concat([
            new Dotenv({
                path: path.join(process.cwd(), envPath)
            }),
            new HtmlWebPackPlugin({
                inject: true,
                template: path.join(__dirname, '../src/static/index.html'),
                favicon: path.join(__dirname, '../src/static/favicon.ico')
            })
        ]),
        module: {
            rules: options.module.rules.concat([
                // {
                //  enforce: 'pre',
                //  test: /\.jsx?$/,
                //  exclude: /node_modules/,
                //  use: [
                //      {
                //          loader: 'eslint-loader',
                //          options: {
                //              quiet: true
                //          }
                //      }
                //  ]
                // },
                {
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    exclude: [ /\.scss$/ ],
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                name: '[hash].[ext]',
                                outputPath: 'fonts'
                            }
                        }
                    ]
                },
                {
                    test: /\.svg$/,
                    loader: 'svg-react-loader'
                },
                {
                    test: /\.(gif|png|jpe?g)$/i,
                    use: [
                        {
                            loader: 'url-loader',
                            options: {
                                limit: 10 * 1024,
                                name: '[hash].[ext]',
                                outputPath: 'assets'
                            }
                        },
                        {
                            loader: 'image-webpack-loader',
                            options: {
                                disable: options.mode === 'development'
                            }
                        }
                    ]
                }
            ])
        }
    }
}

webpack.dev.js

webpack.dev.js

const webpack = require('webpack')
const BrowserSyncPlugin = require('browser-sync-webpack-plugin')

module.exports = require('./webpack.base')({
    mode: 'development',
    devServer: {
        hot: true,
        port: 3000,
        historyApiFallback: true
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new BrowserSyncPlugin(
            { proxy: 'http://localhost:3000/', open: false },
            { reload: false }
        )
    ],
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        plugins: [
                            [
                                'react-css-modules',
                                {
                                    "filetypes": {
                                        ".scss": { "syntax": "postcss-scss" }
                                    },
                                    "generateScopedName": '[name]_[local]_[hash:base64:5]'
                                }
                            ],
                        ],
                    },
                },
                resolve: {
                        extensions: ['.js', '.jsx']
                }
            },
            {
                test: /\.(sa|sc)ss$/,
                use: [
                    { loader: 'style-loader' },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            sourceMap: true,
                            localIdentName: '[name]_[local]_[hash:base64:5]'
                        }
                    },
                    {
                        loader: 'sass-loader'
                    }
                ]
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            },
        ]
    }
})

webpack.prod.js

webpack.prod.js

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = require('./webpack.base')({
    mode: 'production',
    devServer: {
        port: 3000,
        contentBase: path.join(process.cwd(), 'dist/')
    },
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                cache: true,
                parallel: true
            }),
            new OptimizeCSSAssetsPlugin()
        ]
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules\/@babel/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            [
                            '@babel/preset-env',
                                {
                                    'targets': {
                                        'ie': '11'
                                    },
                                    'loose': true,
                                    'forceAllTransforms': true
                                }
                            ],
                            '@babel/preset-react'
                        ],
                        sourceType: 'unambiguous',
                        plugins: [
                            [
                                '@babel/plugin-proposal-decorators',
                                {
                                    'legacy': true
                                }
                            ],
                            '@babel/plugin-transform-runtime',
                            '@babel/plugin-syntax-dynamic-import',
                            '@babel/plugin-proposal-function-bind',
                            '@babel/plugin-proposal-class-properties',
                            '@babel/plugin-proposal-export-default-from',
                            '@babel/plugin-proposal-export-namespace-from'
                        ]
                    }
                },
                resolve: {
                    extensions: ['.js', '.jsx']
                }
            },
            {
                test: /\.(sc|sa)ss$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    {
                    loader: "css-loader",
                    options: {
                        modules: true,
                        sourceMap: true,
                        localIdentName: "[name]_[local]_[hash:base64:5]"
                    }
                    },
                    { loader: "postcss-loader" },
                    {  loader: "sass-loader" }
                ]
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin([path.join(process.cwd(), '/dist')], {
            allowExternal: true
        }),
        new MiniCssExtractPlugin({
            filename: '[name].[hash].css',
            chunkFilename: '[id].[hash].css'
        }),
        new CompressionPlugin({
            test: /\.(js|css)$/,
            filename: asset => asset.file
        })
    ]
})

推荐答案

对于这行代码

test: /\.(sc|sa|c)ss$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                        {
                        loader: "css-loader",

我很确定你不能这样做,因为 scss 和 sass 需要有 sass 或 scss 加载器,所以如果你使用 css-loader 则它不能处理 sass 或 scss

I'm pretty sure you cant do that because scss and sass need to have sass or scss loader so it cant process sass or scss if you using css-loader

这里是我的配置

module: {
        rules: [{
                test: /\.scss$/,
                use: [
                    'style-loader',
                    MiniCssExtractPlugin.loader,
                    {
                        loader: "css-loader",
                        options: {
                            minimize: true,
                            sourceMap: true
                        }
                    },
                    {
                        loader: "sass-loader"
                    }
                ]
            }
        ]
    }

你可以查看我的完整配置 这里

You can view my full config here

这篇关于Webpack - scss/css 模块样式未在产品中应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆