mini-css-extract-plugin & sideEffects incompatibility

Created on 30 Apr 2018  路  14Comments  路  Source: webpack-contrib/mini-css-extract-plugin

Webpack 4.x
NodeJs 8.x/10.x

File generated by mini-css-extract-plugin is removed from the build because of sideEffects.

Confirmed with following values:

"sideEffects": false

"sideEffects": [
    "*.css"
]

Refer to https://github.com/webpack-contrib/mini-css-extract-plugin/issues/93 (closed by the author but unfixed)

Most helpful comment

importing CSS is a side effect. Using sideEffects: false is wrong in this case. You need to specify at least sideEffects: "*.css". Note that this may still not include all CSS. A unused, side-effect-free module can "hide" CSS. This is expected behavior. Here is an example:

import { ComponentA } from "./components.js";
{
  "sideEffects": "*.css"
}
// components.js
export { ComponentA } from "./componentA.js";
export { ComponentB } from "./componentB.js";
// componentA.js
import "./componentA.css";

export class ComponentA {}
// componentB.js
import "./componentB.css";

export class ComponentB {}

In this example componentA.css is included but componentB.css not.

All 14 comments

A CSS File can't have any sideEffects this property is for JS only :)

Well, ok but why the css file is not in the final bundle when using sideEffects?

Where is sideEffects declared ? In a dependency or the projects package.json ? Please provide more context here if possible

Why is *.css included ? What's the purpose ? If sideEffects is set to false and import css from './file.css''s are removed by webpack, loading CSS via e.g css-loader might have a side effect then (within the code css-loader adds)

can confirm.

import './style.scss'

the style will be removed when setting sideEffects false.

sideEffects is in package.json

My use of mini-css-extract-plugin is basic. I just want a single css file.
It works as expected but if I try to use sideEffects, the css file is not created...
I don't import css files in my javascript but maybe it's related to how vue-loader works, I really don't know.

const { VueLoaderPlugin } = require('vue-loader')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

var config = merge(baseConfig, {
  output: { ... },
  mode: 'production',
  devtool: false,
  optimization: { ... },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: ["vue-loader"]
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: { minimize: { discardComments: { removeAll: true } } }
          },
          "postcss-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.js$/,
        include: [`${rootPath}/src`],
        use: ["babel-loader"]
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),

    new MiniCssExtractPlugin({
      filename: "static/css/[name].[hash:8].css"
    })
  ]
})
}

Hi, I also has the problem.
I add
"sideEffects": [ "*.scss" ]
into package.json, but there still has some css files left out in dist .
my production config of css rules:
{ test: /\.css$/, use: [ 'MiniCssExtractPlugin.loader', 'css-loader', 'postcss-loader' ] }, { test: /\.s[ac]ss$/, use: [ 'MiniCssExtractPlugin.loader', 'css-loader', 'postcss-loader' , 'sass-loader'] },
By the way, all the js files import '.scss' file.
the left out files only import './index.scss';

"sideEffects": [ "*.css", "*.scss" ]

I am still broken with use of sideEffects set to false or [ "*.css", "*.scss" ]

If you are using Vue, what ended up fixing it for us was adding *.vue to the list (because of single file components). However, this breaks tree-shaking entirely. YMMV.

importing CSS is a side effect. Using sideEffects: false is wrong in this case. You need to specify at least sideEffects: "*.css". Note that this may still not include all CSS. A unused, side-effect-free module can "hide" CSS. This is expected behavior. Here is an example:

import { ComponentA } from "./components.js";
{
  "sideEffects": "*.css"
}
// components.js
export { ComponentA } from "./componentA.js";
export { ComponentB } from "./componentB.js";
// componentA.js
import "./componentA.css";

export class ComponentA {}
// componentB.js
import "./componentB.css";

export class ComponentB {}

In this example componentA.css is included but componentB.css not.

@sokra Thanks for the explaination, I understand how sideEffects works.
Is that mean webpack considers css file(s) generated by mini-css-extract-plugin but not imported in a js file should not be added in the final bundle... ? So is there a way to exclude some files/extension from deletion in the final bundle when sideEffects is on?

Declaring sideEffects as true in your webpack config works as well.

      {
        test: /\.scss$/,
        sideEffects: true,
        use: !useExternalCss
          ? [{ loader: 'style-loader' }, ...styleLoaders]
          : [{ loader: MiniCssExtractPlugin.loader }, ...styleLoaders],
      },

Hey, for us, as soon as we use sideEffects in our project, CSS order is not respected anymore. We'd like to use sideEffects in webpack (or in the package.json) for excluding the css/scss files, but we can't because the order is different.

@willdurand in case you haven't seen it, here's an open issue for what you're describing: https://github.com/webpack/webpack/issues/7094

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stavalfi picture stavalfi  路  4Comments

dmitrybelyakov picture dmitrybelyakov  路  3Comments

septs picture septs  路  3Comments

ripperdoc picture ripperdoc  路  3Comments

grrowl picture grrowl  路  3Comments