stylesheets

Johannes Ewald edited this page Nov 21, 2016 · 19 revisions

Embedded Stylesheets

By using style-loader and css-loader it's possible to embed stylesheets into a Webpack JavaScript bundle. This way you can modularize your stylesheets with your other modules, so stylesheets are as easy as require("./stylesheet.css").

Installation

Install the loaders from npm.

npm install style-loader css-loader --save-dev

Configuration

Here is a configuration example that enables require() CSS:

{
    // ...
    module: {
        loaders: [
            { test: /\.css$/, loader: "style-loader!css-loader" }
        ]
    }
}

For compile-to-css languages see the corresponding loaders for configuration examples. You can pipe them...

Keep in mind that it's difficult to manage the execution order of modules, so design your stylesheets so that order doesn't matter. (You can, however, rely on the order within a given CSS file.)

Using CSS

// in your modules just require the stylesheet
// This has the side effect that a <style>-tag is added to the DOM.
require("css!./stylesheet.css");

Separate CSS Bundle

In combination with the extract-text-webpack-plugin it's possible to generate a native CSS output file.

With Code Splitting we can use two different modes:

  • Create one css file per initial chunk (see Code Splitting) and embed stylesheets into additional chunks. (recommended)
  • Create one css file per initial chunk which also contains styles from additional chunks.

The first mode is recommended because it's optimal in regards to initial page loading time. In small apps with multiple entry points the second mode could be better because of HTTP request overheads and caching.

Plugin Installation

Install the plugin from npm.

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

General

To use the plugin you need to flag modules that should be moved into the css file with a special loader. After the compilation in the optimizing phase of webpack the plugin checks which modules are relevant for extraction (in the first mode only these that are in an initial chunk). These modules are compiled for node.js usage and executed to get the content. Additionally the modules are recompiled in the original bundle and replaced with an empty module.

A new asset is created for the extracted modules.

Styles from Initial Chunks into Separate CSS Output File

This examples shows multiple entry points, but also works with a single entry point.

// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
    // The standard entry point and output config
    entry: {
        posts: "./posts",
        post: "./post",
        about: "./about"
    },
    output: {
        filename: "[name].js",
        chunkFilename: "[id].js"
    },
    module: {
        loaders: [
            // Extract css files
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            },
            // Optionally extract less files
            // or any other compile-to-css language
            {
                test: /\.less$/,
                loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
            }
            // You could also use other loaders the same way. I. e. the autoprefixer-loader
        ]
    },
    // Use the plugin to specify the resulting filename (and add needed behavior to the compiler)
    plugins: [
        new ExtractTextPlugin("[name].css")
    ]
}

You'll get these output files:

  • posts.js posts.css
  • post.js post.css
  • about.js about.css
  • Additional files required with require.ensure contain embedded styles

or with allChunks: true

  • Additional files required with require.ensure don't contain embedded styles

Styles in Commons Chunk

You can use a separate CSS file in combination with the CommonsChunkPlugin. In this case a CSS file for the commons chunk is emitted too.

// ...
module.exports = {
    // ...
    plugins: [
        new webpack.optimize.CommonsChunkPlugin("commons", "commons.js"),
        new ExtractTextPlugin("[name].css")
    ]
}

You'll get these output files:

  • commons.js commons.css
  • posts.js posts.css
  • post.js post.css
  • about.js about.css
  • 1.js 2.js (contain embedded styles)

or with allChunks: true

  • Additional files required with require.ensure don't contain embedded styles