4 ms·
Ugh, the dependency injection stuff is just Angular all over again. export default wire(Title, ['title'], function resolve(title) { return { title };
by _greim_ 10y ago
Ugh, the dependency injection stuff is just Angular all over again.
export default wire(Title, ['title'], function resolve(title) {
return { title };
});
Now I have to register "title" somewhere. Where is it registered? Did I remember to register it? I no longer know what's going on just by looking at the file in front of me, and my linter is silent. Then I have to annotate the function and declare it in the argument list. Items will be added and removed from the two lists as the app evolves, introducing more mental overhead and increased surface area for bugs, since once again my linter will have nothing to say on the topic.
Surely I'm in the minority given how popular Angular was, but I felt "DI" was the absolute worst thing about Angular's approach—basically a DSL layered over JS requiring yet more specialized tooling. The ability to look at just one file and understand it goes hand-in-hand with static analyzability, and I'd hate for the React community to abandon that and go down this path.
[edit] In the spirit of not dwelling on the negative, I should also say I did find most of the article to be a good summary of design patterns. Nice job!
- munro 10y agoAgreed, it serves no purpose. For testing, dynamic languages have the ability to ... dynamically replace dependencies. :) For building a library, a function that takes in dependencies and returns the component works extremely well & is straightforward to understand, no tooling required.
- dceddia 10y agoCompletely agree. I don't see many people in the React community advocating the use of DI though, so that's a plus. The DI in Angular made a little bit of sense because JS modules weren't very widespread back then. But now, with ES6 imports (and/or 'require') there's no need. We have real modules now, and they can be dynamically injected for testing purposes with something like inject-loader[0]. I think Angular and/or DI's popularity has something to do with Java devs learning frontend development, and feeling more comfortable with more structure. [0] https://github.com/plasticine/inject-loader https://github.com/plasticine/inject-loader
- _greim_ 10y agoMakes sense. My frustration in part stems from having worked on an app that used Angular DI and a module loading system (RequireJS) side by side. The conceptual dissonance and fallout between the two systems was an endless source of bickering and confusion for the team. I came to the situation having worked on a CommonJS/Browserify project, and it was like walking into a brick wall.
- dceddia 10y agoI worked on a project that had Angular + RequireJS too. I don't think having RequireJS added anything at all. It was just additional overhead - every module we added caused at least 3 files to change. We eventually ripped it out and just dealt with Angular's own module system.
- Bahamut 10y agoThis is a misunderstanding of what Angular's DI is meant to solve - it is orthogonal to Angular 1's module system. DI is meant to solve runtime dependency management, which is a different problem from modularity, which is what ES6 modules are meant to solve. For example, oftentimes one has a class that may have an instance floating around. One does not want to instantiate it unnecessarily if it already exists oftentimes, and so the injector will handle that automatically if necessary by instantiating an instance if it doesn't exist already, allowing for efficient memory management of services. It also has a major benefit for facilitating easier patterns for testing & readability. Angular 1's DI has a poor API signature, with the naive allowance of it through a hacky regex, and crappy duplication of string references for the regular usage with minification taken into account - Angular 2's is built much more solidly and without such hacks. It should also be noted that using cjs for dynamic injection is a bit of a hack as well, since it is a non-standard syntax. Angular 2's DI is much more pure, as it could be split off into a standalone library with some build configuration with zero external dependencies other than perhaps an ES6 shim like core.js.
- kin 10y agoYeah, I'm also not a fan of the DI example. I would rather explicitly pass it down the component tree or use Redux's connect. I believe React's docs advise against using context.
- ower_89 10y agoYou can use InversifyJS to inject a value into a React component without passing it explicitly through each component and without using the context http://blog.wolksoftware.com/dependency-injection-in-react-powered-inversifyjs http://blog.wolksoftware.com/dependency-injection-in-react-p...
- chrisabrams 10y agoYou are actually in the majority :)
- quantumhobbit 10y agoAngular's DI is my main reason for switching to react. If it becomes standard in react then what?
- Dr_tldr 10y agoIt's definitely not standard, the almost universal standard is using ES6 import/export. There are several other suspicious patterns here, I definitely wouldn't take these as canonical, or even best practices.
- hccampos 10y agoWell, InversifyJS https://github.com/inversify/InversifyJS https://github.com/inversify/InversifyJS
- msane 10y agoI don't mind DI, in Angular or elsewhere. I'm not sure in what way you think of it as a DSL, or even that it requires tooling. It's a useful pattern in OOP.
- _greim_ 10y agoDI is great; DI isn't the problem at all. It's rather the fact that Angular baked in a DI implementation that doesn't play well with either static analysis tools or module loaders. I'm not even criticizing the creators of Angular; they did something that made sense at the time and worked, in its way. It's just that Angular DI is icky and I hope to never have to deal with it again.
- novembermike 10y agoDI is fine, but that's just the concept that you ask for dependencies rather than relying on them. foo(X dep) {} vs foo() {X dep = new X()} It's overused imo but it's fine. The problem comes with DI frameworks like Spring or Angular DI when you start letting the framework tie your code together. This couples you tightly with the framework and can lead to odd situations where the thing you're getting isn't what you're expecting but that's not obvious because the object passing is happening behind a curtain.