webpack sass-loader not generating a css file
Asked Answered
E

3

40

I can't figure out how to render a css file with the webpack sass-loader.

Here's what my webpackconfig.js looks like:

module.exports = {
  context: __dirname + "/app",
  entry: {
    javascript: "./app.js",
    html: "./index.html"
  },


  output: {
    filename: "app.js",
    path: __dirname + "/dist"
  },


  module: {
    loaders: [
      //JAVASCRIPT
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: ["babel-loader"],
      },

      //Index HMTML
      {
        test: /\.html$/,
        loader: "file?name=[name].[ext]",
      },
      //Hotloader
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: ["react-hot", "babel-loader"],
      },

      // SASS
      {
        test: /\.scss$/,
        loader: 'style!css!sass'
      }

    ],
  }

}

As you can see I'm using the sass-loader module loader specified in the documentation.

  {
    test: /\.scss$/,
    loader: 'style!css!sass'
  }

My root looks as such:

Project Root:
  app:
    style.scss
  dist:
   ?????? WTF is my css file??
  webpack.config.js

I can get everything else working such as html and jsx babble loaders. I just type in webpack into the command line and things happen.

I'm doing something wrong with the sass loader. What is it? Please help.

Emporium answered 25/8, 2015 at 18:16 Comment(0)
P
59

You are using the style-loader, which, by default, embeds your CSS in Javascript and injects it at runtime.

If you want real CSS files instead of CSS embedded in your Javascript, you should use the ExtractTextPlugin.

A basic config would be:

  1. Add var ExtractTextPlugin = require('extract-text-webpack-plugin'); to the top of your Webpack config file.

  2. Add the following to your Webpack config:

    plugins: [
        new ExtractTextPlugin('[name].css'),
    ]
    
  3. Change your SASS loader config to the following:

    {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract(
            'style-loader', // backup loader when not building .css file
            'css-loader!sass-loader' // loaders to preprocess CSS
        )
    }
    

What this does is extract all CSS it can find in your bundle to a separate file. The name will be based on your entrypoint name, which in your case will result in javascript.css (from the entry part of your config).

The ExtractTextPlugin.extract-loader is used by the plugin to find the CSS in your code and put it in separate files. The first parameter you give it is the loader it should fall back to if it encounters files in an async module, for example. Generally this is pretty much always style-loader. The second parameter tells the plugin what loaders to use to process the CSS, in this case css-loader and sass-loader, but things like postcss-loader are often used too.

More info on building your CSS with Webpack can be found here: https://webpack.github.io/docs/stylesheets.html#separate-css-bundle

Puiia answered 26/8, 2015 at 10:9 Comment(5)
you saved a large portion of my hair :)Neophyte
The above is a valid approach, but I'd add a note which I was missing even though I used the above way: webpack won't pick up your styles until you add require("./stylesheet.css") to your module (JS file). It may be obvious (and is mentioned in docs), but for Webpack beginners it's not.Sumpter
@Sumpter Or use html-webpack-plugin. :)Facial
@Sumpter its funny, I get an error when I try to do that: ERROR in ./scripts/app.js Module not found: Error: Cannot resolve 'file' or 'directory' ./app.css ...Satang
the extract extract-text-webpack-plugin now requires you to explicitly give the names of the loader. ie. extract(css-loader|sass-loader)Granth
M
0

Using TypeScript and coming across similar issue, I discovered that the 'scss' file import should be in the index file that Webpack is starting at.

Import in index.ts rather than in an inner module.

Madame answered 17/10, 2016 at 23:47 Comment(0)
C
0

If you simply want to output a regular CSS file and not inject it by a script tag, one good option would be to use the MiniCssExtractPlugin. First you need to install it:

# Using your package manager of choice
yarn add --dev mini-css-extract-plugin

And then initialize the plugin and use that instead of style-loader:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [
      {
        test: /\.scss$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
    ],
  },
};
Charolettecharon answered 29/1 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.