> lazy loading can happen in any component rather than only at "page" level
You can use dynamic imports anywhere in Next using `react-loadable`.
> more things are provided by the team via plugins
Next relies on its thorough `examples` dir for integrations. But it means a lot of manual coding.
I had a crack at a plugin system in the past (i.e plugins for adding features like apollo, redux, etc. AOT like stuff). I found that it obfuscated the code too much. Makes it hard to trace what is happening and make adjustments. The closer the code is to the "Getting Started" examples of Redux, I18n, Apollo, the easier it is to tweak and understand.
E.g. Sometimes it might be clearer to just wrap a Provider manually around the app root, than expose a plugin hook. Because you can see the React tree, whereas with plugins everything is dynamic so you must rely on logging.
I think devs are naturally drawn to DRYness and dividing code up by feature, which is what a plugin system offers, but there are big tradeoffs. I'm interested to dive into Fusion to learn more about their approach though.
> - better support for maintaining server-side complexity (e.g. by using Koa + DI system to make testing/mocking easier)
Great to see you adopting Koa! I use it myself, and feared that the community had stagnated, but now with Fusion, it may be reinvigorated.
> DI system to make testing/mocking easier
Very cautious of DI systems. Same reasons as plugin systems: its hard to see what is going on. And sometimes manually wiring up all the dependencies is actually not much code at all, and you can manage cyclic dependencies and ordering easier.
> You can use dynamic imports anywhere in Next using `react-loadable`
I joined the team after the code splitting part was done, so I don't know off the top of my head whether this library was considered, but it does look interesting. From a glance, it seems to suffer from the issue of sprinkled configuration, but it might be something that we could potentially use to replace our current implementation. Does it support HOC-level async data fetching?
> Very cautious of DI systems. Same reasons as plugin systems: its hard to see what is going on
Interestingly we had a completely opposite experience maintaining our old closed-source framework. Everything was built on top of express and it was really hard to reason about where code for any given thing was. For example, trying to debug some I18N thing meant digging through at least 3 files filled with unrelated concerns in completely unrelated packages.
FWIW, we spent a lot of time designing and redesigning the plugin system (like months). What is there today looks nothing like our first approach. I think we arrived at a pretty good solution, which is centered around colocating related concerns into one place.
> sometimes manually wiring up all the dependencies is actually not much code at all
Yes, wiring things up manually is relatively easy. The challenge we kept running into was taking things out (e.g. no-op-ing production-hitting tracing/metrics code in tests)
Having used Fusion a bit now (I'm an engineer at Uber, but not on the Web Platform team that produced Fusion), I'm really enjoying the DI system. Agreed other DI mechanisms (e.g.: Angular) are too magical; Fusion uses a token system which is very easy to reason about.
- isomorphic treeshaking
- more powerful bundle splitting (i.e. lazy loading can happen in any component rather than only at "page" level)
- async server-side rendering is composable via HOCs rather than only at top-level getInitialProps
- more things are provided by the team via plugins (e.g. I18N, CSRF protection, atomic CSS, async font loading, etc)
- better support for maintaining server-side complexity (e.g. by using Koa + DI system to make testing/mocking easier)
- out-of-band brotli level 11 compression for static assets
The team is about a dozen people now and we've been working on Fusion.js for over a year, so there's probably other stuff I'm forgetting right now :)