morris / vanilla-todo

A case study on viable techniques for vanilla web development.
https://morris.github.io/vanilla-todo/
ISC License
1.17k stars 54 forks source link

Feedback! ( not sure where to put/write this ) #5

Closed zinglax closed 3 years ago

zinglax commented 3 years ago

Hey @morris

First off, great work, I read this last night and really loved your write up and the code. Constraining yourself like you did really makes you think differently about how to do things, and I think the way that you did it helped shed light onto what is possible.

Pure JS is really powerful. For me I started on a similar adventure building a website called Stor.Guru. I previously picked up the book Single Page Web Applications, SPA Book, by @mmikowski, which has a robust format for SPAs similar to what you are doing but not 100% Vanilla JS. The book uses jQuery and a couple other libraries so it is not as constrained as your experiment but it does capture the essence of what you are trying to accomplish by not using frameworks. SPA

One point that he brings up is that you can effectively develop in this style with only a browser, text editor, and terminal. No other applications or frameworks are necessary. This keeps development cycles very quick. You can also do this anywhere, even without an internet connection. Keeping it as easy as JS, CSS, & HTML files that you can open in your browser makes this setup incredibly simple, and that is a huge benefit.

As you continue down this path, like you have started with your application, you can use techniques that make this simple style of development even more powerful. Your thoughts on event-based data flow and custom events are spot on. Custom events are a core part of the app that is built in the SPA Book. This setup allows for any new module in the app to just subscribe to messages that are important to the part of the page that it manages. But the internal messages are only the first layer. The SPA Book uses WebSockets with socket.io, for messaging with the server that are intercepted by a "Data Layer" which then dispatches the custom events to rest of the application. Not advocating for Socket.IO here, just trying to explain how the messaging is done in this instance. The native WebSocket API I believe is pretty simple and supported everywhere now a days. Handling new events is as easy as calling the "update" function with the new data. You basically have Socket Msg --> Custom Event --> Module Update()

Having messaging go through a single point, the Data Layer, is key. It allows you to add another layer in front of it, the fake layer. With the fake layer you can simulate messaging from the server that looks identical to what the rest of the application expects and without ever even starting a webserver. you now have a backend for the application you are developing with just a browser, a text editor, and some static JS, CSS, & HTML files. The fake layer basically becomes your unit tests for the frontend application and a way to quickly develop new modules.

The final part of the SPA book which you might find interesting is Client-Side Storage and I see you have used localStorage some in vanilla-todo. In the book they use an in memory database, TaffyDB, but I have since used IndexedDB in place of it, which is also a native API. Client-Side Storage allows you to store relevant data models from the backend for use and modification by the client. With IndexedDB you have a full object store, now offline, that the client can use to build its page with. To me IndexedDB is the next level of localStorage. I use the idb library as a wrapper for the native API since it is Promised, also not ES5 but still pretty low level, almost vanilla, js.

When you combine Client-Side Storage with the Fake and Data Layers you can build an application that has a faked backend ( including database ) that communicates and sends messages to your frontend. The frontend handles messages, stores data in Client-Side Storage, and fires custom events listened to by each feature module who go get the new data from client storage and update their little portion of the page. All of this with just static files, a browser, and text editor. All of which can be used offline. Pretty cool!

I have implemented this type of faked communication for the demo mode of my app, Stor.Guru Demo, just as an example of it working.

Disclamer: It was not my intent to bore you with this much feedback or to come off like I actually know what I'm doing lol. But I think I was just so excited to see someone else go in the opposite direction of JS frameworks and discover the power in what they can build. Your write up is really well done and my post ( this issue ) is pretty poor and does not due justice to the SPA Book or the topics from it I was explaining. I am not trying to pitch the SPA Book, I just noticed that the topics your post and it brought up are similar! Kudos for the awesome write up of your code and the code itself, I would love to chat more about this topic and your experiences with it! Thanks!

morris commented 3 years ago

I appreciate your feedback very much, thank you! I've heard of the book. It certainly tries to tackle similar problems (frameworks do, too). Anyways I believe being active in the field (using vanilla, using frameworks, or reading books) and trying to find good practices builds understanding and experience, and you seem to be doing that :)

For this kind of discussion, I think e-mail is a better fit: mb@morrisbrodersen.de ✨

Thanks again, and good luck with your project!

mmikowski commented 3 years ago

Hi @morris and @zinglax

Author of the book here (along with Josh Powell, of course). I have a pretty comprehensive project used in a number of high-volume commercial products. The only major sticking point in more general adoption IMO is the lack of generator scripts. But those are coming.

Updates are continuing as this is the basis for yet another commercial product. Pending upgrades include messaging usinjg JSON Pure over native WebSockets and a client upgrade to ES6. Socket.IO is no longer needed or beneficial now that implementation has become consistent and reliable :)

Cheers, Mike