web-dev-qa-db-ja.com

Vue-TypeScriptプロジェクトでshims-tsx.d.tsファイルは何をしますか?

TypeScriptでVueプロジェクトを作成すると、2つの宣言ファイルが含まれます:shims-vue.d.tsおよびshims.tsx.d.ts.

//shims-vue.d.ts

declare module "*.vue" {
  import Vue from 'vue';
  export default Vue;
}

そして:

//shims-tsx.d.ts

import Vue, { VNode } from 'vue';

declare global {
  namespace JSX {
    // tslint:disable no-empty-interface
    interface Element extends VNode {}
    // tslint:disable no-empty-interface
    interface ElementClass extends Vue {}
    interface IntrinsicElements {
      [elem: string]: any;
    }
  }
}

小さなプロジェクト(Vue CLIなし)の作成中)に2番目のプロジェクト(shims.tsx.d.ts)を含めるのを忘れたため、プロジェクトが(エラーなしで)期待どおりにコンパイルおよび実行されます。

私はそれについてこの投稿を見つけました: https://github.com/vuejs/vue-cli/issues/1198 ですが、より明確にすることを望んでいました。

このファイルが何をするのか、なぜ含まれているのか知りたいのですが。つまり、この宣言ファイルを含めないと、アプリを「破壊」するために何をしなければならないでしょうか。

ありがとう!

19
Brandon

最初のファイルは、IDEが.vueで終わるファイルが何であるかを理解するのに役立ちます

2番目のファイルでは、.tsxファイルを使用しながら、IDEでjsx syntaxsupportを有効にして、JSXスタイルのTypeScriptコードを記述できます。

20
Ohgodwhy

このリンク は、私が見つけた唯一のまともな説明でした。基本的にそれはWebpackで行うことです。

Webpackを使用していない場合-TypeScriptのみを使用している場合、次のようなことはエラーになります。

import Foo from "./Foo.vue";

明らかにTypeScriptは.vueファイルを理解しないため、これらは実際にはTypeScriptモジュールではありません。

ただし、Vueプロジェクトを設定すると、常にそれが機能することがわかります。それはどのように機能しますか?Webpack!私が知る限り(狂気を避けようとしました)これは基本的にWebpackの仕事です-Javascript/TypeScriptのすべてのimportファイルを調べ、それらを「バンドル」します。つまり、それらを1つのファイルにマージします。

しかし、特定のファイル形式を処理するために追加できる「ローダー」(ひどい名前)で拡張可能です。たとえば、CSSローダーを使用するように構成できます。それはそれが見つけたとき

import "./foo.css"

CSSを出力にバンドルし、おそらく実行時にDOMに挿入するためのJavascriptを追加するか、そのようなナンセンスなものを追加します。

とにかく、それらをバンドルする*.vueファイルのローダーもあると思います。これがimport Foo from "./Foo.vue"が機能する理由です。なぜshimファイルが必要なのですか?

TypeScriptはまだ満足していないからです。 Webpackについて何も認識していないため、Foo.vueをインポートしようとすると、エラーがスローされます(Can't find module "./Foo.vue"が表示されます)。

解決策はshims-vue.d.tsです。ファイル名が.d.tsで終わる限り、ファイル名は重要ではないようです。 TypeScriptは同じディレクトリまたはそのような場所ですべての.d.tsを探すと思います。

いずれの場合でも、内容は次のとおりです。

declare module "*.vue" {
  import Vue from 'vue';
  export default Vue;
}

つまり、「*.vueという名前のモジュールをインポートするたびに(ワイルドカードがサポートされています)、実際には実行せず、代わりにこれらのコンテンツがあるかのように扱います」という意味です。

これは私にとってはどのように動作するようです:import Foo from "./Foo.vue"を実行すると、FooのタイプはVueになります。 Fooタイプを実際にインポートする方法がないようです。

編集:実際に私はそれが動作すると思います*別の.vueファイルにコンポーネントをインポートする場合。 .tsからインポートする場合は、Vueのエイリアスを取得するだけです。これはテストで迷惑です! これに関する別の質問 を作成しました。

2
Timmmm