SassNinja / media-query-plugin

Webpack plugin for media query extraction.
MIT License
205 stars 27 forks source link

media queries extracted multiple times #2

Closed kthalmann closed 6 years ago

kthalmann commented 6 years ago

First, props for this plugin! It's time we use separate files for media queries to prevent unnecessary render blocking.

I'm using the symfony/webpack-encore bundle for an easy webpack configuration. When I use yarn run encore dev --watch to automatically recompile the assets, after the first changes and recompiling I can see that the media queries are extracted multiple times. If I quit the watch task and run it again the media queries seem extracted correctly again.

// webpack.config.js
const Encore = require('@symfony/webpack-encore');

const MediaQueryPlugin = require('media-query-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

Encore
    // empty the outputPath dir before each build
    .cleanupOutputBeforeBuild()

    // show OS notifications when builds finish/fail
    .enableBuildNotifications()

    // the project directory where all compiled assets will be stored
    .setOutputPath('web/build/')

    // the public path used by the web server to access the previous directory
    .setPublicPath('/build')

    // will create web/build/app.js and web/build/app.css
    .addEntry('app', './web_src/assets/js/app.js')

    // allow sass/scss files to be processed
    // .enableSassLoader()

    .enablePostCssLoader()

    // allow legacy applications to use $/jQuery as a global variable
    .autoProvidejQuery()

    .enableSourceMaps(!Encore.isProduction())

    // enable react
    .enableReactPreset()
    .configureBabel(function(babelConfig) {
        babelConfig.plugins = [
            'transform-class-properties',
            'transform-object-rest-spread'
        ];
    })

    .addLoader({
        test: /\.scss$/,
        use: [
            MiniCssExtractPlugin.loader,
            'css-loader',
            MediaQueryPlugin.loader,
            'postcss-loader',
            'sass-loader'
        ]
    })

    .addPlugin(
        new MediaQueryPlugin({
            include: ['app'],
            queries: {
                // commented media queries are not worth it (yet)
                '(max-width: 575.98px)': 'xs-down',
                '(min-width: 576px)': 'sm-up',
                // '(max-width: 767.98px)': 'sm-down',
                '(min-width: 768px)': 'md-up',
                // '(max-width: 991.98px)': 'md-down',
                '(min-width: 992px)': 'lg-up',
                // '(max-width: 1199.98px)': 'lg-down',
                '(min-width: 1200px)': 'xl-up',
                // '(min-width: 576px) and (max-width: 767.98px)': 'sm-only',
                // 'screen and (prefers-reduced-motion: reduce)': 'prm',
                print: 'print'
            }
        })
    );

module.exports = Encore.getWebpackConfig();
SassNinja commented 6 years ago

Hi @kthalmann, thanks for your issue!

You're right, the watch mode is not working correctly. I've just checked this (without webpack-encore) and confirm it.

I'll try to fix this on the weekend.

SassNinja commented 6 years ago

Should be fixed now in the branch fix/watchmode

@kthalmann would you please test if it works in your setup as well?

npm install --save-dev git+https://github.com/SassNinja/media-query-plugin.git#fix/watchmode

kthalmann commented 6 years ago

Unfortunately I still get the same results. The media queries are getting appended to the files after every rerun. No errors during the build.

SassNinja commented 6 years ago

Would you create a full example setup with encore? (e.g. via gist or codesandbox)

I'm not able to create a working setup with mini-css-extract-plugin (even without my plugin). So far it seems easier to me to work directly with webpack...

Here's a draft what I tried https://codesandbox.io/s/24rlpy7y7n

kthalmann commented 6 years ago

Sorry for the delay. Actually the problem doesn't seem to be Encore. I did a clean setup without Encore and the problem persists. Here is my setup: https://gist.github.com/kthalmann/2c1cae9ed6939a45bea6f30f02967d59

to use encore with webpack 4 you have to use the master branch at the moment "@symfony/webpack-encore": "git://github.com/symfony/webpack-encore.git#master"

hope that helps

SassNinja commented 6 years ago

alright, I'm now able to reproduce it!

If you use only one query in the options (what I did) it doesn't occur. But any further query has got the same problem again.

I'll try to fix this

SassNinja commented 6 years ago

I've worked over the code to have a safe way to remove the CSS from the previous compilation. My tests were all successful – no more duplicate CSS in the extracted files.

Please check and let me know if it works for your setup as well!

kthalmann commented 6 years ago

Yes, good job! Expected results in my setups with and without encore.

SassNinja commented 6 years ago

Glad to hear :)

I've merged the fix now so it's going to be in the next minor release (1.1.0)