ts-loader
ts-loader copied to clipboard
Unable to load default and exported from vue templates
Expected Behaviour
I expect to import default and exported interfaces from ts file/portion. It was working on ts-loader 8.x with webpack 4.x and it's failing on ts-loader 9.x with webpack 5.x.
It even works on ts-loader 8.x using webpack 5.x (not recommended since I believe it's not designed for).
Actual Behaviour
Typescript return the error TS2614 when trying to do an import like import HelloWorld, { HelloProp } from './components/HelloWorld.vue';
See the full output:
(ts-loader-9)$ ./node_modules/.bin/webpack
assets by status 53.1 KiB [cached] 1 asset
orphan modules 416 KiB [orphan] 15 modules
runtime modules 500 bytes 2 modules
./src/main.ts + 14 modules 415 KiB [built] [code generated]
ERROR in /Users/juanbasso/tmp/webpack5/hello-world-no-class/src/App.vue.ts
3:21-30
[tsl] ERROR in /Users/juanbasso/tmp/webpack5/hello-world-no-class/src/App.vue.ts(3,22)
TS2614: Module '"*.vue"' has no exported member 'HelloProp'. Did you mean to use 'import HelloProp from "*.vue"' instead?
ts-loader-default_0c5a263502dc9404
webpack 5.48.0 compiled with 1 error in 5039 ms
Steps to Reproduce the Problem
I created a sample to reproduce the working and not working versions:
- ✅ ts-loader 8.x with webpack 4.x: https://github.com/jrbasso/ts-loader-import-bug/tree/ts-loader-8
- ✅ ts-loader 8.x with webpack 5.x: https://github.com/jrbasso/ts-loader-import-bug/tree/ts-loader-8-webpack5
- ✖️ ts-loader 9.x with webpack 5.x: https://github.com/jrbasso/ts-loader-import-bug/tree/ts-loader-9
To reproduce, simply checkout the branch and run npm ci && ./node_modules/.bin/webpack
Location of a Minimal Repository that Demonstrates the Issue.
See steps to reproduce.
@jrbasso, I don't use Vue but I took a look at your ts-loader-9 repo. I saw the same error message you report.
TypeScript is complaining that Module '"*.vue"' has no exported member 'HelloProp'
, which is true, the definition of *.vue in shims-due.d.ts does not include HelloProp. If you include HelloProp as an export in the *.vue module as below the error disappears:
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
export interface HelloProp {
title: string,
caption: string
}
}
I appreciate this may not be a generic solution to this issue. The thread below discusses this error when importing interfaces from Vue components:
https://stackoverflow.com/questions/65738176/how-to-avoid-ts2614-error-when-importing-interfaces-from-vue-components
I don't know why it worked in ts-loader-8 but it seems to me that the error TypeScript is reporting is correct. Perhaps the Vue community has found a solution.
Fair enough. That was my understanding, but since it was working on ts-loader 8.x I thought it had some magic internally. To avoid adding the interface on the shim I created a definition file just for the class that exports the interface.
Do you want to leave this ticket open to handle a fix on 8.x or should it be closed?
I'd quite like for this to be fixed in ts-loader - I think it's an issue. But as I'm not a Vue user I'm not well placed to help.
My guess is that the answer lies in looking at the src
files on this PR:
https://github.com/TypeStrong/ts-loader/pull/1251
That's where we went from ts-loader 8 to 9 and where I assume the break happened. (Maybe worth checking that v9.0.0 was the first version where this didn't work)
The src
changes are actually pretty minimal, so I expect diagnosis might be fairly straightforward
I've just run into this while trying to import interfaces exported from Vue SFCs. I'm not using the shim for vue so the resulting error is a TS2307:
ERROR in /path/to/importing/component.vue.ts(LINE,CHAR)
TS2307: Cannot find module './path/to/exporting/component.vue' or its corresponding type declarations.
Downgrading from 9.2.6 to 8.3.0 also fixes the problem for me (maintaining running webpack 5). I can verify that 9.0.0 was the version that broke things. I'm going to take a look at the PR above and try and isolate what's causing it.
@johnnyreilly I don't suppose you still have a copy of the feat/webpack-5 branch? There's nothing that stands out for me as a breaker, I was going to go commit by commit through your changes but can't sync the un-merged commits as the branch no longer exists.
I have a feeling I haven't I'm afraid. Did a rm -rf
along the way. But I'd take a look at the diffs in the src
folder alone. If memory serves, there aren't many. It was mostly a case of deleting code and using the built in webpack types (which shouldn't be relevant)
Actually comparing the transpiled code for ts-loader
8 as opposed to 9 might be more revealing in terms of different running JavaScript (which is what is relevant for your case I believe)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Here's a workaround for the ts-loader 9.x.
diff --git a/webpack.config.js b/webpack.config.js
index 34a6296..a140bbe 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -20,8 +20,12 @@ module.exports = {
},
{
test: /\.vue$/,
- loader: 'vue-loader',
- }
+ use: [{
+ loader: "vue-loader"
+ }, {
+ loader: "ts-loader"
+ }]
+ }
],
},
output: {