Reactgo: How to implement SASS?

Created on 22 Feb 2017  路  10Comments  路  Source: reactGo/reactGo

Question

First off I want to say thanks for creating this great boilerplate. I'm a big fan of SASS and I find it's better for my purposes than style solutions. Can anyone let me know how to implement it into this project? I've tried but I'm not that great with webpack. Thanks a lot

question

All 10 comments

You can use sass-loader instead of postcss-loader. Or, even you can use postcss-loader with sass-loader.
Look at the flux/alt branch of this repository. This used to use sass quite a long ago.

Did you try adding "sass-loader" to line 46ish of the webpack/rules/css.js file? )After the postcss-loader object) After installing the dependency of course. You might run into issues with the server compilation though...

Yea I tried, doesn't seem to work. I think it'll require a lot more work to use sass.

Try this:

npm install isomorphic-style-loader sass-loader node-sass --save-dev

Add this to the webpack/rules/index.js add as an item in the exported array.

   {
      test: /\.scss$/,
      use: [
        browser ? "style-loader" : "isomorphic-style-loader",
        browser ? "css-loader" : "css-loader/locals",
        "sass-loader"
      ]
    }

Add '.scss' to the webpack/resolve.js extensions....

Then import a .scss file in one of your components.

Thanks that works, but it causes a brief FOUC on production. Do you have any idea why this is?

yeah because it's not being extracted... I just ran into this today myself... I'm testing a fix ATM for a related issue I'm having as well. here is what I'm trying right now (for my thing..) .

{
      test: /\.css$/,
      use: production && browser ?
      ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: 'css-loader'
      }) : [
        browser ? 'style-loader' : 'isomorphic-style-loader',
        browser ? 'css-loader' : 'css-loader/locals'
      ],
      include: PATHS.modules + '/material-grid/'
    }

I'm using this to include a css file from a module but the same principle should apply. You'll need to use the extract text plugin in some way with your SCSS files so that they are pulled into the assets/styles/main.css when you do your build. I'm not using SCSS myself but I'm sure there is a way.

@gittestcoder did you fix this?

@nicomfe sorry for the late reply, yes I was able to fix it. Below is my full css.js file:

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PATHS = require('../paths');

module.exports = ({ production = false, browser = false } = {}) => {
  /*
   * modules: boolean - Enable/Disable CSS Modules
   * importLoaders: number - Number of loaders applied before CSS loader
   *
   * Read more about css-loader options
   * https://webpack.js.org/loaders/css-loader/#options
   *
   * For server-side rendering we use css-loader/locals as we do not want to
   * embed CSS. However, we still require the mappings to insert as className in
   * our views.
   *
   * Referenced from: https://github.com/webpack-contrib/css-loader#css-scope
   *
   * For prerendering with extract-text-webpack-plugin you should use
   * css-loader/locals instead of style-loader!css-loader in the prerendering bundle.
   * It doesn't embed CSS but only exports the identifier mappings.
   */
  const localIdentName = '[name]__[local]___[hash:base64:5]';

  const createCssLoaders = embedCssInBundle => ([

    {
      loader: 'css-loader',      
      options: {
        localIdentName,
        sourceMap: !production,
        minimize: true,
        importLoaders: 1
      }
    },
    {
      loader: "sass-loader"
    }
  ]);

  const createBrowserLoaders = extractCssToFile => loaders => {
    if (extractCssToFile) {
      return ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: loaders
      });
    }
    return [{ loader: 'style-loader' }, ...loaders];
  };

  const serverLoaders = createCssLoaders(false);
  const browserLoaders = createBrowserLoaders(production)(createCssLoaders(true));

  return {
    test: /\.s?css$/,
    use: browser ? browserLoaders : serverLoaders,  
    include: PATHS.app
  }
};

Before seeing this thread, I also overhauled my ReactGo to use scss instead of less. It works perfectly, except I get the aforementioned FOUC on production.

I tried implementing the snippet from @gittestcoder, but it causes an issue with relative paths (image assets cannot be resolved).

Below is my css.js config. Any ideas as to how I fix the FOUC issue?

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PATHS = require('../paths');

module.exports = ({production, browser}) => {
  /*
   * modules: boolean - Enable/Disable CSS Modules
   * importLoaders: number - Number of loaders applied before CSS loader
   *
   * Read more about css-loader options
   * https://webpack.js.org/loaders/css-loader/#options
   *
   * For server-side rendering we use css-loader/locals as we do not want to
   * embed CSS. However, we still require the mappings to insert as className in
   * our views.
   *
   * Referenced from: https://github.com/webpack-contrib/css-loader#css-scope
   *
   * For prerendering with extract-text-webpack-plugin you should use
   * css-loader/locals instead of style-loader!css-loader in the prerendering bundle.
   * It doesn't embed CSS but only exports the identifier mappings.
   */
  const localIdentName = 'localIdentName=[name]__[local]___[hash:base64:5]';

  const createCssLoaders = embedCssInBundle => ([
    {
      loader: embedCssInBundle ? 'css-loader' : 'css-loader/locals',
      options: embedCssInBundle ? {
        localIdentName,
        modules: true,
        sourceMap: true
      } : {}
    },{
      loader: 'sass-loader',
      options: {
        sourceMap: true
      }
    }
  ]);

  const createBrowserLoaders = extractCssToFile => loaders => {
    if (extractCssToFile) {
      return ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: loaders
      });
    }
    return [{ loader: 'style-loader' }, ...loaders];
  };

  const serverLoaders = createCssLoaders(false);
  const browserLoaders = createBrowserLoaders(production)(createCssLoaders(true));
  return {
    test: /\.(css|scss)$/,
    use: browser ? browserLoaders : serverLoaders,
    include: PATHS.app
  };
};

@emmya I see that you dont have the importLoaders options applied. You might need to add it.
Also, please check that once you perform a production build you have all needed css files extracted and created correctly in the build folder.
If not, please check that you're correctly calling the css.js file with production since the browser build should use ExtractTextPlugin
Moreover, ensure that you're using ExtractTextPlugin in the plugins section of the production build

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jrodl3r picture jrodl3r  路  7Comments

evansteelepdx picture evansteelepdx  路  3Comments

kenjim83 picture kenjim83  路  8Comments

ZeroCho picture ZeroCho  路  8Comments

choonkending picture choonkending  路  8Comments