With the rise of large single page applications, Javascript and CSS have become increasingly intertwined. It’s often the case that values are copied between the two (for example, animation durations for use with React’s CSSTransitionGroup or passing brand colors into a graphing library). However, maintaining two copies of the same value inevitably leads to updating only one and ending up with a frustrating bug. Luckily, with webpack and CSS modules, there is a better way. In this blog post, we’ll explore how to share a variable between your scripts and your styles with the aforementioned example of sharing an animation duration for a CSSTransitionGroup.

The first step is to install our dependencies:

npm install sass-loader node-sass webpack --save-dev

Next, we need to configure webpack to use sass-loader so we can access our Sass code from Javascript.

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  }
}

Now for the interesting part. We define the actual variable value in Sass and export it to Javascript. CSS Modules have a neat utility called :export. The :export directive works basically like ES6’s export keyword. Your Sass code will export an object containing the variable name to use in Javascript and its associated value. These values are all exported as strings.

// styles/animation.scss
$animation-length: 250;
$animation-length-ms: $animation-length + 0ms;

:export {
  animationMillis: $animation-length-ms;
}

.component-enter {
  ...

  transition: all $animation-length-ms ease-in;
}

You’ll notice that we first declare the integer value in one variable, and then add 0ms to it in other. This allows us to export only "250" rather than "250ms" which is a little easier to parse on the Javascript side (adding 0ms to the number coerces its “type” into ms).

Now, in Javascript, we just need to import the styles from the stylesheet, and parse an int out of the variable we exported!

// js/animation.js
import styles from '../styles/animation.scss'
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup'

const millis = parseInt(styles.animationMillis)

...

<CSSTransitionGroup
  transitionName="component"
  transitionEnterTimeout={millis}
  transitionLeaveTimeout={millis}
/>

...

This method is incredibly easy, but it will pay off in spades when you avoid the headache of syncing changes between Javascript and Sass.

Want more coding tutorials for all your DevOps needs? Sign up for our newsletter now. (We respect your privacy, and you will only be signed up to the blog post updates list. Email frequency: once/month.)

Mark Siebert

Author Bio

Mark is a full-stack engineer who cut his teeth on professional software development at Lucid Software where he specialized in building scalable backend systems. He's a huge fan of open source software and is one of the primary authors of Relate (database access library) and Cumulus (AWS infrastructure management). Mark loves watching shows with his wife, studying Chinese, and hunting Minecraft chickens.