tsyringe
tsyringe copied to clipboard
Usage without Reflect
Is your feature request related to a problem? Please describe.
I need to install reflect-metadata
even when if emitDecoratorMetadata
not used.
Description
In some cases emitDecoratorMetadata
can't work. For example, when using esbuild
as typescript compiler (which is used in popular Vite
).
Tsyringe can work in such environment, it just will not interfere injection token (one need to provide token to @inject
manually), but I still need to install and import reflect-metadata
because of tsyringe requires a reflect polyfill. Please add 'import "reflect-metadata"' to the top of your entry point.
Alternate solutions I understand why this check is needed in most cases, but maybe you can add a way to tell tsyringe that I don't need a Reflect?
+1 We have the exact same need. A warning log could be sufficient instead of throwing an error, since it's not true that tsyringe require a reflect polyfill.
I've had success switching from reflect-metadata
to @abraham/reflection
which is a drop-in replacement and works with esbuild and vite.
// main.ts
-import "reflect-metadata";
+import "@abraham/reflection";
// Your code here...
@shrink the only plus here is that @abraham/reflsection
is much smaller. But it still not really work with esbuild (because esbuild doesn't produce a code which will call Reflect
API
I had the same problem when converting a project from a Rollup-based solution to SvelteKit, which uses Vite, which uses ESBuild. I needed to provide the import although it's not needed when using the explicit constructor(@inject(OtherClass) otherClass: OtherClass) {..}
method.
I have found a way to make it work in vite 4+. I've used this package: @anatine/esbuild-decorators and added it to the optimizeBuild step. From my understanding it shouldn't have worked after build (because from the docs vite does not use esbuild when building for prod) , but it does work!
https://stackblitz.com/edit/vitejs-vite-hzkjj3?file=vite.config.ts
Here's a system for using TSyringe without decorators at all, by simply making the same calls to Reflect.decorate()
and Reflect.metadata()
which would normally be compiled by the decorators - https://gist.github.com/waynebloss/28fd81a00eec98a67007bec40473a71b
It's a work in progress and being used only internally, not packaged in any way. Some inspiration was taken from the source code of VS Code.
It also allows for nice autocomplete for dependencies which were registered by name and a shorthand for doing injectWithTransform, injectAll, injectAllWithTransform, e.g.
registerClass(MyClass, [
"dep1", // Inject dep1 by id.
["dep2"], // ...array of dep2 by id.
["dep3", getYesNo, ...yesNoArgs], // ...dep3 transformed to bool.
[Dep4, [getId, ...getIdArgs]], // ...dep4 array transformed to string.
YadaProvider, // ...exact type.
]);