Vue-Typescript项目中的shims-tsx.d.ts文件是做什么的?

时间:2019-02-11 00:40:39

标签: typescript vue.js

使用打字稿创建Vue项目时,会包含两个声明文件: 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)时,我忘记包含第二个项目(shims.tsx.d.ts),并且我的项目可以编译并按预期运行(没有错误)。

我发现了有关此帖子: https://github.com/vuejs/vue-cli/issues/1198,但希望得到更多说明。

我很好奇这个文件的作用以及为什么包含它?换句话说,如果我不包括此声明文件,我将不得不“破坏”我的应用程序。

谢谢!

2 个答案:

答案 0 :(得分:25)

This link是我能找到的唯一体面的解释。基本上,这与Webpack有关。

如果您不使用Webpack,而仅使用Typescript,则执行类似的操作会出错:

import Foo from "./Foo.vue";

因为显然Typescript无法理解.vue文件-它们实际上不是Typescript模块。

但是,如果您设置了Vue项目,则会发现它一直都在执行。这是如何运作的? Webpack!据我所知(我试图通过学习有关webpack的任何知识来避免精神错乱),这基本上是Webpack的工作-它遍历Javascript / Typescript中的所有import文件和“捆绑包”它们,即它将它们合并到一个文件中。

但是它可以用“加载器”(可怕的名称)扩展,可以添加以处理特定的文件格式。例如,您可以将其配置为使用CSS加载器。这意味着当它找到

import "./foo.css"

它将CSS捆绑到输出中,并可能添加一些Javascript在运行时将其插入DOM中,或者像这样废话。

无论如何,(我认为)还有*.vue个文件的加载程序,用于处理这些文件。这就是import Foo from "./Foo.vue"起作用的原因。为什么我们需要填充文件?

因为打字稿仍然不满意。它对Webpack一无所知,因此当您尝试导入Foo.vue(它会告诉您Can't find module "./Foo.vue")时,它仍然会引发错误。

解决方案是shims-vue.d.ts。只要文件名以.d.ts结尾,文件名似乎并不重要。我猜打字稿会在同一目录或类似目录中寻找所有.d.ts

无论如何,内容是这样的:

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

这基本上意味着:“每次导入名称为*.vue(支持通配符)的模块时,实际上就不要这样做-而是将其视为具有这些内容”。

这对我来说似乎是这样:如果您执行import Foo from "./Foo.vue",则Foo的类型将为Vue。似乎没有一种实际上导入Foo类型的方法。

编辑:实际上,如果您将组件导入另一个.vue文件中,则我认为它可以工作。如果从.ts导入,则只会得到Vue的别名。这在测试中很烦人!我做了another question about this

答案 1 :(得分:7)

第一个文件可帮助您的IDE了解以.vue结尾的文件是什么

第二个文件允许您使用.tsx文件,同时在IDE中启用jsx sytnax支持以编写JSX样式的打字稿代码。