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!