How to get Flow to properly work with Vue 2 (webpack)?
babeljs, flowtype, vue.js, vuejs2, webpack
Solution
You can still use Flow for the JS portion of a .vue component, by commenting out the `<template>`, `<style>` and `<script>` portions:
/* @flow
<style>
...style definitions here
</style>
<template>
...html...
</template>
*/
// <script>
export default {
methods: {
flowIt (a: number): number {
return a * 10
}
},
mounted: function () {
this.flowIt(20)
this.flowIt('bah') //Won't throw error, as flowIt is attached to
//this.
}
}
// </script>
The vue compiler will still recognize the `<template>, <style> and <script>` sections even when commented, but the Flow type checker will ignore them and only process the proper javascript section.
Unfortunately, this won't get you 100% type coverage, as Flow will not be able to check functions and objects attached to `this` (the Vue component itself), however, you can still benefit from Flow's type checking of calls out to external functions (e.g. Vuex actions and getters, other javascript imported modules), and if you have extended business logic within the component's methods, you can get some type safety when working with the method parameters.
Problem
I'm trying to add Flow to the Vue 2 webpack-template. For the record, I'm on runtime-only (files follow the `.vue` format / standard). My first attempt was to use flow through the cli, which I realized it's not going to work because it didn't know how to handle `.vue` files. My second attempt was to add a webpack loader (namely flow-status-webpack-plugin) and run Flow check as part of the build (like `eslint` works for example). That didn't work out, so I looked into other options. My third attempt was to use a babel plugin, which was fairly successful at first. I used babel-plugin-typecheck + babel-plugin-syntax-flow. There's no output in Webpack, however a type error would break the app. I'm fine with this approach; it'll work fine with a CI and break the build. Here's how my `.babelrc` looked: ``` { ... "plugins": [ ... ["typecheck", { "disable": { "production": true } }], "syntax-flow", "transform-flow-strip-types" ], ... } ``` At this point, Flow works as expected for global methods, but doesn't work inside a Vue component: ``` <template>...</template> <script> /* @flow */ const flowIt = (a: number): number => { return a * 10 } flowIt(20) flowIt('bah') // Uncaught TypeError: Value of argument "a" violates contract. Expected: number Got: string export default { mounted: function () { flowIt(20) flowIt('bah') // Sees nothing wrong here } } </script> <style>...</style> ``` On top of that, the goal is to not change the app code because of Flow. Ideally, I'd just use Vue as normally: ``` <template>...</template> <script> /* @flow */ export default { methods: { flowIt (a: number): number { return a * 10 } }, mounted: function () { this.flowIt(20) this.flowIt('bah') // Should throw a type error. } } </script> <style>...</style> ``` Not sure if this has that much to do with Vue as it has with my experience with Flow (hint: not that experienced). I'm thinking I need some type files that make Flow 'understand' how a Vue component is structured (same for directives I guess). To those that have more experience with it, how did you get Flow to properly work with Vue + webpack?