webpack-contrib / sass-loader

Compiles Sass to CSS
MIT License
3.9k stars 427 forks source link

After upgrading from 7.2.0 to 7.3.1 my webpack always minifies CSS? #784

Closed Friends-for-Brands closed 4 years ago

Friends-for-Brands commented 4 years ago

Good day!

Yesterday I have tried to upgrade my sass-loader from 7.2.0 to 7.3.1 but facing some weird problems now. In production & development mode by default, the sass-loader minifies my CSS output.

I would highly appreciate it if someone can help me out.

Also, when I try to upgrade to the latest Version 8 I get undefined of SPLIT on the build. Is this a know issue?

P.S. All packages Webpack and Node are up to date.

Followed by my Webpack config.

require('checkenv').check();

// Webpack Setup
const {
    THEME_AUTHOR,
    THEME_NAME,
    ASCII_TEXT,
    ASCII_FONT,
    HOST,
    PORT
} = require('./env.config');

const path = require('path');
const paths = require('./paths.config');
const pkg = require('../package.json');
const webpack = require('webpack');
const date = new Date();

// Plugins
const HappyPack = require('happypack');
const DashboardPlugin = require('webpack-dashboard/plugin');
const { AsciiArtWebpackPlugin } = require('ascii-art-webpack-plugin');
const ImageminWebpWebpackPlugin = require('imagemin-webp-webpack-plugin');
const HardSourceWebpack = require('hard-source-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const BrowserSync = require('browser-sync-webpack-plugin');
const MiniCssExtract = require('mini-css-extract-plugin');
const styleLint = require('stylelint-webpack-plugin');
const CopyWebpack = require('copy-webpack-plugin');
const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const WebpackBuildNotifierPlugin = require('webpack-build-notifier');
const CleanTerminalPlugin = require('clean-terminal-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const Imagemin = require('imagemin-webpack-plugin').default;
const threadPool = HappyPack.ThreadPool({ size: 4 });

// Config utils
const { removeEmpty, getIfUtils } = require('webpack-config-utils');
const { NODE_ENV } = process.env;
const { ifProduction, ifDevelopment } = getIfUtils(NODE_ENV);

module.exports = {
    target: 'web',
    mode: ifDevelopment ? 'development' : 'production',

    stats: {
        colors: false,
        hash: false,
        version: false,
        timings: false,
        assets: false,
        chunks: false,
        modules: false,
        reasons: false,
        children: false,
        source: false,
        errors: false,
        builtAt: false,
        errorDetails: false,
        entrypoints: false,
        warnings: false,
        publicPath: false
    },

    optimization: {
        minimize: ifProduction(true, false),
        namedModules: ifDevelopment(true, false),
        runtimeChunk: 'single',
        noEmitOnErrors: true,
        splitChunks: {
            hidePathInfo: true,
            chunks: 'all',
            automaticNameDelimiter: '-',
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            name: THEME_NAME,
            cacheGroups: {
                style: {
                    enforce: true,
                    priority: 1
                },
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: 2,
                    name: 'vendors',
                    enforce: true,
                    chunks: 'all'
                }
            }
        },

        minimizer: [
            new TerserPlugin({
                test: /\.js(\?.*)?$/i,
                cache: true,
                parallel: 4,
                sourceMap: ifDevelopment(true, false),
                extractComments: false,
                terserOptions: {
                    compress: {
                        drop_console: ifProduction(true, false)
                    }
                },
                exclude: /\/node_modules/
            })
        ]
    },

    entry: {
        src: [paths.entry.js(), paths.entry.sass()]
    },

    output: {
        path: paths.output.base(),
        filename: paths.filename.js()
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loaders: ['happypack/loader?id=js']
            },

            {
                test: /\.scss$/,
                exclude: /node_modules/,
                loaders: [MiniCssExtract.loader, 'happypack/loader?id=scss']
            }
        ]
    },

    plugins: removeEmpty([
        new CleanWebpackPlugin({
            // Write Logs to Console
            verbose: ifDevelopment(true, false),

            // Automatically remove all unused webpack assets on rebuild
            cleanStaleWebpackAssets: false,

            // Do not allow removal of current webpack assets
            protectWebpackAssets: false
        }),

        new ExtraWatchWebpackPlugin({
            files: ['.stylelintrc', '.eslintrc']
        }),

        new HappyPack({
            id: 'js',
            verbose: ifDevelopment(true, false),
            threadPool: threadPool,
            loaders: ['babel-loader', 'eslint-loader']
        }),

        new HappyPack({
            id: 'scss',
            verbose: ifDevelopment(true, false),
            threadPool: threadPool,
            loaders: [
                {
                    loader: 'css-loader',
                    options: {
                        url: false,
                        modules: false
                    }
                },
                'postcss-loader',
                'sass-loader'
            ]
        }),

        new styleLint({
            configFile: '.stylelintrc',
            context: paths.sass(),
            files: '**/*.s?(a|c)ss'
        }),

        new MiniCssExtract({
            filename: paths.filename.sass()
        }),

        new DashboardPlugin(),

        new CopyWebpack([
            {
                from: paths.images(),
                to: paths.output.images()
            }
        ]),

        new CopyWebpack([
            {
                from: paths.fonts(),
                to: paths.output.fonts()
            }
        ]),

        ifProduction(
            new ImageminWebpWebpackPlugin({
                config: [
                    {
                        test: /\.(jpe?g|png)/,
                        options: {
                            quality: 75
                        }
                    }
                ],
                overrideExtension: true,
                detailedLogs: true,
                silent: false,
                strict: true
            })
        ),

        ifProduction(
            new Imagemin({
                test: /\.(jpe?g|png|gif|svg)$/i
            })
        ),

        new AsciiArtWebpackPlugin({
            text: ASCII_TEXT,
            font: ASCII_FONT,
            extensions: ['js', 'css']
        }),

        new HardSourceWebpack.ExcludeModulePlugin([
            {
                // HardSource works with mini-css-extract-plugin but due to how
                // mini-css emits assets, assets are not emitted on repeated builds with
                // mini-css and hard-source together. Ignoring the mini-css loader
                // modules, but not the other css loader modules, excludes the modules
                // that mini-css needs rebuilt to output assets every time.
                test: /mini-css-extract-plugin[\\/]dist[\\/]loader/
            },
            {
                test: /my-loader/,
                include: path.join(__dirname, 'vendor')
            }
        ]),

        new HardSourceWebpack({
            environmentHash: {
                root: process.cwd(),
                directories: [],
                files: ['package-lock.json', 'yarn.lock']
            },

            info: {
                mode: 'none',
                level: 'debug'
            },

            // Clean up large, old caches automatically.
            cachePrune: {
                // Caches younger than `maxAge` are not considered for deletion. They must
                // be at least this (default: 2 days) old in milliseconds.
                maxAge: 2 * 24 * 60 * 60 * 1000,
                // All caches together must be larger than `sizeThreshold` before any
                // caches will be deleted. Together they must be at least this
                // (default: 50 MB) big in bytes.
                sizeThreshold: 50 * 1024 * 1024
            }
        }),

        new BrowserSync(
            {
                proxy: HOST,
                port: PORT,
                host: 'localhost',
                open: false,
                notify: false,
                logFileChanges: false,
                logLevel: 'info',
                // files: [`../**/*.scss`, `../**/*.php`],
                files: [
                    {
                        match: [
                            // '../assets/css/*.css',
                            // '../assets/js/*.js',
                            '../**/*.php'
                        ],
                        fn: (event, file) => {
                            if (event == 'change') {
                                const bs = require('browser-sync').get(
                                    'bs-webpack-plugin'
                                );
                                if (
                                    file.split('.').pop() == 'js' ||
                                    file.split('.').pop() == 'php'
                                ) {
                                    bs.reload();
                                } else {
                                    bs.reload('*.css');
                                }
                            }
                        }
                    }
                ],
                snippetOptions: {
                    ignorePaths: ['wp-admin/**', 'wp-content/**']
                }
            },

            {
                reload: false
            }
        ),

        new FriendlyErrorsPlugin(),

        new CleanTerminalPlugin(),

        new webpack.optimize.ModuleConcatenationPlugin(),

        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(NODE_ENV),
            'process.env.VERSION': JSON.stringify(pkg.version)
        }),

        new webpack.optimize.OccurrenceOrderPlugin(true),

        new webpack.BannerPlugin({
            banner: `Copyright ${date.getFullYear()} ${THEME_AUTHOR} All Rights Reserved - v${
                pkg.version
            }\nLast updated: ${date.getDate()}/${date.getMonth() +
                1}/${date.getFullYear()} (${date.getHours()}:${(
                '0' + date.getMinutes()
            ).substr(-2)})`,
            exclude: /(main-vendor|main-runtime)\.js/i
        }),

        ifDevelopment(new webpack.HashedModuleIdsPlugin()),

        ifDevelopment(
            new webpack.SourceMapDevToolPlugin({
                exclude: /(main-vendor|main-runtime)\.js/i
            })
        ),

        ifDevelopment(
            new WebpackBuildNotifierPlugin({
                title: `${THEME_AUTHOR}`,
                sound: false,
                suppressSuccess: true
            })
        )
    ])
};
alexander-akait commented 4 years ago

It looks like you just deleted our lovely crafted issue template. It was there for good reasons. Please help us solving your issue by answering the questions asked in this template. I'm closing this. Please either update the issue with the template and reopen, or open a new issue.

In production mode we generate compressed css (from sass) to increase performance.