# Frontend languages and technologies

# TypeScript

Our TypeScript is compiled by Babel, using the @vue/babel-preset-app as a base configuration and a corresponding TypeScript plugin for Vue CLI. You can update this configuration in babel.config.js and tsconfig.json.

# Vue

Since Vue is such a huge part of our app, it is recommended reading through at least the Essentials of Vue's guide.

# Vue Router

To understand how to manage pages with Vue Router, reading through the Essentials of those docs is recommended. See also routing in this application.

# Apollo (state management)

Both apollo-client and vue-apollo are included for state management through GraphQL. Have a look first at Apollo Client introduction and then at Vue Apollo integration docs.

Read about state management in this application.

# CSS

For our styles, we're using SCSS and CSS modules, which you can activate by adding the lang="scss" and module attributes to style tags in Vue components:

<style lang="scss" module>
  /* Styles go here */
</style>

# SCSS

SCSS is a superset of CSS, meaning any valid CSS is also valid SCSS. This allows you to easily copy properties from other sources, without having to reformat it. It also means you can stick to writing the CSS you're still comfortable with while you're learning to use more advanced SCSS features.

I specifically recommend reading about:

Just those features cover at least 95% of use cases.

# Importing global modules

To import files from node_modules using aliases, Webpack's css-loader requires adding ~ to the beginning of a module name to denote that it's an global (not relative) file reference. For example:

@import '~font-awesome/scss/font-awesome';

# Design variables and tooling

All our variables, placeholder classes, mixins, and other design tooling are in the src/design folder. The result is aliased as @design for convenience and can be imported into SCSS using:

@import '@design';
// Access $size-sm, etc.

This makes all our design variables available in your component or SCSS file.

NOTE: The src/design folder should never contain code that compiles to actual CSS, as that CSS would be duplicated across every component the file is imported into. This type of code should be placed in Vue components directly.

# CSS modules

As mentioned earlier, every Vue component should be a CSS module. That means the classes you define are not actually classes. When you write:

<style lang="scss" module>
  .inputLabel {
    /* ... */
  }

  .input {
    /* ... */
  }
</style>

You're actually defining values on a $style property of the Vue instance such as:

$style: {
  inputLabel: 'base-input_inputLabel__3EAebB_0',
  input: 'base-input_input__3EAebB_1'
}

These values contain automatically generated classes with:

  • the file name of the component
  • the name of the class
  • a random hash

Do you know what that means?! You can never accidentally write styles that interfere with another component. You also don't have to come up with clever class names, unique across the entire project. You can use class names like .input, .container, .checkbox, or whatever else makes sense within the isolated scope of the component - just like you would with JavaScript variables.

# Sharing SCSS variables with JavaScript

If you ever need to expose the value of an SCSS variable to your JavaScript, you can with CSS module exports! For example, assuming you have this variable defined:

$size-grid-padding: 1.3rem;

You could import our design tooling, then use CSS modules' :export it:

<style lang="scss" module>
  @import '@design';

  :export {
    // stylelint-disable-next-line
    grid-padding: $size-grid-padding;
  }
</style>

Then you can access the value using this.$style['grid-padding'].

If you need access from outside a Vue component (e.g. in a Vuex module), you can do so in src/design/index.scss. See that file for specific instructions. Our src/main.js consumes variables in this way.

# Global CSS

Typically, only src/app.vue should ever contain global CSS and even that should only include base element styles and utility classes (e.g. for grid management). A handful of global classes are created here for convenience.

# CSS FAQ

Why use SCSS instead of plain CSS or another CSS preprocessor?

CSS preprocessors offer a lot of additional power - just having a browser-independent way to use variables is invaluable. But SCSS has some other advantages over competing preprocessors:

  • SCSS it a superset of CSS, which means:
    • You can copy and paste valid CSS into SCSS and it will always be valid.
    • There's a gentler learning curve, as devs can write the same CSS they're used to, gradually incorporating more SCSS features as they're needed.
  • It's well-supported by both Stylelint and Prettier, eliminating nearly all arguments over code style.
Last updated: 6/26/2020, 9:59:26 AM