rollup-plugin-typescript2: Importing Vue SFC from `lang="ts"` block

While switching from rollup-plugin-typescript to rollup-plugin-typescript2 in order to produce declaration files, the *.vue files are not recognized anymore.

[!] (rpt2 plugin) Error: someFolder/index.ts(2,53): semantic error TS2307 Cannot find module './component.vue'.
src\index.ts
Error: someFolder/index.ts(2,53): semantic error TS2307 Cannot find module './component.vue'.

Trying by just importing rollup-plugin-typescript instead of rollup-plugin-typescript2 bundles without a problem.

This could be bound to this issue though I have the last version (of every plugin today indeed).

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 1
  • Comments: 18 (9 by maintainers)

Most upvoted comments

It works for me with this setup, to compile a single vue component:

Right, but that’s not a real use case. That’s hello world. For anyone having trouble understanding the problem, here’s what I’ve gleaned.

rollup literally can’t do this

why? here’s an example:

<script lang="ts">
import Bar from './Bar.vue';
// ...
</script>
  1. vue plugin passes script over to typescript plugin
  2. typescript plugin encounters a .vue file, but has no way of knowing what to do with it because rollup doesn’t provide a mechanism for plugins to defer to other plugins on imports like webpack. Regular JS can defer to plugins, but code already being processed by a plugin cannot.
  3. I actually don’t understand why this is different than lang=scss or lang=ts, but it is I guess.

Well, what can I do?

Not much.

But vuetify! buefy!

Vuetify is typescript, but doesn’t use SFCs. It’s pure render functions.

Buefy uses SFCs and rollup, but no typescript.

Really though, there’s nothing I can do?

You aren’t going to like it. For every Vue file you need to import from a typescript file, you’ll have to create a regular javascript file intermediary.

import Bar from './Bar.vue';

export default Bar;

Then and only then will you be able to build your typescript SFC component lib with rollup.

geez, that sucks

If you’ve come up with a better solution, I’d love to hear it.

Hello.

First of all thank you very much for working on this plugin. It does indeed make much more sense than rollup-plugin-typescript.

I can confirm that this issue exists and setup a small demo repository: https://github.com/danimoh/rollup-plugin-typescript2-vue-demo

If you commment out the line import AnotherComponent from './AnotherComponent.vue'; it does compile, but unfortunately not with this line enabled.

It’s funny that we encountered this issue around the same time. Maybe it was caused by a recent change? A guess from my side with very limited knowledge about rollup, rollup plugins and typescript would be: Is it possible that typescript itself is trying to import AnotherComponent instead of rollup or rollup-plugin-vue handling that import first?

That would explain why rollup-plugin-typescript does not have this issue as it compiles on a per file basis with transpileModule.

In this case, the following might be interesting: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#customizing-module-resolution

Any work on this issue is very much appreciated.

Reproduced on both repos, not sure if it is the same problem yet, but it is likely.

To fix second case we do indeed need to send module resolution back to rollup so that vue plugin can do it’s thing.

Problem with hooking up rollup’s module resolution and typescript is that rollup in later versions returns a Promise from context.resolveId(...). So the call chain looks like this:

  • rollup calls plugin’s transform
  • plugin calls typescript’s LanguageService.getEmitOutput
  • language service calls plugin’s implementation of LanguageHost.resolveModuleNames and expects resolved paths to be returned in that function
  • host calls rollup’s PluginContext.resolveId
  • rollup returns a Promise
  • if I understand correctly, all I can do with a promise is to make another promise

LanguageService seems to be strictly synchronous: https://github.com/Microsoft/TypeScript/issues/1857

Plugin.transform can itself return a Promise, but the mechanics of chaining multiple promises made deep inside callbacks on an observer object elude me at the moment.

Or a small repo with reproduction 😃