9

I've switched from including stylesheets the oldschool way:

<link rel="stylesheet" href="./../css/main.css">

to Webpack approach:

var css = require('./../css/main.css');

It works, but I don't like that it extracts the css from this file into inline tag, because then it's harder to debug it in Dev Tools. For example I have no idea from which file and line these attributes are coming from:
enter image description here

How can I move it to separate file or generate a source map that would point me to the source file? So when I inspect it Dev Tools it will look like this:

enter image description here

My webpack.config.js:

var autoprefixer = require('autoprefixer');

module.exports = {
    devtool: "css-loader?sourceMap",
    module:  {
        loaders: [
            {test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000'},
            {
                test:   /\.css$/,
                loader: "style-loader!css-loader!postcss-loader"
            }
        ]
    },
    entry:   [
        './static/js/app.js'
    ],
    output:  {
        filename: './static/js/bundle.js'
    },
    watch:   false,
    postcss: function () {
        return [autoprefixer];
    }
};

My app.js:

var $ = require('jquery');
window.jQuery = $;
window.$ = $;
require('bootstrap-loader');

module.exports = (function () {
    alert('IT WORKS!');
});

window.app = module.exports;
var css = require('./../css/main.css');
van_folmert
  • 4,257
  • 10
  • 44
  • 89

1 Answers1

3

To extract your styles from your bundle to an external stylesheet you need to use extract text plugin.

The general webpack config looks like this:

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

module.exports = {
    devtool: "source-map",
    entry: 'path/to/entry.js',
    output:  {
        path: 'path/to/bundle'
        filename: 'bundle.js'
    },
    module:  {
        loaders: [
            {
                test:   /\.css$/,
                loader: ExtracTextPlugin.extract('css-loader?sourceMap')
            }
        ]
    },
    plugins: [
         new ExtractTextPlugin('styles.css')
    ]
};

The parts that you should notice are using devtool: "source-map" for the debugging part and that with the plugin you provide the loader as the parameter to extract method of the plugin:

loaders: [
    {
        test:   /\.css$/,
        loader: ExtracTextPlugin.extract('css-loader?sourceMap')
    }
]

Here you can also chain loaders if you need for example sass-loader too:

loaders: [
    {
        test:   /\.scss$/,
        loader: ExtracTextPlugin.extract('css-loader?sourceMap!sass-loader?sourceMap')
    }
]

You don't need the style-loader anymore but you can also provide it as a fallback loader to the plugin:

loaders: [
    { 
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({
            fallbackLoader: "style-loader",
            loader: "css-loader?sourceMap"
        })
    }
]

and in your plugins array you instantiate the plugin and provide the name you want for the external stylesheet:

plugins: [
     new ExtractTextPlugin('styles.css')
]

You can also use [name] placeholder if you have multiple entry points and you will have a stylesheet per entry.

jal
  • 1,100
  • 1
  • 8
  • 17
  • 1
    Thanks, the file is generated, but now I still have to include this `styles.css` into template by `` tag? – van_folmert Nov 18 '16 at 13:59
  • This mapping doesn't make sense - it points to scss file, but the file generated by ExtractTextPlugin, not the real source file. So if I would bundle 2 scss together the mapping would point to the bundle, instead of 1 of those 2 files. – van_folmert Nov 18 '16 at 14:21
  • My bad, I was extracting into scss, instead css. But still [I cannot get those mappings right](http://stackoverflow.com/questions/40680721/extracttextplugin-no-scss-mapping-in-main-css-map). – van_folmert Nov 18 '16 at 15:29
  • @van_folmert: As you already noticed you have to use sourceMap queries on loaders themselves too. About the first question you can use the [html webpack plugin](https://github.com/ampedandwired/html-webpack-plugin) to generate an html file based on a template and insert your bundles automatically in it on every build. – jal Nov 18 '16 at 17:13
  • plugins: [ new HtmlWebpackPlugin({ template: 'src/index.html' }), new ExtractTextPlugin('styles.css') ] – jal Nov 18 '16 at 17:14