URL: https://www.progressiverobot.com/vuejs-components-flow/

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

flow illustration for: 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.

				
					
[label 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`))

				
			
				
					
[label ExampleComponent.vue]

&lt;template&gt;

  &lt;p&gt;I'm made with Flow!&lt;/p&gt;

&lt;/template&gt;



&lt;script&gt;

/* @flow */



const randomThing: string = 'Boop!'



export default {

  created() {

    console.log(randomThing)

  }

}

&lt;/script&gt;

				
			

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!