typescriptvue.jsvitetypescript-decoratortsyringe

Make tsyringe decorators works with Vite


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 :

Things I have done :

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");

Solution

  • 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 !!!