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 ですが、より明確にすることを望んでいました。
このファイルが何をするのか、なぜ含まれているのか知りたいのですが。つまり、この宣言ファイルを含めないと、アプリを「破壊」するために何をしなければならないでしょうか。
ありがとう!
最初のファイルは、IDEが.vue
で終わるファイルが何であるかを理解するのに役立ちます
2番目のファイルでは、.tsx
ファイルを使用しながら、IDEでjsx
syntaxsupportを有効にして、JSXスタイルのTypeScriptコードを記述できます。
このリンク は、私が見つけた唯一のまともな説明でした。基本的にそれは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
のエイリアスを取得するだけです。これはテストで迷惑です! これに関する別の質問 を作成しました。