Integrate Sass & React (create-react-app)

Bootstrapping your app with create-react-app? Super-charge it with Sass to make theming a cinch. Bonus — includes Foundation integration too!

Often I bootstrap my React projects with create-react-app. Just about every-time, I find myself Googling how to integrate Sass (scss). To save time, I’ve followed the advice of Sara Soueidan’s Just write. and jotted it down as reference. Bonus — includes Foundation integration as well!

  1. Install a starter app: $ npx create-react-app [app name]
  2. Eject the build scripts: $ npm run eject
  3. Install & configure Sass loaders: $ npm i -D sass-loader node-sass
  4. Optional — Install & configure Foundation: $ npm i -D foundation-sites

Configure Sass Loaders

After you’ve installed sass-loader and node-sass, you’ll need to configure the webpack.config.dev.js and webpack.config.prod.js files in the config folder. First, add the Sass loaders:

          autoprefixer({
            browsers: [
              '>1%',
              'last 4 versions',
              'Firefox ESR',
              'not ie < 9', // React doesn't support IE8 anyway
            ],
            flexbox: 'no-2009',
          }),
        ],
      },
    },
  ],
},
// Process scss with Sass
{
  test: /\.scss$/,
  loaders: [
    require.resolve( 'style-loader' ),
    require.resolve( 'css-loader' ),
    require.resolve( 'sass-loader' )
  ]
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you 'import' an asset, you get its (virtual) filename. In

Next, add /\.scss$/, to the exclude array right after the loaders.

// SCSS Loaders
{
  test: /\.scss$/,
  loaders: [
    require.resolve( 'style-loader' ),
    require.resolve( 'css-loader' ),
    require.resolve( 'sass-loader' )
  ]
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you 'import' an asset, you get its (virtual) filename. In
// production, they would get copied to the 'build' folder. This
// loader doesn't use a 'test' so it will catch all modules that fall
// through the other loaders.
{
  // Exclude 'js' files to keep 'css' loader working as it injects
  // its runtime that would otherwise processed though 'file' loader.
  // Also esclude 'html' and 'json' extensions so they get processed
  // by webpacks internal loaders.
  exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/, /\.svg$/, /\.scss$/],
  loader: require.resolve( 'file-loader' ),
  options: {
    name: 'static/media/[name].[hash:8].[ext]',
  },
},

Configure Foundation

I recommend importing your base Foundation styles (reset, typography, etc) in the root component of your app. Individual component styles like off-canvas, menus, accordions, etc. should be loaded by the React component that needs it — unless you plan on using some of those component styles globally. For example, here’s the global stylesheet:

@import 'settings';
@import '~foundation-sites/scss/foundation';

// Global styles
@include foundation-global-styles;
@include foundation-typography;
@include foundation-xy-grid-classes;

If you have a accordion component for instance, you’ll import a separate scss file for it and include the Foundation styles for it like so:

@import './../../styles/settings';
@import '~foundation-sites/scss/foundation';

@include foundation-accordion;

Author: Ben Marshall

Red Bull Addict, Self-Proclaimed Grill Master, Entrepreneur, Workaholic, Front End Engineer, SEO/SM Strategist, Web Developer, Blogger

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.