Sunday, 12 March, 2017 UTC


Summary

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!