I am writing a Vue application and I want to use tsyringe
.
Currently I am stuck with an error saying : "Error: TypeInfo not known for "ListService"
.
This happens every time I want to resolve a service that has at least one parameter in its constructor.
Here is my setup :
- Node v20.10.0 / NPM v10.2.3
- Vite 5.0.2
- Vue 3.3.9
- Tsyringe 4.8.0
- Typescript 5.3.2
Things I have done :
- I have imported
"reflect-metadata"
in my main.js file - I have tried resolving a service that doesn't have any parameter in its constructor, and it works without throwing an error !
- I thought this might have something to do with the decorators as I have had problems with them in the past. Thus I tried the following :
- Use the
@rollup/plugin-typescript
plugin (I recalled it solved some problems in another project). It didn't have an effect on my problem - Use SWC instead of esbuild, but I couldn't make it work. I may have done it incorrectly...
- Use
@abraham/reflection
instead ofreflect-metadata
- Use the
@anatine/esbuild-decorators
plugin, but it didn't have an effect. I am not sure if I set this up correctly, as there isn't really a doc for this use case.
- Use the
If you have any idea on how I can make it work, I will gladly take the suggestion, as I am kinda out of ideas.
If you have made tsyringe
work with vue, I am curious to see how you did (and where I messed up) !
My code (simplified)
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* Own settings */
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"paths": {
"@/*": ["./src/*"]
},
"types": ["element-plus/global"]
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
package.json
{
"type": "module",
"dependencies": {
"tsyringe": "^4.8.0",
"vue": "^3.3.8",
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.0",
"reflect-metadata": "^0.1.13",
"typescript": "^5.2.2",
"vite": "^5.0.0",
"vue-tsc": "^1.8.22"
}
}
vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
plugins: [
vue({ template: { transformAssetUrls } }),
],
});
main.ts
import { createApp } from "vue";
import { container } from "tsyringe";
import { Database, ListService } from "./services";
import App from "./App.vue";
container.registerSingleton(Database); // No dependencies
container.registerSingleton(ListService); // Depends on Database
console.log(container.resolve(Database)); // works;
console.log(container.resolve(ListService)); // fails;
const app = createApp(App);
app.mount("#app");
Alright, I got this working !!!
@rollup/plugin-typescript
was the solution to my problem once again ! My mistake was the order of my plugins. I placed it in the last position and somehow, that didn't work. When I tried again, I placed the plugin right after the vue plugin (second place then), and it worked !!!