[HN Gopher] TodoMVC App Written in Vanilla JavaScript
___________________________________________________________________
TodoMVC App Written in Vanilla JavaScript
Author : marban
Score : 138 points
Date : 2022-05-07 11:38 UTC (11 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| cehrlich wrote:
| I once wrote a Twitter clone in Vanilla JS, just for the sake of
| it.
|
| I'm glad we have frameworks.
| Philip-J-Fry wrote:
| The thing I enjoy about frameworks like React is the declarative
| nature of the UIs.
|
| I'd love to not be able to use them and to create complex UIs in
| pure JavaScript but it always ends up being painful where you
| spend more time optimising the rendering than doing any work.
|
| In simple apps I will write UI in a functional matter in pure
| JavaScript, regardless of the performance implications. But
| bigger DOM means worse performance with this method.
|
| When will we get to the point where we can tell the browser what
| we want the DOM to look like and then the browser does the
| diffing like a framework would?
| ricardobeat wrote:
| There's absolutely no way you'll have worse performance with
| this vs React. The app is modifying the target elements
| directly, not recreating the whole page with innerHTML. React
| will do the same amount of work at a minimum, and that's
| _after_ rebuilding the whole tree and diffing it.
|
| The main bottleneck here are the synchronous localStorage calls
| happening in the render path, they could be moved to a separate
| timer.
| Philip-J-Fry wrote:
| I never suggested you'd have worse performance. But it's not
| declarative, it's tedious.
|
| Read my comment again.
| grayrest wrote:
| > There's absolutely no way you'll have worse performance
| with this vs React.
|
| It's normal to get much worse performance than React if you
| layout thrash and it's very easy to layout thrash without
| batched updates. There's overhead in the vdom but getting all
| the updates batched tends to be a performance win in any
| decent sized app. This was an active area of library
| exploration/development in the 2008-2012 timeframe but the
| only framework actively promoting it was Sencha IIRC.
| toomim wrote:
| One way React can be faster than hand-written code is by
| batching all dom manipulation into animation frames.
| ricardobeat wrote:
| The rendering code here is already batched since everything
| happens within a single render() call. And unless you're
| using react fiber, its rendering is also synchronous.
| sarchertech wrote:
| Handwritten JS could also batch DOM manipulation (without
| the need for virtual dom comparison).
| SemanticStrengh wrote:
| https://github.com/wilsonpage/fastdom
| 1marc wrote:
| Ooo fastdom looks great! Thanks for the link.
| SemanticStrengh wrote:
| https://www.youtube.com/watch?v=VKMw2it8dQY
| chacham15 wrote:
| It seems like you didnt actually look at the code because
| thats exactly what its doing:
| https://github.com/1Marc/todomvc-
| vanillajs-2022/blob/main/js... it clears innerHTML there and
| then rerenders the children
| 1marc wrote:
| I did this style to mimick modern framework code -- taking
| the state (todos) and render the state of the world every
| time. If the browser had a DOM diffing api this would be
| more efficient and we would be there. So for a larger
| project I might using something like Lit's html stand-alone
| package or fastdom to get the DOM digging functionality
| without much dependency code.
| ricardobeat wrote:
| You're right, I did a quick reading and thought it was
| updating elements one by one.
|
| I still suspect this might be faster than React anyway.
| Would be interesting to try.
| SemanticStrengh wrote:
| Right but proper manual dom is generally faster than
| optimized react code. That does not means that in general
| manual dom code is proper.
| kgbcia wrote:
| i agree it's up to the browsers chromium , Safari , and Firefox
| to do the diff. But we might need a new meta tag or change to
| the Fetch API to tell them this html page should only update
| the elements that are different.
|
| Remember <meta http-equiv="refresh" content="5"> .
|
| It was discouraged because the back button broke. If you're
| developing a single page react app, I don't think you care
| about the back button.
| nkrisc wrote:
| > If you're developing a single page react app, I don't think
| you care about the back button.
|
| Your users likely do, so you should too.
| creakingstairs wrote:
| > If you're developing a single page react app, I don't think
| you care about the back button.
|
| You should though. One easy way is to use react-router. e.g.
| going to /profile renders the Profile component. Then
| navigating to /dashboard renders the Dashboard component.
| Pressing the back button will take you to /profile.
|
| Another pet peeve of mine is people using internal react
| state when they should just use path or query params to make
| it transparent and easily sharable.
| alserio wrote:
| The primitives of fine grained reactive programming seem to
| me more amenable to be implemented by the browser than react-
| style whole world diffing
| recursive wrote:
| Cases where "UI should be a function of state" seem like a
| small sliver of all use cases. Probably not worth the
| complexity for implementing directly in the browser. And there
| are plenty of conditions that just prohibit the pattern
| entirely as far as I can tell. Things where referential
| stability matters, like you have a contentEditable or allow
| arbitrary edits on a canvas.
| deergomoo wrote:
| Personally I would argue that UI should _always_ be a
| function of state. When it isn't, you open yourself up to all
| sorts of inconsistencies and difficult edge cases. Of course,
| it's not always that easy; having two sources for said UI
| (the HTML document itself and the JavaScript within it)
| certainly complicates matters.
| mattgreenrocks wrote:
| Echoes of Alan Kay's recent comment on how software devs are
| way too concerned with the how the computer works to the
| detriment of what the software is supposed to do.
| ramesh31 wrote:
| Yup. The reality is that programmer time is far far more
| expensive than compute time. And as long as that's the case,
| increasing levels of abstraction are our only hope at
| building complex software.
| emteycz wrote:
| The battle is fought over performance and size, I think
| that's exactly what the user wants.
| vips7L wrote:
| I don't think the typical user cares about size.
| oblib wrote:
| I agree. In over 20 years I've never had a single user
| ask or complain about the size of the app. They have let
| me know when there was something not working right
| though.
| 1marc wrote:
| People definitely notice speed and performance. They
| won't complain about it generally, sure... but there's
| plenty of data and case studies on the fact that users
| care https://nitropack.io/blog/post/web-performance-
| matters-case-...
| ramesh31 wrote:
| >People definitely notice speed and performance.
|
| There's sort of a "Maslow's Hierarchy of User Needs" that
| exists in software though. So long as the user _can_ do
| something, and their immediate needs are met, performance
| concerns are just a small annoyance. And generally they
| will continue to ask for more features rather than
| performance improvements as long as the app remains
| _usable_.
| emteycz wrote:
| Well then you've never seen poor people uninstalling apps
| from their cheap smartphones because they need to install
| and use a different one ;-) that you don't see it doesn't
| mean it's not there
| anonymoushn wrote:
| it sounds sort of wild to expect there to be diffing! why do
| you have to generate a whole copy of the stuff instead of just
| telling the browser what changes to make? bonus: the existing
| apis instead of one that don't exist yet.
| Bilal_io wrote:
| Diffing seems necessary when your UI gets complicated to the
| level that a small change requires a full page re-render.
| However, I don't think this is necessary for at least 95% of
| the websites on the internet.
| dymk wrote:
| Diffing is exactly what you need to do (barring newer methods
| like svelte) to figure out what to tell the browser to
| change. The vdom tree is much faster to manipulate than DOM
| nodes.
| recursive wrote:
| But you can't see those changes until the actual DOM
| changes as well. It's only because of react's insistence
| that mutation is evil that this became a problem. You could
| just directly update the thing you wanted to and just skip
| the whole diff thing.
| dymk wrote:
| No, the reason React has a VDOM is because the DOM is
| slow to update, compared to manipulating javascript
| objects. It's worthwhile to calculate the list of minimum
| updates ahead of time rather than using the DOM as the
| source of truth.
|
| Not sure where you think mutation comes into play here,
| that's an orthogonal concern--you can have an API that
| mutates some internal representation of a VDOM, and it's
| still faster than manipulating the DOM directly.
| recursive wrote:
| In order to achieve immutability, large chunks of state
| have to be cloned whenever a single value changes. This
| sometimes causes a whole new DOM node to be created
| during reconciliation. React encourages you not to think
| about it too much. But some nodes can't be replaced. Like
| canvas or anything contentEditable. It's not orthogonal.
| It's a direct consequence of the design philosophy.
| Philip-J-Fry wrote:
| Because it can be automated? Every app that doesn't do this
| is just implementing the diff by hand, e.g. on this event
| delete this element, update this element, add CSS class to
| this element, etc. When the UI gets complicated you have to
| maintain this all yourself and it's a pain. Multiple event
| listeners between components to say something has happened.
|
| It makes sense to be able to describe what you want to
| achieve and to let the browser determine how to get there in
| the most efficient way.
|
| If the browser could do this it would make a tonne of JS code
| so much simpler. There's a lot that goes into making sure
| that there's no unnecessary DOM updates because it's just
| slow.
|
| I don't write assembly and move things between registers by
| hand, I write a function and the compiler decides the most
| efficient way of doing it. UI should be the same way, I say
| what I want to happen and the browser decides how to get
| there.
| 5560675260 wrote:
| > When the UI gets complicated you have to maintain this
| all yourself and it's a pain
|
| This is also something that can be automated by a
| framework. Check out https://svelte.dev/blog/virtual-dom-
| is-pure-overhead
| Philip-J-Fry wrote:
| Yes... but that's the exact argument I'm making here.
| Unless you want to go through that pain, you need a
| framework.
|
| Whether that's Svelte without a VDOM or React with a
| VDOM. The entire point of these frameworks is that you
| can write complex UI in a declarative way. They both
| exist because writing it declaratively in pure JS leads
| to performance issues. But there's nothing stopping the
| browser implementing something that does this
| optimisation for you.
| recursive wrote:
| I find the "pain" to be drastically overstated. See this
| HN post.
| bobbylarrybobby wrote:
| Yes, but there are ways to accomplish this automation
| without diffing. Svelte does this by statically wiring up
| the data dependencies in your app when it builds, and then
| at runtime making exactly the changes to the DOM that it
| needs to based on the information it had at build time. No
| need to diff.
| Philip-J-Fry wrote:
| The point is that A) that's a framework and B) that
| requires you to compile Svelte files.
|
| If you want to write declarative UI in pure JS then you
| need the browser to do these DOM optimisations for you,
| and diffing the changes is the way to do that.
| goldenkey wrote:
| How do we get 31 comments but not a single one on why this
| solution is subpar?
|
| The entire TODO list is rendered anytime a single item is
| changed/removed/added. The biggest thing frameworks give us is
| fast, differential DOM updates.
|
| Once browsers add differential update APIs, then we can kiss
| React and all the other players goodbye :-)
| taeric wrote:
| I mean... You aren't wrong, but the amount of data that fits on
| a typical page is usually such that the speed of a full refresh
| probably shouldn't be that big of a deal.
| timcavel wrote:
| syspec wrote:
| Wouldn't this have loads of memory leaks from never removing the
| event listeners when the todo elements go away?
|
| I think it hides the complexity by pretending that's not a
| problem
| realPubkey wrote:
| Also it does not work properly when it is used in more then one
| browser tab.
| grabanski wrote:
| Here's what it would look like to support that usecase:
| https://github.com/1Marc/todomvc-
| vanillajs-2022/commit/09979...
| gherkinnn wrote:
| The event listeners get cleaned up by the GC. At least in
| modern browsers.
|
| While events aren't explicitly mentioned, MDN offers an
| insightful read:
|
| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memo...
|
| Alternately, one can use event delegation [0]. As does React
| under the hood [1].
|
| 0 - https://javascript.info/event-delegation
|
| 1 -
| https://reactjs.org/blog/2020/08/10/react-v17-rc.html#change...
| rickstanley wrote:
| Nice! I was going to suggest the usage of Trusted Types API [0]
| to escape HTML [1], but support [2] for modern browsers is not
| there yet, specifically for HTML.
|
| 0: https://developer.mozilla.org/en-
| US/docs/Web/API/Trusted_Typ...
|
| 1: https://github.com/1Marc/todomvc-
| vanillajs-2022/blob/1c31309...
|
| 2: https://developer.mozilla.org/en-
| US/docs/Web/API/TrustedHTML...
| grabanski wrote:
| Cool! I'll look into the API and consider adding it to this
| implementation. Or happily would take a look at a PR for it.
| randomfool wrote:
| Seriously- just do the innerHTML assignment on li.innerHTML
| omitting the title, followed up by a simple
| li.querySelector().textContent = todo.title.
| grabanski wrote:
| How does this look? https://github.com/1Marc/todomvc-
| vanillajs-2022/commit/d38e5...
| arriu wrote:
| For me, the biggest issue with using vanilla JS is the lack of
| guardrails.
|
| Before even considering something like this I'd want to see a
| style guide and clear definition of where code should live.
| Frameworks like React do that well. I can expect a random React
| dev to mostly do similar things.
| notduncansmith wrote:
| > I can expect a random React dev to mostly do similar things.
|
| This has not been my experience. Even experienced software devs
| will differ stylistically, but intermediate devs often come up
| with _very_ different ideas about how things ought to work. I
| suspect this is due to wide variance in awareness of different
| libraries /platform features/stylistic patterns/etc, a
| consequence of being in a relatively unregulated industry.
|
| I have worked for companies using React since 2014 and no 2
| projects have had the same layout. My current and previous
| employers have had the closest codebases, but only in terms of
| directory structure, and even now the current one is changing
| to become quite different (in a way I think is good, but only
| time will tell).
| yuzuquat wrote:
| Hey! This is really awesome. I'm building my own SPA in vanilla
| js, and I'm definitely stealing some ideas here. I think a lot of
| people here see the resurgence of vanilla js as a repudiation of
| their favorite framework. There's a definitely a time and a place
| for both, and it's never bad to take a break and revisit the
| basics
| 1marc wrote:
| Thank you! Agreed!
| norswap wrote:
| FWIW TodoMVC does list a vanilla JS implem:
| https://todomvc.com/examples/vanillajs/
|
| It's older though (seems to have been first written 6 years ago)
| and has significantly more code.
| wackget wrote:
| Why is there HTML inside the JavaScript? Doesn't that defy the
| entire point of the MVC pattern?
| dymk wrote:
| That's a misunderstanding of MVC - it's a design pattern that's
| language agnostic, not a declaration that HTML needs to live
| separately from JavaScript. The view logic in JS lives
| separately from the model logic in JS lives separately from
| controller etc.
| pjmlp wrote:
| React people think it doesn't, and apparently that is what
| everyone should be using...
| mrspeaker wrote:
| I like the "const TodoStore = class extends EventTarget" idea to
| trigger rendering... neat trick!
| telagraphic wrote:
| I noticed that, where does one even find EventTarget in the
| docs/references? I feel a bit behind on built in apis...
| xupybd wrote:
| I'm impressed this took an hour and a half. Is this the kind of
| timeframe someone should be able to throw something together in?
| xdennis wrote:
| Vanilla JavaScript feels like jQuery now. Doing this was quite
| awkward in ECMAScript 3 and 5.
|
| > App.$.filters.querySelectorAll('a').forEach(el =>
| el.classList.remove('selected'));
| oblak wrote:
| [deleted]
| ravenstine wrote:
| Looks well made, code is pretty good, but why the archaic form of
| JavaScript other than the import statements? There's a lot of
| well supported syntactic sugar that would make it much easier on
| the eye. I also wouldn't bother with the IIFE.
| timcavel wrote:
| qudat wrote:
| Now add 500 more features and 10 engineers and see if it scales.
| Hint: it doesn't. Sure you can make it work, but as someone who
| regularly makes FE decisions for a team, I wouldn't want to
| impose vanilla on them.
|
| What I will say is it's tough. I don't like the idea of react at
| this point. I like building products that don't need something
| heavy like react/redux.
|
| I recently launched https://lists.sh to scratch that no js itch.
| It was a ton of fun and I want to chase that feeling.
|
| But building a web app is what businesses want. And while you
| could make vanilla js work, you'd be reinventing a lot of tooling
| to get you there.
| 1marc wrote:
| With some patterns they can follow, vanilla js does indeed
| scale so well that it becomes boring. There's no longer any
| code to rewrite for the latest and greatest frameworks. No
| dependencies to manage. It just becomes almost too easy at some
| point, at least in my experience with many projects I've led.
|
| I've made millions and millions for major brands, including my
| own company, and customers go "wow how is your site so fast!!"
| All. The. Time.
|
| The biggest pressure I've found is from the engineers
| themselves. Not all engineers like to go counter culture and
| learn browser APIs and JavaScript. They would simply like to
| use what everyone else is using. They tend to argue against
| vanilla using canned arguments read off of framework websites
| that don't apply much or aren't even problems in the actual
| codebase.
|
| :shrug:
| BiteCode_dev wrote:
| Also:
|
| - add time constraints, where you need to implement widgets
| that you could source from a JS framework ecosystem otherwise.
|
| - in your 10 engineers, make it 5 juniors, 2 interns and 3
| seniors comming from PHP, and make sure they write all the code
| in the same style, follow a congruent architecture, can find
| solutions to common problem, get easy onboarding, etc.
|
| - request sub-routing, off-line mode, notifications, content
| udpated by multiple users and so on.
|
| - put a big table in there with 10000 rows and ask your team it
| renders fast.
| danielskogly wrote:
| I wrote a TodoMVC App with React, Redux and SSR that works
| without JS enabled in the browser a while back, for those
| interested in that sort of thing :)
|
| Demo: https://todo-react-redux-noscript.herokuapp.com/
|
| Repo: https://github.com/wishy-gift/todo-react-redux-noscript/
|
| Talk (updated framework): https://m.youtube.com/watch?v=3yY-
| Z-X3xE4
|
| Helpers to do your own stuff:
| https://www.npmjs.com/package/@wishy-gift/noscript
| Trufa wrote:
| I'm sorry but this is not a fairly complex app. When things do
| get more complex (and not even that much) is when you start
| hitting problems. How would you reuse a "component"? Among many
| other things.
|
| I honestly don't know if that's the point of the author but I
| would agree that many framework are too heavy, but honestly there
| so many good compromises today that don't make you re-invent the
| wheel and fix bugs that have been have been fixed millions of
| times before.
|
| Going against good abstractions as developers seems to go against
| the most powerful tool we've got.
| moffkalast wrote:
| > How would you reuse a "component"?
|
| Save the element template as a string and set innerhtml of a
| div as that?
|
| > compromises today that don't make you re-invent the wheel
|
| Yeah but there's also no need to include jQuery and bog down
| your site with piles of code you won't ever call just because
| you don't know how to use the native api like a normal person.
| React/Angular/whatever are just the latest fad of that mindset,
| big team corporate ease of use aside.
| wildrhythms wrote:
| What happens when you need to update some deeply nested child
| element without re-rendering the whole tree? Suddenly you
| need some system of labeling the children, how to find them
| in the dom, how to update them, how to keep them in sync with
| the state... a vanilla JS solution becomes extremely unwieldy
| as soon as you step out of the "global pointers to elements"
| phase (what the project in the OP is). Lit-html is an example
| of a tool that solves this problem in tiny package- less than
| 1KB- and you can continue using string templates with that.
| moffkalast wrote:
| I mean speaking for myself, I mostly make robotics web apps
| which isn't the most typical of web applications but the
| times this sort of thing is needed are few and far between.
|
| So yes, this pattern is helpful for solving that sort of
| thing when it occurs (and if the use case is even
| substantial enough to warrant it) and Lit looks like it
| would fit that role reasonably well, but basing the entire
| site on this principle as a full on framework seems a bit
| ludicrous.
|
| What html actually lacks is the option to include external
| html part files, but there are lots of ways to do that
| serverside that don't involve the stupid idea of putting
| html into strings in js files for literally everything.
| moreira wrote:
| It's a good way for people to revisit the current status quo
| and avoiding cargo cult. Frameworks are useful, but there's
| definitely an element of cargo cutting going on in the JS
| ecosystem whereby no matter what the requirements, you just
| reach for React/Vue. We're getting to a point where almost
| nothing that uses JS gets built without a frontend framework
| (and all its weight) anymore.
|
| One thing that's easy to notice from reading the code is that
| so much of the code takes inspiration from the frameworks
| themselves. How the code is organised - the state store, the
| render function, the computed getters, the mutation methods,
| it's all there. It's clean.
|
| Perhaps the main benefit of frameworks is that they've taught a
| whole generation of JS developers how to organise their code in
| a way that can scale to bigger, more complex apps (vs. how easy
| to make a mess of things in the jQuery days).
|
| -
|
| Having said that, I do agree with your point about things
| getting more complex: This is a properly specced, easy to grasp
| project. Throw in stakeholders and PMs needing to add
| functionality and requirements changing, and this system might
| start to struggle. Not to mention the cost of onboarding new
| developers. I feel like that's the best thing about frameworks
| in any language; when you jump into a new project you know more
| or less how everything is organised and where things are
| supposed to be, and you can get going fairly quickly.
| mch82 wrote:
| Building on your comment, frameworks have described
| themselves as "polyfills". Polyfills used to be libraries
| that added modern browser features to old browsers. Then,
| Angular and React began using polyfills to add future
| features to modern browsers. The intent was always
| communicated as "some day we won't need this because it's
| built in to HTML5 and when that happens your initial payload
| will be smaller". Typescript has had similar effect on
| JavaScript language features and syntax.
|
| This rewrite of the Vanilla JS TodoMVC is a great
| illustration of how far things have come.
| ericsilly wrote:
| My app CardBoard (https://www.cardboard.team/) is no-framework
| vanilla js. This is a large-ish codebase with a lot of
| functionality, and the same code is wrapped with apache cordova
| for both iOS and Android apps. In 2022, browser-native
| WebComponents (addresses encapsulation, code organization, and
| re-use) with no frameworks is a hill I'd die on.
| ghubcoder wrote:
| I get this running it in chrome Uncaught
| SyntaxError: Missing initializer in const declaration (at
| helpers.js:4:14)
|
| Installed and ran with: npm install npm run
| start
|
| Any idea what went wrong...?
| ricardobeat wrote:
| The assignment (=) is missing from those const declarations,
| except for the first one; I guess they were hastily converted
| from function declarations to satisfy modern tastes.
| grabanski wrote:
| Oops, yeah I just accepted a pull request from the community
| that broke my helpers module declarations. Just fixed it,
| thanks for noticing!
| gherkinnn wrote:
| A good exercise, well executed.
|
| While I would rather nail my bollocks to the ceiling than build a
| vanilla application (in any stack), there's no denying the
| benefit revisiting the basics.
| krembanan wrote:
| Yeah, that's exactly what I would imagine vanilla js code look
| like, and I'm glad we moved on to frameworks. Just this small app
| seems not so fun to maintain
| blowski wrote:
| Yep, it's a really nice demo for how to use JavaScript. But
| it's not a valid criticism of Vue, React, Svelte because it's
| solving a very simple problem. The reason for those frameworks
| becomes clear when you have multiple people maintaining it and
| adding features.
| [deleted]
| lelandfe wrote:
| Oh, hey! This is from the founder of Frontend Masters - easily
| the best FE resource I've ever found:
| https://frontendmasters.com/. Their content creation process is
| pretty nifty: they run live workshops regularly that subscribers
| can join, and the footage from the workshops ultimately gets cut
| and turned into the tutorials.
|
| Had no idea who was behind it, but I love that they're still
| contributing back like this.
| grabanski wrote:
| Ah, thanks for the plug!! I did this as a fun little weekend
| project, glad people are finding it useful as a reference of
| how simple vanilla JS can be these days. :-)
| msoad wrote:
| This code reminds me of Backbone. I think we all started here and
| then abstracted event handling and reactivity into a tiny
| framework like Backbone.
|
| React and other declarative approaches are inherently different.
| In React I hardly think of when my component renders. In Backbone
| days, I remember having to debug why some part of code is not
| running when I'm expecting it to run. React does this really
| well.
| steve_adams_86 wrote:
| A cool thing about react is that it's easy to reason about as
| well. The reconciliation algorithm is fundamentally pretty
| simple and there isn't any magic happening.
|
| It can get confusing to track down unexpected renders when you
| think the result of the algorithm should be different, but
| that's not really an issue with react so much a the nature of
| managing complex state, memoization algorithms which
| potentially use different diffing strategies, and logic which
| might be mutating state in ways you don't quite expect, and so
| on.
|
| People criticize these front end libraries but I'm still
| impressed by how well state management has been integrated into
| such extensible and scalable view layers.
| listless wrote:
| The code here is clean, well written and honestly not that much
| more verbose than many of the framework ones. I also found it
| simple to understand.
|
| Would you need a "framework" when an app gets beyond TODO? I
| think you would need to start refactoring your code to be more
| framwork-like. But this is something we don't do, and I would say
| would even be considered "anti-pattern".
| mch82 wrote:
| My bet is that as soon as someone popularizes a way to manage
| state across a set of web components the pendulum will swing
| back to the "Vanilla JS" approach. It's so nice to work on web
| apps without having to install NodeJS, builders, cli tools, and
| so on. And it encourages software engineers to learn the web
| platform APIs instead of learning frameworks.
|
| HTML and CSS are actually quite nice to work with, given modern
| browser developer tools. Much simpler to work with when they
| are literal files.
|
| It wouldn't surprise me if people continue to compile other
| languages to JavaScript or WASM though. It seems reasonable a
| Java developer might like to work in Java or a Ruby developer
| in Ruby instead of writing JavaScript. But I don't understand
| how people feel confident writing web applications if they
| don't take the time to understand CSS, HTML, or the browser
| APIs.
| mmcnl wrote:
| How many people who are critical of the current state of JS
| actually use it on a daily basis? Modern frameworks like React
| and Vue don't exist to fill in the gap left by native JS, they
| exist so that you write your application in a declarative way
| where the view is rendered as a function of state. This relieves
| the developer of keeping track of DOM state, as you only declare
| the render function once, and after that you only need to manage
| state.
|
| If anything, modern frameworks tend to build as much upon the
| native functionality that is available. This reduces bundle sizes
| and increases performance. It's an abstraction on top of the
| browser capabilities, not a clone.
|
| Now, onto the code itself. The author claims it is "pretty
| simple" to build "fairly complex things". He backs up the claim
| by stating it took only 60 minutes to write this app.
|
| First, I would be careful to claim things are easy or difficult.
| This is very subjective, and phrased in the wrong way it can also
| come across as arrogant.
|
| Second, the app is not simple. Looking at the code the author
| created his own DOM abstraction. The current abstraction is only
| proven to work for a simple to do app.
|
| Third, a to do app is not a "complex thing". Not even remotely.
|
| It's a nice exercise, but the conclusion drawn by the author
| aren't valid.
| klabb3 wrote:
| > React and Vue [...] exist so that you write your application
| in a declarative way where the view is rendered as a function
| of state
|
| Exactly. To elaborate, here's the big, big caveat in a
| miniature form:
|
| https://github.com/1Marc/todomvc-vanillajs-2022/blob/854dd40...
|
| Note that this clears and recreates the DOM on every action (eg
| mark complete), and DOM ops are the most expensive ones. This
| is a sound strategy for vanilla JS, because the alternative is
| mutating the DOM and keeping it in sync which is error prone to
| put it mildly.
|
| I use frameworks very sparingly, and am always cautious with
| deps. But a reactive UI/diff engine is non-negotiable for me.
| brrrrrm wrote:
| I wrote a video editor in vanilla JS
| https://github.com/bwasti/mebm
| skybrian wrote:
| It would be a different demo, but this could be made fairly
| modern with some lightweight tooling and dependencies:
|
| - Use esbuild to bundle the app. - Now you can change the file
| extension and switch to Typescript. (Esbuild doesn't check the
| types, but VS Code will.) - Then change the file extension to tsx
| and use Preact.
|
| I'm writing a little app this way and it seems quite nice. I
| don't think I'm missing anything?
| 1marc wrote:
| Agreed, esbuild is nice. And adding TypeScript at some type of
| scale probably makes sense. Not sure where that line is, but in
| this simple example I'm trying to avoid all external tools.
| randomfool wrote:
| Please do not re-implement HTML sanitization. Just replace that
| escapeForHTML and innerHTML assignment with a later textContent
| assignment. Please. Pretty please.
| grabanski wrote:
| That seems like a good improvement. Pull requests welcome!
| grabanski wrote:
| How does this look? https://github.com/1Marc/todomvc-
| vanillajs-2022/commit/d38e5...
| simooooo wrote:
___________________________________________________________________
(page generated 2022-05-07 23:01 UTC)