Mithril.js: Official component/utility library

Created on 5 Nov 2018  ·  7Comments  ·  Source: MithrilJS/mithril.js


Updates

  • Add query string utils to the list of things to pull out.
  • Add request utils to the list.
  • Add hydration to the list.
  • Strike a sentence that's no longer true.

Now that we're starting to see several common themes, I don't think it'd be a terrible idea to start having an official userland component/utility library for the common requests and things otherwise broadly useful. For example:

  • Async: See #2282. It simplifies async view loading to something that's a lot easier to use.
  • Route: The router itself might qualify for inclusion here if we go for #2281.

    • m.buildQueryString and m.parseQueryString should be transferred with this - they're not broadly useful outside routing.

    • Link: For the common case of m("a", {oncreate: m.route.link(opts = {})}), a lot of people (me included) would like to see an easier way of specifying links than this verbosity. This one is probably the only one that really merits core inclusion, though.

  • SelfSufficient: We've decided that it belongs in userland, but there's been so many requests for this both here and on Gitter for subtree management that I feel it needs a more centralized home.
  • stream: Mithril's streams library really belongs here, not necessarily at the top level.
  • Request: Mithril's request library, m.request/m.jsonp, could fit here, if we want to keep most of the batteries out of core.

    • A lot of people are good enough with just using fetch, so I'm not sure this is as broadly useful in core as it used to be. If you're stuck on IE, you of course would still appreciate this.

  • hydrate: We've decided it's probably not ideal to include in core, but it'd definitely be worth having at least supported in some official capacity.

    • We also need to ensure that 1. the DOM is what we expected (and patch it if it isn't), and 2. our internal state is initialized correctly.

    • We'd have to replace text nodes in any case where we have either multiple text nodes or a child component.

    • This would likely have to directly manipulate some internal stuff if we hope for it to be reasonably fast.

    • Or in other words, it's non-trivial and it probably doesn't belong fully in userland.

Each of these would be distinct utilities out of core, not shipped with the main bundle. This would almost function like Mithril's "standard library", basically anything that doesn't belong in Mithril itself, but is still useful nevertheless.

My thought is adopting mithril/util/${module} for each of these, where mithril/util re-exports everything. Of course we currently do have such a subfolder, but we could rename that to core-util, things we ship with the main bundle, to make room for this new namespace. Edit: removed as of #2317.

MetFeedback

Most helpful comment

Just to chim in my support, I'd very much love to have a hydrate util. It'd make things easier to build a hybrid SPA/SSR app with Mithril and mithril-node-render.

All 7 comments

@orbitbot How broadly useful is that? I'd rather keep our bar high here, and m.request is simple enough most of us just use it directly. I would consider a PR that adds those common aliases to m.request as long as you keep the existing m.request.METHOD(url)/m.request.METHOD({url, ...opts}), but I don't see why a simple wrapper would be a good standard library entry.

It wasn't a strong suggestion, mainly one of convenience in that it's easy to provide default options and add code that is run every time a request is made.

I would love to see some component / util library in place for mithril. Even if some approaches might be opinionated, i think it will help every new comer to wrap the head around some basic concepts and its pro/cons. Me personally, i had to implement a multilingual page. This sound easy, but the translations needed to be available for server side rendering and i made some big mistakes while implementing it and some pages got rendered in the wrong language... i would love to share my approach within a common mithril library.

@ChrisGitIt This component library wouldn't include any UI components, at least initially. It'd start out purely control- and API-related.

As for I18n, Mithril is itself massive overkill. You'll have better success using a library (like any of these) or a quick hack, and each of these will work flawlessly on server-side, too. Plus, i18n("label") is a lot more concise than m(I18n, {label: "label"}).

In case you're curious how simple that above i18n function can be:

function i18n(label) { return i18n.db[i18n.locale || "en"][label] }
i18n.locale = "en"
i18n.db = {}
// Set the current locale using this:
i18n.locale = "es"
// Add keys like this:
i18n.db["en"] = {hello: "Hello!", bye: "Goodbye!", ...}
i18n.db["es"] = {hello: "¡Holá!", bye: "¡Adiós!", ...}
i18n.db["jp"] = {hello: "お早う!", bye: "左様なら!", ...}

Of course, it's very simple and it doesn't support things like pluralization, but you get the point.

Hi @isiahmeadows,

and thanks for your infos. I actually thought more about the "dynamic" problems that do arise while working with translations (mostly SSR concerns) and SPAs.

So here are some "problems" that will arise if not properly approached (like i did):
1: Loading ALL translations while APP is starting up, quickly becomes massiv overkill (my current translations are about 50 KB, but there are 7 translations ... so bundling localization (webpack and alike) files should be avoided (bad startup time, longer parsing time (especially on "older" devices ... like 3 year old iPads) etc.).
=> I'm currently using a "onmatch" route component that loads the language dynamically.

2: Using a dynamic loading approach might be easily possible on the client, but if you are on the server (SSR), the translations need to be encapsulated AND the encapsulated translations needed to be passed to every component that needs it (otherwise, it might happen server side that "en" is loading, but "de" is loaded quicker and then the translation is a different one... was this understandable? Took me some time to see my implementation flaw ...

3: ... some more problems that i do not (want) to remember ;-)

So i think it would be nice to have component/util library that is not only a pure "plug&play" but also shows some drawbacks and possible solutions to integrate with mithril (like using the "onmatch" route component).

Just to chim in my support, I'd very much love to have a hydrate util. It'd make things easier to build a hybrid SPA/SSR app with Mithril and mithril-node-render.

Was this page helpful?
0 / 5 - 0 ratings