Webpack: Merge Multiple CSS Into Single File

August 10, 2017
Using ExtractTextPlugin, can merge Sass and Less as well.

Note: Webpack might not be the best tool for this purpose, but it can be done ;)

Make sure webpack is installed and setup.

By default, webpack will bundle and embed CSS into the javascript file.

Merge CSS

The best way to merge CSS files into one independent CSS file is to use extract-text-webpack-plugin.

npm install --save-dev extract-text-webpack-plugin

Edit webpack.config.js to include setup the plugin.

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    'bundle.min.css': [
      path.resolve(__dirname, 'src/css/main.css'),
      path.resolve(__dirname, 'src/css/local.css')
    ],
    'bundle.js': [
      path.resolve(__dirname, 'src/index.js')
    ]
  },
  output: {
    filename: '[name]',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader'
        })
      },
    ],
  },
  plugins: [
    new ExtractTextPlugin("bundle.min.css"),
  ]
}; 

The generated dist/bundle.min.css is pure css file combining src/css/main.css and src/css/local.css.

# npm run build
./node_modules/.bin/webpack
# build for production (with minified)
./node_modules/.bin/webpack -p

Merge Sass and Less

You can combine .css, .less and .sass into a single CSS output.

Install Sass and Less loaders.

npm install --save-dev sass-loader node-sass
npm install --save-dev less-loader less

Edit webpack.config.js to setup the loaders.

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    'bundle.min.css': [
      path.resolve(__dirname, 'src/css/main.css'),
      path.resolve(__dirname, 'src/css/local.css'),
      path.resolve(__dirname, 'src/css/test.less'),
      path.resolve(__dirname, 'src/css/test.sass'),
    ],
    'bundle.js': [
      path.resolve(__dirname, 'src/index.js')
    ]
  },
  output: {
    filename: '[name]',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader'
        })
      },
      {
        test: /\.sass$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader']
        })
      },
      {
        test: /\.less$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'less-loader']
        })
      }
    ],
  },
  plugins: [
    new ExtractTextPlugin("bundle.min.css"),
  ]
};

Build.

./node_modules/.bin/webpack

Directory structure.

├── dist
│   ├── bundle.js
│   ├── bundle.min.css
│   └── index.html
├── package.json
├── src
│   ├── css
│   │   ├── local.css
│   │   ├── main.css
│   │   ├── test.less
│   │   └── test.sass
│   └── index.js
└── webpack.config.js

NOTE: Refer to webpack configuration to combine Bootstrap dependencies into single js and css file.

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.