Home > Software design >  Webpack, generate individual CSS file for each imported CSS file with MiniCssExtractPlugin
Webpack, generate individual CSS file for each imported CSS file with MiniCssExtractPlugin

Time:07-12

I'm new to Webpack (and dev) and am trying to figure out how to use Webpack and some plugins to separate any CSS import into an individual CSS link tag.

This is my webpack-config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  entry: {
    index: ['./src/assets/js/script.js'],
  },

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'assets/js/[name].bundle.js',
    assetModuleFilename: 'assets/images/[name][ext][query]',
    clean: true,
  },

  plugins: [
    new HtmlWebpackPlugin({
      chunks: ['index'],
      title: "~we don't talk about bruno~",
      filename: 'index.html',
      template: './src/index.html',
    }),
    new MiniCssExtractPlugin({
      filename: 'assets/css/[name].css',
    }),
  ],

  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          // 2. remove CSS from JS and save into an external file
          { loader: MiniCssExtractPlugin.loader },
          // 1. generate CSS into CommonJS
          'css-loader',
        ],
      },
      {
        test: /\.scss$/i,
        use: [
          // 3. remove CSS from JS and save into an external file
          { loader: MiniCssExtractPlugin.loader },
          // 2. generate CSS into CommonJS
          'css-loader',
          // 1. tranpile SCSS into CSS
          'sass-loader',
        ],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
    ],
  },
};

This is my JavaScript file:

import '../css/style.scss';
import 'animate.css';

I know Webpack is a bundler and I understand it but is there a possibility to generate index.css and animate.css individually and link it to HTML? Or maybe use another plugin and specify animate.css on the Webpack config.

CodePudding user response:

Solution

You could use optimization entry of webpack.config.js. You can add this entry in your webpack.config.js after plugins array for example:

optimization: {
    moduleIds: "deterministic",
    splitChunks: {
      cacheGroups: {
        styles: {
          test: /animate.css/
          name: "animate",
          type: "css/mini-extract",
          chunks: "all",
          enforce: true,
        },
      },
    },
  },

The above configuration would generate a separate file for animate.css. However it won't generate a separate CSS file per CSS file import. It's kind of the opposite of what a module bundler is made for.

More

Often what we do is to separate the code we wrote from what's coming form node_modules, writting this config:

 optimization: {
    moduleIds: "deterministic",
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          chunks: "all",
        },
        styles: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          type: "css/mini-extract",
          chunks: "all",
          enforce: true,
        },
      },
    },
  },

This way, in addition to what you would have normally, you get vendors.js and vendors.css for what's coming from node_modules. See Code Splitting on Webpack's official documentation to learn more.

  • Related