Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebPack how to put all css files into one css file

I am fairly new to WebPack, and I want to be able to take a directory of CSS files (.app/styles/[css files...]) and output them into one CSS file (dist/styles.css).

Currently, all the JavaScript files is compiled into one single "index_bundle.js" file, which is perfect, but I want to achieve the same for my CSS files.

After a lot of "Googling", I found that the ExtractTextPlugin for WebPack should be able to help with this, but this only works for one CSS file that is added to the "entry" property (eg: entry: {style: "./app/styles/style.css"}) which is then added to the html's head as a link tag, which is fine, but I want all my css files to go into one styles.css file and then use that in the html's head as a link.

My current WebPack config looks like this:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ExtractTextPluginConfig = new ExtractTextPlugin(
    "styles.css", 
    {
        allChunks: false
    }
);

module.exports = {
    entry: {
        index: "./app/index.js"//,
        //styles: "./app/styles/style1.css" // I don't want one file, I want to use a directory eg: "./app/styles/"
    },
    output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader'
            },
            { 
                test: /\.css$/, 
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            }
        ]
    },
    plugins: [
        HtmlWebpackPluginConfig,
        ExtractTextPluginConfig
    ]
}

Can someone please point me in the right direction? Even if it is another plugin or a different approach. Any help will be greatly appreciated!

EDIT: My new WebPack config looks like this:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ExtractTextPluginConfig = new ExtractTextPlugin(
    "index_bundle.css"
);

module.exports = {
    entry: [
        './app/index.js',
        './app/index.css'
    ],
    output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
    },
    module: {
        preloaders: [
            {
                test: /\.css/,
                exclude: /styles/, 
                loader: 'import-glob-loader'
            }
        ],
        loaders: [
            {
                test: /\.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader'
            },
            { 
                test: /styles\.css$/, 
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            },
            { 
                test: /\.json$/, 
                loader: 'json' 
            }
        ]
    },
    devServer: {
        historyApiFallback: true
    },
    plugins: [
        HtmlWebpackPluginConfig,
        ExtractTextPluginConfig
    ]
}
like image 878
Fred Avatar asked Nov 01 '16 08:11

Fred


People also ask

How do I import all CSS files into one CSS file?

Note: There are two different ways to import a CSS file into another using @import url(“style2. css”); or @import “style2. css”; or directly import any CSS file or multiple CSS file in the HTML file directly within <style>@import “style1. css”; or .

How do I bundle a CSS file in webpack?

By default, Webpack will inline your CSS as Javascript tags that injects the CSS into the page. This sounds strange but it lets you do hot reloading in development. In production you extract them to a file using the ExtractTextPlugin, and require it with a normal link tag.

How do I combine CSS files?

To combine external CSS files, you can simply copy / paste all of your CSS code into one main file. Therefore all of the content from within the other CSS files will now reside within the main file allowing the browser to only make one request for a CSS file instead of multiple.

Does webpack compile CSS?

style-loader converts it to JavaScript and implements webpack's Hot Module Replacement interface. Webpack supports a large variety of formats compiling to CSS through loaders. These include Sass, Less, and Stylus.


1 Answers

Ok, so it seems to have been a camel-case problem.

With the help of Davin Tryon, I was able to resolve my issue - thanks!

If you look at: https://www.npmjs.com/package/import-glob-loader they have the following:

preloaders: [{
    test: /\.scss/,
    loader: 'import-glob-loader'
}]

It should be:

preLoaders: [{
    test: /\.scss/,
    loader: 'import-glob-loader'
}]

So in the end, my whole webpack.config.json looks like this:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ExtractTextPluginConfig = new ExtractTextPlugin(
    "index_bundle.css"
);

module.exports = {
    entry: [
        './app/index.js',
        './app/index.css'
    ],
    output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
    },
    module: {
        preLoaders: [
            {
                test: /\.css$/,
                exclude: /styles/, 
                loader: 'import-glob-loader'
            }
        ],
        loaders: [
            {
                test: /\.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader'
            },
            { 
                test: /\.css$/, 
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            },
            { 
                test: /\.json$/, 
                loader: 'json' 
            }
        ]
    },
    devServer: {
        historyApiFallback: true
    },
    plugins: [
        HtmlWebpackPluginConfig,
        ExtractTextPluginConfig
    ]
}

And my index.css file looks like this:

@import './styles/**/*';

This is working for me and I get a single css output file "index_bundle.css". The style and scripts also automatically gets injected into the html template.

index.html before injection:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Admin - Login</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css"/>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

index.html after injection in /dist folder:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Admin - Login</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css"/>
    <link href="index_bundle.css" rel="stylesheet"></head>
    <body>
        <div id="app"></div>
    <script type="text/javascript" src="index_bundle.js"></script></body>
</html>
like image 69
Fred Avatar answered Oct 19 '22 07:10

Fred