tsyringe icon indicating copy to clipboard operation
tsyringe copied to clipboard

Usage without Reflect

Open Djaler opened this issue 2 years ago • 6 comments

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?

Djaler avatar Oct 02 '21 08:10 Djaler

+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.

roblebel avatar Nov 12 '21 21:11 roblebel

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 avatar Nov 30 '21 13:11 shrink

@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

Djaler avatar Nov 30 '21 13:11 Djaler

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.

dummdidumm avatar Apr 12 '22 13:04 dummdidumm

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

dh94 avatar Mar 25 '23 11:03 dh94

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.
]);

image

waynebloss avatar Jan 24 '24 17:01 waynebloss