简体   繁体   English

shims-tsx.d.ts 文件在 Vue-Typescript 项目中有什么作用?

[英]What does the shims-tsx.d.ts file do in a Vue-Typescript project?

When creating a Vue project with typescript, two declaration files are included: shims-vue.d.ts and shims.tsx.d.ts .使用typescript创建 Vue 项目时,包含两个声明文件: shims-vue.d.tsshims.tsx.d.ts

//shims-vue.d.ts

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

And:和:

//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;
    }
  }
}

While creating a small project (without the Vue CLI) I forgot to include the second (shims.tsx.d.ts) and my project compiles and runs as expected (without error).在创建一个小项目(没有 Vue CLI)时,我忘记包含第二个(shims.tsx.d.ts),我的项目按预期编译和运行(没有错误)。

I found this post about it: https://github.com/vuejs/vue-cli/issues/1198 , but was hoping for more clarification.我发现了这篇关于它的帖子: https : //github.com/vuejs/vue-cli/issues/1198 ,但希望得到更多说明。

I am just curious what this file does and why it is included?我只是好奇这个文件的作用以及为什么包含它? In other words, what I would have to do to "break" my app if I don't include this declaration file.换句话说,如果我不包含此声明文件,我将必须做什么才能“破坏”我的应用程序。

Thanks!谢谢!

The first file helps your IDE to understand what a file ending in .vue is第一个文件帮助您的 IDE 了解以.vue结尾的文件是什么

The second file allows you to use .tsx files while enabling jsx syntaxsupport in your IDE to write JSX-style typescript code.第二个文件允许您使用.tsx文件,同时在 IDE 中启用jsx语法支持以编写 JSX 样式的打字稿代码。

This link was the only decent explanation I could find.这个链接是我能找到的唯一体面的解释。 Basically it is to do with Webpack.基本上它与Webpack有关。

If you aren't using Webpack - you're only using Typescript, then doing something like this is an error:如果你没有使用 Webpack - 你只使用 Typescript,那么做这样的事情是一个错误:

import Foo from "./Foo.vue";

Because obviously Typescript doesn't understand .vue files - they aren't actually Typescript modules.因为显然 Typescript 不理解.vue文件 - 它们实际上不是 Typescript 模块。

However, if you set up a Vue project you'll find that it does it all the time.但是,如果您设置了一个 Vue 项目,您会发现它一直都在这样做。 How does that work?这是如何运作的? Webpack!网络包! As far as I can tell (I have tried to avoid insanity by learning anything at all about webpack), this is basically Webpack's job - it goes through all of the import files in your Javascript/Typescript, and "bundles" them, ie it merges them into one file.据我所知(我试图通过学习有关 webpack 的任何东西来避免精神错乱),这基本上是 Webpack 的工作 - 它遍历您的 Javascript/Typescript 中的所有import文件,并“捆绑”它们,即它将它们合并为一个文件。

But it extensible with "loaders" (terrible name) that can be added to handle particular file formats.但是它可以通过“加载程序”(可怕的名称)进行扩展,可以添加它来处理特定的文件格式。 For example you can configure it to use a CSS loader.例如,您可以将其配置为使用 CSS 加载器。 That means when it finds这意味着当它找到

import "./foo.css"

It will bundle the CSS into the output, and probably add some Javascript to insert it into the DOM at runtime, or some nonsense like that.它会将 CSS 捆绑到输出中,并且可能会添加一些 Javascript 以在运行时将其插入到 DOM 中,或者诸如此类的一些废话。

Anyway, there's also (I presume) a loader for *.vue files that handles bundling those.无论如何,还有(我假设)一个用于处理捆绑这些文件的*.vue文件的加载器。 So that's why import Foo from "./Foo.vue" works.所以这就是为什么import Foo from "./Foo.vue"起作用的原因。 Why do we need the shim file?为什么我们需要 shim 文件?

Because Typescript still isn't happy.因为打字稿仍然不高兴。 It doesn't know anything about Webpack, so it will still throw an error when you try and import Foo.vue (it'll tell you Can't find module "./Foo.vue" ).它对 Webpack 一无所知,因此当您尝试导入Foo.vue时它仍然会抛出错误(它会告诉您Can't find module "./Foo.vue" )。

The solution is shims-vue.d.ts .解决方案是shims-vue.d.ts The filename does not seem to be important, as long as it ends with .d.ts .文件名似乎并不重要,只要以.d.ts结尾.d.ts I guess Typescript looks for all .d.ts in the same directory or something like that.我猜 Typescript 在同一目录或类似目录中查找所有.d.ts

In any case, the contents are this:无论如何,内容是这样的:

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

Which basically means, "every time you import a module with the name *.vue (wildcards are supported), then don't actually do it - instead treat it as if it had these contents".这基本上意味着,“每次你导入一个名为*.vue的模块(支持通配符),然后实际上不要这样做 - 而是将其视为具有这些内容”。

This is how it seems to behave for me: If you do import Foo from "./Foo.vue" then the type of Foo will by Vue .这对我来说似乎是这样的:如果你确实import Foo from "./Foo.vue"那么Foo的类型将由Vue There does not seem to be a way to actually import the Foo type.似乎没有办法实际导入Foo类型。

Edit: Actually I think it works *if you import the component in another .vue file.编辑:实际上我认为它有效*如果你在另一个.vue文件中导入组件。 If you import it from .ts then you just get an alias for Vue .如果您从.ts导入它,那么您只会获得Vue的别名。 This is annoying in tests!这在测试中很烦人! I made another question about this .我对此提出了另一个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM