I have been following the Meteor project from it’s early days. In the beginning the attraction was in that you could:
- Do everything in javascript
- Avoid the node waterfall callback coding style
- The reactive data that was rendered in spacebar templates
From back then things have changed dramatically in the javascript world. The javascript implementations have matured to ES6/7 and the import/require system avoids the global namespace issue, allowing modular construction of the applications. Also, In the same time amazing things have happened in regards to libraries and the npm system. Due to this javascript rich client side applications have thrived and is now becoming the defacto web development practice. At the same time React and Angular had had great momentum. Personally I feel that the React way of doing things is the most important change in regards to finally being able to create reusable components. The next thing was seeing how Redux can help decouple applications, and how it in co-operation with React can help build applications that scale.
Looking at the divergence on Meteors v1 solution and the market out there it was evident that MDG had to do something. If they didn’t do something Meteor would die. And that would be a shame, because Meteor in itself and especially some parts of it really deserves the right to live. So, I applaud them in their attempt (and quest) to make Meteor stay attractive and alive.
Now, in 1.3 and 1.4 we are looking at the new future, but there still seems to be some uncertainty on where to go from here. I am currently building an application and using Meteor (1.3.4.1). I am using React and have adapted the application directory structure to the new recommendations. I loved this part as it made the application a lot more modular and removed a lot of dependencies. While doing this I was on my way to add Redux to the mix, when the question hit me like so many before me on how to integrate the database collection changes into the Redux state. Without having them there the option of properly logging and inspecting the timeline goes away. Also, having the collection changes reactive via minimongo directly to the DOM means that these changes have no traceability neither. I was looking at alternatives and the typical choices were to either let redux handle application state and let the domain state (collection data) stay reactive, or to add the reactive part into the state. The latter is the most clean way to do it, as that allows the historical debugging and the timeline. However, the latter option also means that the data will not only be stored in Minimongo, it will also be stored in the state. I then came across Cerebral, and it fealt like an epiphany in regards to how apps should be made. Granted, it looks like “another” Redux, and yes it is. But, it highlighted an important fact for me: The application itself can be made to run in its entirety without a view layer. Just using the console to drive actions is enough. Also, Cerebral has a pretty nice event timeline historical debugger (Chrome extension).
But, Cerebral in itself is not my choice though. It doesn’t solve reactive data-sources and easy collections (= rapid prototyping).
Now. I think Meteor should continue trying to make “application development” easy and simple, also in the future. And to do that I suggest the following principles:
- Embrace developing apps via a central application state manager (ASM). This state may even also be totally handled server side too?
- Let the ASM actions ask for data (like a subscription and a query in one). Changes in the data-sources are then logged as state-changes, just like manual user UI state-changes. The server-side data-changes are given via DDP to the ASM, which then handles the changes as an action (the change is coming due to an active subscription, so it is expected that someone is there to receive the changes).
- Let the visual components be separate to the “application”. These are parts of the view, but only implicitly. Nothing in the components should be wired to the application. Note: Some frameworks does not have components, so this is then optional.
- Have the view part of the application be handled in a separate part. Here the developer can set up the view using any tech / framework of choice. This part lays out the dom elements to the page and wires them up to receive application state.
- Then components subscribe to change-events for the ASM states they want to monito. If we follow React philosophy we would subscribe to the root state, so that the complete application state is sent to the root state on any state-changes. React would then render the view in it’s virtual DOM before re-rendering changes only to the browser DOM. As an alternative solution (more efficient, but not as pure as React philosophy recommends), each component can subscribe for whatever leaf-state they are interested in. This way they will be notified only for the changes it is interested in. Now, this may or may not be your preference. The point is that as a developer you can choose.
This means that Meteor’s responsibilities will be:
- Server-side:
- Startup
* Setup data-sources
* Distribute startup files to the client. - Runtime
* Receive and setup subscription queries
* Send subscription query change responses via DDP to the ASM - Client-side
- Startup
* Setup the application Actions and States.
* Setup the View, subscribe to state-change events (and implement view updates according to change-events) - Runtime
* Handle UI changes via actions to the ASM
* Act on data-source change callbacks from the ASM
This is a drawing that illustrates the application modules (not including the distribution of the initial files, the hot changes or server/client side script inclusion).:
Testing the application logic/state itself is very easy with this system. You don’t even need to start the view-layer. You can just run actions and verify the application state. for data-driven actions, these could be injection mocked.
I believe that Meteor would be awesome if something like this was supported. It would allow for setting up logics without considering the view-layer. It allows for re-implementing the presentation, without affecting the application logics. It is afaict presentation framework agnostic so it should attract anyone. The build-part of Meteor might have additional options for aligning with NPM and NodeJs(?). Testing application logics become trivial. Data is integral with state and feels “natural”, and includes Meteor DDP and reactive changes. I can even envision a nice bug-reporting system that collects the X last states and appends these to the report to help the for the devs to replicate the problem.
I think that this seems like a pretty good solution for me. Not sure if this is in contrast with the goals of MDG though.
Any thoughts?