14

Here is my folder structure:

enter image description here

I want to minify and bundle the CSS files inside my src/css folder and output it as a single CSS file inside dist. All the examples I've seen so far recommend require-ing the CSS file inside a JS file. I do not want that. Is there a way to configure in webpack.config.js to just minify and copy these files?

Saravana
  • 37,852
  • 18
  • 100
  • 108

2 Answers2

5

Got it working.

Install dev-dependecies

npm i extract-text-webpack-plugin --save-dev
npm i css-loader --save-dev

webpack.config.js

const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const extractCSS = new ExtractTextPlugin('bundle.min.css')

module.exports = {
  entry: {
    'bundle.min.css': [
      __dirname + '/src/styles/abc.css',
      __dirname + '/src/styles/xyz.css',
      __dirname + '/src/styles/mno.css'
    ]
  },
  devtool: '',
  output: {
    path: __dirname + '/dist/styles/',
    filename: '[name]'

  },
  module: {
    rules: [{
        test: /\.css$/i,
        use: extractCSS.extract({
          use: {
            loader: 'css-loader',
            options: {
              minimize: true
            }
          }
        })
    }]
  },
  resolve: {
    alias: {},
    modules: [],
    extensions: ['.css']
  },
  plugins: [
    extractCSS
  ]
};

bundle.min.css will get generated. Based on minimize: true/false, minification will be decided. Enjoy!

softvar
  • 17,917
  • 12
  • 55
  • 76
  • Is it necessary to specify all css files in the entry? – Bonomi Mar 10 '18 at 17:28
  • Yea, because one css file won't include another. So one has to write it manually. In case of JS files, one entry point is needed and all other js files which are imported are automatically gets bundled. Visualize the graph of the imported statements and you will understand. – softvar Mar 10 '18 at 19:32
  • 2
    extract-text-webpack-plugin is now deprecated – kojow7 Aug 21 '19 at 15:45
1

It will go in three steps;

first you will need two loaders and plugin; named css-loader and style-loader and extract-text-webpack-plugin respectively.

Then your config might look like following:

const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const path = require('path');
module.exports = {
  entry: {
    app: './src/index.js'
  },
  output: {
    path: 'dist',
    filename: 'js/[name]-bundle.js'
  },
  devtool: "cheap-source-map",
  resolveLoader: {
    modules: [
      'node_modules',
      path.join(__dirname, '../node_modules'),
    ]
  },
  module: {
    loaders: [
      {
        test: /.css?$/,
        loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }),
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("css/[name].css"),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        screw_ie8: true,
        conditionals: true,
        unused: true,
        comparisons: true,
        sequences: true,
        dead_code: true,
        evaluate: true,
        join_vars: true,
        if_return: true
      },
      output: {
        comments: false
      }
    }),
  ]
}

And then in your entry file, require them like require('./style.css');

Remember, it will follow the paths as your source.

If you are loading font files and images in you css, you might need the file-loader plugin as well which will copy all assets in directory.

The file-loader config will look like:

{
    test: /.png?$/,
    loader: 'file-loader?name=img/[name].[ext]',
    exclude: /node_modules/
}

The UgligyJsPlugin will also minify the CSS.

Pankaj
  • 954
  • 8
  • 15
  • Is there a way to do this without `require`-ing the CSS from JS file? That feels very odd. – Saravana Mar 16 '17 at 14:10
  • CSS would not be added in JS file, it is just a require, which means that JS app depends on CSS files. This config is straight form one of my applications. – Pankaj Mar 16 '17 at 14:11