Skip to content

Using Sass With Synergy

esr360 edited this page Feb 13, 2020 · 12 revisions

Synergy by default uses JavaScript to handle a module's styles (learn more). You can alternatively use Sass for styling your modules.

Synergy uses Cell for styling modules with Sass

Checkout Synergy-Boilerplate-Sass for a minimal working demo

Setup

Using Sass with Synergy requires Synergy-Sass-Importer in the build pipeline. Synergy comes with Cell as a dependency, which comes with Synergy-Sass-Importer as a dependency, which means it does not need to be installed separatly. Simply pass Synergy-Sass-Importer as an importer in your Sass's configuration.

Using Webpack

// ES6 Imports
import SassJSONImporter from '@onenexus/synergy-sass-importer';

// OR CommonJS
const SassJSONImporter = require('@onenexus/synergy-sass-importer');

export default function() {
  return {
    ...
  
    module: { 
      rules: [ 
        {
          test: /\.scss$/,
          use: [
            {
              loader: 'sass-loader', 
              options: {
                sassOptions: {
                  importer: SynergySassImporter
                }
              }
            }
          ]
        }
      ]
    },
  
    ...
  }
}

.sassrc.js

Useful if using something like Parcel.js

const SassJSONImporter = require('@onenexus/synergy-sass-importer');

module.exports = {
  importer: SynergySassImporter
}

Importing Sass Files Into Modules

The best way to inject your Module's Sass styles into your app is by importing the Module's Sass file into your Module's main JSX/JS/index file, ensuring you have an appropriate loader (e.g. Webpack's Sass Loader).

See the Creating a Module page of the Cell wiki for more information on how to use Cell

Example
/modules/Accordion/index.jsx
import './layout.scss';

...
/modules/Accordion/config.js

Learn more about using JavaScript/JSON for configuration

export default (theme) => ({
  'name': 'accordion',
  ...
});
/modules/Accordion/layout.scss

You must import the Cell library into the Module's Sass file

Ensure your Sass compiler is setup to use Synergy-Sass-Importer

@import '~@onenexus/cell/dist/cell';
@import 'config.js';

@include module {
  ...
}

Tip: Checkout thesass-resource-loader package if you want to avoid having to import Cell into every module's Sass file

Importing Theme Into layout.scss

If your project has a theme, and your Module's configuration uses the theme (as shown above), then you must also import the theme into your Module's Sass file (e.g. /modules/Accordion/layout.scss) (learn more) before importing its corresponding config file:

@import '~@onenexus/cell/dist/cell';
@import '../../themes/myTheme.js';
@import 'config.js';

@include module {
  ...
}

Tip: Checkout thesass-resource-loader package if you want to avoid having to import the theme into every module's Sass file

Single App Sass file

Alternatively, you can go a bit more old-school and have a single .css file for your app, which will require a corresponding app.scss file or equivalent thereof.

Taking an Accordion module as an example, the project may resemble the following (note the app.scss file):

|-- modules
|   |-- Accordion
|   |   |-- index.jsx
|   |   |-- config.js
|   |   |-- layout.scss
|-- app.scss

Import all required Modules' corresponding Sass files:

This method allows you to only import the Cell library once

app.scss
@import '~@onenexus/cell/dist/cell';
@import '/modules/Accordion/layout';
...
Import app.scss Into Your App

Ensure you have the correct Sass/Scss loaders setup

import './app.scss';
...

Global Variables Via Webpack

You can set globals variables in Sass during compile time through Node via Webpack.

webpack.config.babel.js
import { default as SassJSONImporter, transformJStoSass } from '@onenexus/synergy-sass-importer';

export default function() {
  return {
    ...
  
    module: { 
      loaders: [ 
        {
          test: /\.scss$/,
          use: [
            ...
            {
              loader: 'sass-loader', 
              options: {
                prependData: transformJStoSass({
                  someProperty: 'someValue',
                  someObject: {
                    someNestedProperty: 42
                  }
                }),
                sassOptions: {
                  importer: SynergySassImporter
                }
              }
            }
          ]
        }
      ]
    },

    ...
  }
}

...now within your Sass:

@debug $someProperty; // 'someValue'
@debug map-get($someObject, 'someNestedProperty'); // 42