Flow をVue 2 webpack-templateに追加しようとしています。記録のために、私はランタイムのみを使用しています(ファイルは.vue
形式/標準に従います) )。
私の最初の試みは、CLIを介したフローを使用することでしたが、.vue
ファイルの処理方法がわからなかったため、動作しないことに気付きました。
私の2番目の試みは、webpackローダー(つまり flow-status-webpack-plugin )を追加し、ビルドの一部としてフローチェックを実行することでした(たとえば、eslint
は機能します)。それはうまくいかなかったので、私は他のオプションを調べました。
私の3番目の試みは、最初はかなり成功したbabelプラグインを使用することでした。 babel-plugin-typecheck + babel-plugin-syntax-flow を使用しました。 Webpackには出力はありませんが、タイプエラーが発生するとアプリが破損します。私はこのアプローチで大丈夫です。 CIで正常に動作し、ビルドを中断します。
.babelrc
の外観は次のとおりです。
{
...
"plugins": [
...
["typecheck", {
"disable": {
"production": true
}
}],
"syntax-flow",
"transform-flow-strip-types"
],
...
}
この時点で、フローはグローバルメソッドで期待どおりに機能しますが、Vueコンポーネント:
<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>
その上、目標はフローのためにアプリコードを変更しないことです。理想的には、通常どおりVueを使用します:
<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>
これが私のFlowの経験と同じようにVueと関係があるかどうかはわかりません(ヒント:それほど経験はありません)。Flow 'を理解させるタイプのファイルが必要だと思います。 'Vueコンポーネントの構造(私が推測するディレクティブについても同じ)。
それをより経験している人にとって、FlowをVue + webpackで適切に動作させるにはどうすればよいですか?
<template>
、<style>
、および<script>
の部分をコメントアウトすることで、.vueコンポーネントのJS部分にフローを引き続き使用できます。
/* @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>
vueコンパイラはコメントされた場合でも<template>, <style> and <script>
セクションを認識しますが、フロータイプチェッカーはそれらを無視し、適切なjavascriptセクションのみを処理します。
残念ながら、Flowはthis
(Vueコンポーネント自体)にアタッチされた関数とオブジェクトをチェックできないため、これでは100%の型カバレッジは得られません。 Flowの外部関数(Vuexアクションとゲッター、その他のjavascriptインポートモジュールなど)への呼び出しの型チェックを引き続き利用できます。また、コンポーネントのメソッド内にビジネスロジックを拡張している場合は、メソッドを操作するときに型の安全性を確保できます。パラメーター。
これは、フローとビューを統合するためのさらに別のアプローチです。その間、flow
はeslint
に来ました。したがって、フローエラーをリントエラーとして直接取得できます。これはよりクリーンなアプローチですが、フローはビルドプロセスと結合されます(flow check
を個別に実行することはできませんが、エラーを取得するには、ビルドパイプライン全体をwebpack経由で実行する必要があります)。 2017年5月10日現在、.vue
ファイルでフルフローをサポートするために この問題 が解決されるのをまだ待っています。
ほとんどの場合、これで問題ありませんが、flow check
を実行する際の柔軟性(および速度)が必要な場合もあります。これは、CIの設定にも依存する可能性があります。
フローとエスリントを設定する方法は次のとおりです。
Depsをインストールする
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
.babelrc
を構成します
{
...
"plugins": [
"babel-plugin-transform-class-properties",
"babel-plugin-syntax-flow",
"babel-plugin-transform-flow-strip-types"
]
}
.eslintrc
を構成します
{
"parser": "babel-eslint",
"plugins": [
"html",
"flowtype-errors"
],
"extends": [
"vue"
],
"rules": {
"flowtype-errors/show-errors": 2
}
}
.flowconfig
ファイルを作成します。構成するものがない場合は、空にすることができます。
この場合、他の回避策は必要ありません。その後、任意の/* @flow */
ファイルのスクリプトタグで.vue
を使用できます。元の投稿を参照してください ここ 。
Nikの答え に加えて、彼の「コメント」戦略をランタイムチェッカーと組み合わせると、「パッケージ」が少し完全になることに言及する価値があります。これを行う1つの方法は、 babel-plugin-tcomb を使用することです。これにより、ランタイムチェッカーがwebpack /ビルドプロセス(保存時)の一部になり、CIスクリプトの一部としてflow check
になります。
開発の場合、tcombはランタイムチェックを実行し、例外(コンソール)をスローします。静的チェックを行わないため、次のようになります。
<script>
/* @flow */
const flowIt = (a: number): number => {
return '' // Sees nothing wrong here, should be a number
}
// Vue component
export default {
...
}
</script>
期待どおりに動作しません。ただし、次のようになります。
<template>{{ foo('bar') }} <!-- Type error --></template>
<script>
/* @flow */
const flowIt = (a: number): number => {
return '' // Type error
}
// Vue component
export default {
methods: {
foo: (x) => { flowIt(x) // Type error }
},
mounted: () => {
flowIt([]) // Type error
}
}
</script>
これは理想的ではありませんが、保存するたびにチェックが行われ、ほとんどのタイプエラーが検出されます。言及する価値がある:tcombは同じアノテーションを使用する(内部でFlowを使用する)ので、箱から出してすぐに機能します。
多くの場合、それは十分ではなく、フローのポイントをやや打ち負かします。これに対する解決策は、前述のように、CIでflow check
を実行することです。これには多くの変更が必要です。
.flowconfigを更新して.vueファイルをロードします。
...
[options]
module.file_ext=.vue
module.file_ext=.js
...
@flowプラグマを含むコメントにテンプレートとスタイルブロックを含めます。スクリプトタグをコメントアウトします(このアプローチについては ここ ):
/* @flow
<template>...</template>
<style>...</style>
*/
// <script>
...
// </script>
それは少し厄介ですが、私はより良い方法を見つけることができませんでした。理想的には、FlowはHTMLドキュメント内の<script>
タグを処理できますが、それは今のところウィッシュリストにあります( 問題を参照 )。
本番環境でtcombを無効にする
{
...
"plugins": [
...
"syntax-flow",
"transform-flow-strip-types"
],
"env": {
"development": {
"plugins": ["tcomb"]
}
}
}
これは当面は解決されたと思います。今では、ハッキングなしでVueコンポーネントでFlowを使用できます。構成の詳細については、このかなり素晴らしい記事を参照してください: https://alligator.io/vuejs/components-flow/
vue
のプロジェクトテンプレートをflow
で実装しました。 https://github.com/wemake-services/wemake-vue-template 単一ファイルコンポーネント、リンティング、jest
によるテスト、ビルド、サーバーサイドレンダリングをサポートします。
コンポーネントは次のようになります。
<template>
...
</template>
<script>
// @flow
import Vue from 'vue'
import { Store } from 'vuex'
import Component from 'nuxt-class-component'
import { Getter, State } from 'vuex-class'
import AppLogo from '~/components/AppLogo'
import Comment from '~/components/Comment'
import type { CommentType, StateType } from '~/types'
@Component({
components: {
AppLogo,
Comment
}
})
export default class Index extends Vue {
@State('comments') comments: Array<CommentType>
@Getter('hasComments') hasComments: boolean
fetch (
{ store, app }: { store: Store<StateType>, app: Vue }
): Promise<Array<CommentType>> {
// Uncomment the next line to test flow types:
// console.log(this.comments + 12)
return store.dispatch('fetchComments', app)
}
}
</script>
構成するにはいくつかのことが必要です。
flow
が含まれるすべて: https://github.com/wemake-services/wemake-vue-template/blob/master/template/package.json.flowconfig
を作成しています。これは難しいかもしれません: https://github.com/wemake-services/wemake-vue-template/blob/master/template/.flowconfig.babelrc
の構成: https://github.com/wemake-services/wemake-vue-template/blob/master/template/.babelrceslint
の構成: https://github.com/wemake-services/wemake-vue-template/blob/master/template/.eslintrcflow-typed install
をトリガーする: https://github.com/wemake-services/wemake-vue-template/blob/master/template/package.json#L12vuex
store:state、commitハンドラー、getter、およびアクションに注釈を付けることもできます。この部分には @vue-flow-typed/vuex
を使用できます。
それはそれがどのように見えるかです:
type StateType = {
comments: string[]
}
function state (): StateType {
return {
comments: null
}
}
const getters = {
hasComments (state: StateType): boolean {
return Boolean(state.comments && state.comments.length > 0)
}
}
const mutations = {
'SET_COMMENTS': (
state: StateType, comments: string[]
) => {
state.comments = comments
}
}
const actions = {
async fetchComments (
{ commit, state }: ActionContext<StateType>
) {
const data = await Promise.resolve(['good', 'Nice'])
commit('SET_COMMENTS', data)
// Uncomment next line to see typing in action:
// console.log(state.comments, state.fake)
return data
}
}
ただし、一部の部分に注釈を付けることはまだ不可能であることに注意してください。既知の問題の詳細については、こちらをご覧ください: https://github.com/sobolevn/vue-flow-typed#known-problems