5 ms·
I have a suggestion to this, but I don't know how to get it out there. I can't build a library because the point is to not depend on libraries. My suggestion i
by zachrose 11y ago
I have a suggestion to this, but I don't know how to get it out there. I can't build a library because the point is to not depend on libraries.
My suggestion is that if your going to build an application in the browser, your project needs an architecture that will last beyond today's libraries and tooling. You want to recognize what's unique about your app and express those parts without touching the DOM or network, even if they seem trivial now.
My particular favorite way to do that is using an event bus to create a catalog of custom/domain-specific events, with views emitting operation- or command-like events and internal models emitting new states. This is basically the important part of Flux without the special concepts (stores, dispatcher) that you may be fine without, and is already available in jQuery, Backbone, node's EventEmitter, and many other libraries out there.
React and immutability and the rest of Flux are all very reasonable next steps if somehow you come to need them, but you are likely not spreading your UI development across hundreds of engineers. Unnecessary new stuff is just going to steer your conversations towards libraries and away from your domain.
- baddox 11y agoRedux or anything similar to it seems pretty close to this, assuming you always want to stick to its basic architecture (atomic immutable application state with "reducers" that take a state and an action and return the new resulting state). Redux is so small that it's hard to see why you would need to switch away from it if you're keeping the same architecture, but even if you wanted to it ought to be fairly easy, since reducers are pure functions and actions are (or should be) simple JSON-able data. The actual rendering of state to DOM is done completely separately by registering callbacks that listen for application state changes. Of course, if you're using some other architecture to manage application state, results may vary.
- MatthewPhillips 11y agoHow can I write reusable components if my domain logic must be separate from my view logic?
- baddox 11y agoI was responding to a question about separating "the unique parts of your app" from other concerns like DOM and the network. I interpreted "the unique parts of your app" to be the way application state is represented and modified, which is a pretty reasonable definition for the common term "business logic." Library-agnostic reusable components is another question, and certainly a good one. There doesn't seem to be a good answer right now. Web Components appears to be intended to solve that problem, but it isn't looking so good in my opinion. I would probably go with a similar approach to reducers in Redux: a simple function that takes a state object and returns some library-agnostic representation of DOM. Of course there is no standard representation of DOM that I know of, but you could just output a plain JS object representing the DOM tree. There are probably many libraries out there offering a way to represent DOM that could easily to plugged into (with a simple wrapper) whatever new DOM rendering library is hot.
- zachrose 11y agoThe "separation" between your business logic and your view logic is really better thought of as a decoupling. Let's say for example that your application is a game of solitaire. Rendering the cards is a view concern. Interpreting UI events as game actions is a view concern. Accepting or rejecting those game actions is business concern. Animating that acceptance or rejection is a view concern. Persisting or restoring your moves or game state to an API is a business concern with some networking glued to the side of it. That's sort of a trivial example, but the event catalog for your application might look like this: name: GAME_STATE, payload: A JSON representation of the card stacks name: PLEASE_MOVE, payload: A representation of an attempted move name: MOVE_REJECTED, payload: The card that tried to make an illegal move A move event would result in a new state event or a rejection event. Your rendering components don't need to know how that happens or who controls the state. Your core components don't need to know if this game is being played on a server or a browser. Your move events might come from a swarm of multiple players. An analytics component can listen to the bus and fire off things that it's looking for.
- MatthewPhillips 11y agoThat's fine if my application is a game of solitaire. But what happens when I want to distribute it as a component, <Solitaire />? I can't, because it's not self-contained.
- zachrose 11y agoTotally. But if I'm being extreme I would say that keeping your application state "memoized" into a single value may or may not be necessary for your application. If it's not, you've just coupled all of the data models in your application to into the same entity, which makes it easier to turn those couplings into dependencies, which makes them harder to test and use separately later.