Tutorial

Writing Vue.js Components with Flow

Vue.js

While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.

Type checking is a tricky concept in Vue. While it’s easy to do in plain script files, Vue single-file components are a much trickier beast to get working. While some choose TypeScript, perhaps for class-based components, others find TypeScript’s heavyweight nature and difficulty to integrate with common tools to not be worth the effort. Facebook’s Flow is a typechecker that fits much better into a standard webpack + babel + eslint toolchain, and is commonly used in React projects. Once you get it set up, it just works!

Getting Flow to work with Vue is a bit tricky as it involves several dependencies and minor configuration tweaks to make them all work properly together, so let’s start out by installing those first.

Installation

Starting from vue-cli’s webpack-simple template, there are nine extra dependencies to install. Here’s what each of them does:

Babel:

  • babel-plugin-syntax-flow - Adds support for flow syntax in Babel.
  • babel-plugin-transform-class-properties - Adds support for class properties and static methods
  • babel-plugin-transform-flow-strip-types - Removes type annotations from source files before transpiling with Babel.

Eslint: (optional)

  • eslint - Eslint. It’s pretty much the de-facto linter for JS, with integrations for a variety of editors and IDEs as well. If you’re not using this now, you’ll want to start using it.
  • babel-eslint - Patches Eslint to use Babel’s parser for parsing source files.
  • eslint-plugin-html - Allows Eslint to handle HTML files. (ie. Only lints stuff inside script tags.)
  • eslint-plugin-flowtype-errors - Passes flow errors through Eslint, and to your editor’s eslint plugin if you have one.
  • eslint-plugin-vue - Opinionated utilities for Eslint with Vue.
  • eslint-config-vue - Opinionated config for Eslint with Vue.

Flow:

  • flow-bin - The Flow typechecker.

Install via Yarn or NPM:

# Yarn
$ yarn add \
  babel-plugin-syntax-flow \
  babel-plugin-transform-class-properties \
  babel-plugin-transform-flow-strip-types \
  eslint \
  babel-eslint \
  eslint-plugin-html \
  eslint-plugin-flowtype-errors \
  eslint-plugin-vue \
  eslint-config-vue \
  flow-bin \
-D

# NPM
$ npm install \
  babel-plugin-syntax-flow \
  babel-plugin-transform-class-properties \
  babel-plugin-transform-flow-strip-types \
  eslint \
  babel-eslint \
  eslint-plugin-html \
  eslint-plugin-flowtype-errors \
  eslint-plugin-vue \
  eslint-config-vue \
  flow-bin \
--save-dev

Configuration

.babelrc

Add the babel plugins to the end of your .babelrc file.

{
  ...
  "plugins": [
    "babel-plugin-transform-class-properties",
    "babel-plugin-syntax-flow",
    "babel-plugin-transform-flow-strip-types"
  ]
}

.eslintrc

Set up your .eslintrc file like so:

{
  "parser": "babel-eslint",

  "plugins": [
    "html",
    "flowtype-errors"
  ],

  "extends": [
    "vue"
  ],

  "rules": {
    "flowtype-errors/show-errors": 2
  }
}

.flowconfig

And finally, create a .flowconfig file in your project root directory. It can be empty, just make sure it’s present.

Usage

You can now use Flow in your .js files or .vue single-file components just by adding the /* @flow */ annotation to the top of each file or script section.

Assuming your editor or IDE has the proper eslint packages installed, you should now have real-time error checking and positional annotations whenever there is an error or warning.

stupid-file.js
/* @flow */

const doSomethingStupid(stringArg) {
  // Flow should show an error here, "The operand of an arithmetic operation must be a number."
  return stringArg * 3109;
}

console.log(doSomethingStupid(`I'm stringy`))
ExampleComponent.vue
<template>
  <p>I'm made with Flow!</p>
</template>

<script>
/* @flow */

const randomThing: string = 'Boop!'

export default {
  created() {
    console.log(randomThing)
  }
}
</script>

And there you have it! Nothing else in your toolchain has to change.

There’s plenty more to learn about Flow. If you’re not familiar with it already, a great next step would be the Flow Docs. Enjoy!

Creative Commons License