mini-css-extract-plugin icon indicating copy to clipboard operation
mini-css-extract-plugin copied to clipboard

Filtering multiple entries chunks

Open zalishchuk opened this issue 3 years ago • 6 comments

Feature Proposal

The feature I am trying to implement is filtering entry chunks from which CSS will be extracted. Any chance it can be done using filename function syntax and pathData argument in it?

Feature Use Case

Two same entry points, with different names, but one of them does not have externals in it. Done with the help of webpack5 layers feature. So as a result, we have like 2 identical .css files exported with different names, but want to have only one. HtmlWebpackPlugin has this feature and it is very useful.

// webpack.config.js

entry: {
  bundle: {
    import: './src/index.js',
    layer: 'bundle',
  },
  'bundle-externals': {
    import: './src/index.js',
    layer: 'bundle-externals',
  },
},
externals: {
  byLayer: {
    'bundle-externals': {
      'my-lib': 'myLib',
    },
  },
},
plugins: [
  new MiniCssExtractPlugin({
    chunks: ['bundle'], // proposed feature
    filename: '[name].css'
  }),
  new HtmlWebpackPlugin({
    chunks: ['bundle'],
    template: './src/index.html',
  }),
]

Please paste the results of npx webpack-cli info here, and mention other relevant information

System:
  OS: macOS 11.6.5
  CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
  Memory: 151.33 MB / 16.00 GB
Binaries:
  Node: 16.15.0 - ~/.nvm/versions/node/v16.15.0/bin/node
  Yarn: 1.22.19 - ~/.yarn/bin/yarn
  npm: 8.5.5 - ~/.nvm/versions/node/v16.15.0/bin/npm
Browsers:
  Chrome: 105.0.5195.125
  Safari: 15.4
Packages:
  css-loader: ^6.7.1 => 6.7.1
  css-minimizer-webpack-plugin: ^4.1.0 => 4.1.0
  html-webpack-plugin: ^5.5.0 => 5.5.0
  postcss-loader: ^7.0.1 => 7.0.1
  resolve-url-loader: ^5.0.0 => 5.0.0
  sass-loader: ^13.0.2 => 13.0.2
  style-loader: ^3.3.1 => 3.3.1
  webpack: ^5.74.0 => 5.74.0
  webpack-cli: ^4.10.0 => 4.10.0
  webpack-dev-server: ^4.11.0 => 4.11.0

zalishchuk avatar Sep 20 '22 16:09 zalishchuk

Why do not use layer? https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/loader.js#L304

alexander-akait avatar Sep 22 '22 22:09 alexander-akait

@alexander-akait the reason is that layers are not included into plugin options validation schema, and even if I remove the validation manually it doesn't work as expected.

ValidationError: Invalid options object. Mini CSS Extract Plugin has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'layer'. These properties are valid:
   object { filename?, chunkFilename?, experimentalUseImportModule?, ignoreOrder?, insert?, attributes?, linkType?, runtime? }

The solution I found for myself is:

function _wrapExternalsLayer(rawExternals) {
  const externals = rawExternals.byLayer;

  return (ctx, callback) => {
    const issuerLayer = ctx.contextInfo?.issuerLayer;
    if (issuerLayer) {
      const moduleName = ctx.request.split('/')[0];
      const externalResult = externals[issuerLayer]?.[moduleName];
      if (externalResult) return callback(null, externalResult);
    }

    callback();
  };
}

// webpack.config.js
externals: _wrapExternalsLayer({
  byLayer: {
    'bundle-externals': {
      'my-lib': 'myLib',
    },
  },
}),

zalishchuk avatar Sep 22 '22 22:09 zalishchuk

Ah, didn't notice this layer option is for the loader, not the plugin, but still doesn't solve the problem I mentioned above.

zalishchuk avatar Sep 22 '22 23:09 zalishchuk

Yeah, you need to pass this to loader https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/loader-options.json#L28

alexander-akait avatar Sep 23 '22 00:09 alexander-akait

The feature I am trying to implement is filtering entry chunks from which CSS will be extracted.

Can you clarify?

Because in this case you will have the first chunk extracted and the second chunk with CSS inside JS, do you expect it?

alexander-akait avatar Sep 23 '22 00:09 alexander-akait

To be honest, I don't think you're going in the right direction. You can use multi compiler mode for it. Maybe I missing something, so can you create a small repo/example and show you what you expected?

alexander-akait avatar Sep 23 '22 00:09 alexander-akait

Closing due to inactivity. Please test with latest version and feel free to reopen if still regressions. Thanks!

alexander-akait avatar Apr 16 '24 16:04 alexander-akait