Home > OS >  Create individual css <links> using MiniCssExtractPlugin for each css import inside JavaScript
Create individual css <links> using MiniCssExtractPlugin for each css import inside JavaScript

Time:07-06

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 JS

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. Though 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 know more about it.

  • Related