Alex Ironside
Alex Ironside

Reputation: 5049

Extracting sass as css using webpack

First. I know questions like this were asked, but I am missing something to understand them. I am trying to compile scss to css. And I would like webpack to basically do the same as sass app.scss : app.css. I tried to configure it using extract-text-webpack-plugin, but I am doing something wrong or missing smth.

It worked if I include(app.scss) in app.js but this makes no sense because if anyone has disabled JavaScript the styles won't work.

This is my webpack.config.js file. I have no idea how to do it.

const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
var jsConfig = {
  entry: "./_dev/scripts/app.js",
  output: { filename: "./scripts/bundle.js" },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
    ]
  }
};

var scssConfig = {
  entry: "./_dev/scss/app.scss",
  output: { filename: "./content/app.css" },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin({filename:"./_dev/scss/app.scss"}),
  ]
};

var config = [scssConfig, jsConfig];

module.exports = config;

Edit: I also found this. This series would have helped with all my questions so if you have similar questions make sure to read it before asking!

https://codeburst.io/simple-beginner-guide-for-webpack-2-0-from-scratch-part-v-495dba627718

Upvotes: 1

Views: 1210

Answers (1)

margaretkru
margaretkru

Reputation: 2781

You need to include your app.scss for webpack to be able to find your scss references because webpack will traverse your project and apply loaders to all files it can find through references starting from app.js recursively down. If you don't have references to app.scss somewhere in the project webpack can't find it and it won't build it. So in the entry of you project (assume it is app.js) you need to do this:

import 'relative/path/to/styles/app.scss';

But it doesn't mean that those who don't have js enabled won't receive your styles. You need to include app.scss only for the build phase of your project, after that your styles will be included in html and will be loaded even for those without js enabled.

webpack concepts section explains how webpack finds dependencies based on your entry point building its internal graph of dependencies.


Update:

There is a way that allows you to not add your app.scss in your js. You can include multiple files in your entry object in your webpack config. Here is an example of how configuration might look in your case:

const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
var config = {
  entry: {
     main: [
        "./_dev/scripts/app.js", 
        "./_dev/scss/app.scss"
     ],
  },
  output: { 
    path: './scripts',
    filename:  "bundle.js" 
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test: /\.(css|scss)/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: ['css-loader', 'sass-loader']
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("./_dev/scss/app.scss"),
  ]
};

module.exports = config;

More information available on SO question webpack-multiple-entry-points-sass-and-js.

You also have incorrect configuration of ExtractTextPlugin in webpack. You are placing the whole path in the option for filename, which is not correct. In your case it should look like this:

plugins: [
    new ExtractTextPlugin("./_dev/scss/app.css"),
  ]

Upvotes: 5

Related Questions