stan.codes
stan.codes

Reputation: 379

Webpack mini-css-extract-plugin doesn't produce css files when building

I am trying to configure mini-css-extract-plugin to produce a single or chunks of CSS files from SCSS after building, but as it seems I am not very familiar with webpack and I fail somewhere.

Using "webpack": "^4.29.0", "mini-css-extract-plugin": "^0.5.0" what I managed to produce are JS files where they should have been CSS files.

const webpack = require('webpack')

const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const isProd = (process.env.NODE_ENV === 'production')

const port = 3000,
    host = 'localhost'

const styles = [
    { loader: isProd? MiniCssExtractPlugin.loader : 'style-loader' },
    {
        loader: 'css-loader',
        options: {
            sourceMap: !isProd,
            modules: true,
        }
    },
    { loader: 'postcss-loader' },
    {
        loader: 'sass-loader',
        options: {
            sourceMap: !isProd,
        }
    }]

module.exports = {
    mode: isProd? 'production': 'development',
    entry: ['@babel/polyfill', './src/index.js'],
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                exclude: /node_modules/,
                use: styles
            },
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
                exclude: /node_modules/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'content/fonts/'
                    }
                }]
            }
        ]
    },
    resolve: {
        extensions: ['.scss', '.js', '.jsx']
    },
    output: {
        path: __dirname + '/dist',
        publicPath: '',
        filename: 'bundle.js'
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new CopyWebpackPlugin([
            { from:'src/content/images', to: 'content/images' },
        ]),
        new HtmlWebpackPlugin({
            template: './src/index.html',
            inject: 'body',
        }),
        new MiniCssExtractPlugin({
            chunkFilename: '[name].css',
            filename: 'styles.css'
        })
    ],
    optimization: {
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                styles: {
                    name: 'styles',
                    test: /\.(css|sass|scss)$/,
                    chunks: 'all',
                    enforce: true,
                    minChunks: 1,
                    reuseExistingChunk: true,
                }
            }
        }
    },
    devtool: 'source-map',
    devServer: {
        contentBase: './dist',
        hot: true,
        host: host,
        port: port,
        historyApiFallback: true,
        compress: true,
    }
}

I want to able to produce a big single CSS file or multiple chunks of CSS and files.

Upvotes: 3

Views: 3265

Answers (1)

Ali Doustkani
Ali Doustkani

Reputation: 808

The problem is that the isProd is always false, that's why webpack creates your style chunk as a js file (styles.bundle.js). Set the isProd to true and give it a try. It should work. Actually I tried it on my machine and it did work.

const isProd = true // just for debugging purpose. (process.env.NODE_ENV === 'production')

And one more thing, I recommend to not to use Sass and PostCss together. I think that cost your project with more complexity. Because I don't think you'll need Sass or any other preprocessor with a tool like PostCSS. But if you insist on that, PostCSS has a nice parser for sass files, that way your webpack config will be more readable at least. Good luck!

Upvotes: 2

Related Questions