DEV Community

artydev
artydev

Posted on • Edited on

MVU library

MVU is a little wrapper around some functions coming from functions coming from different libraries :

m (wrapper around make in DML)

return a function which creates an element, and append it to the current base

dom (selectBase in DML)

Select a position to append the following objects

udom (unselectBase in DML)

Release position to the previous context

observable

Creates a new observable, returns a function which can be used to get the observable's value by calling the function without any arguments and set the value by passing one argument of any type.

morphdom

Fast and lightweight DOM diffing/patching (no virtual DOM needed)

Demo

<div>id='app'></div>

Here we create a 'h2 element creator' function named h2.

We then use this function to create an actual 'h2' element.

We finally append this element to a div tag which id is 'app'

  import "https://cdn.jsdelivr.net/gh/artydev/mvu@DMLMorph/dist/mvu.es.js";

  let h2 = m("h2")

  dom(app)
    let title = h2("Hello MVU");
    title.style.color = "orange"
  udom()

You can test it here : demo

See you for the new post...

Top comments (9)

Collapse
 
artydev profile image
artydev

Hy Eckehard,

Thank you very much for paying attention to MVU

MVU library as changed a little, since that article.
The latest version is here MVU

For now I did not used typescript, I simply use the 'ts' extension for convenience.

I must also clean MVU.

I would be glad if you could give an eye to it

MVU server totally my needs, it's small and can be integrated directly from CDN.

Concerning the evolution DML/REACT, good idea.

It would effectively nice to replace JSX, in fact I already thought of this, when I tried to use ASTRO a static site generator...

It's a real challenge, If I can help you in any way, don't hesitate to contact me...

Regards

Collapse
 
efpage profile image
Eckehard • Edited

You wrote:

For now I did not used typescript, I simply use the 'ts' extension for convenience.

That´s strange, as in your examples "mvu.umd.min.js" is used as a script name. Looks like a compiled version of mvu.ts ?!?

Could you also explain the last statemens in mvu.ts?

const MVU = { m, dom, udom, render, html }
globalThis["MVU"] = MVU;
Enter fullscreen mode Exit fullscreen mode

As far as I understand, this will give you access to your functions via

    MVU.render()
Enter fullscreen mode Exit fullscreen mode

You could achieve this also using the ES6-module sytax import { MVU } from MVU.js, which is a bit less "hacky".

Better code organization

If you want to support the DML project, you can help me to find a better module structure. This would apply to your MVU-project as well. I decided not to use ES6-modules, as the module syntax forces you to export every single definition. DML was meant to act like a "language extension", so there would be a long very list of exports.

Importing via import * as DML from "DML.js" would force me to use the following syntax:

DML.h1("Headline",DML._box) 
Enter fullscreen mode Exit fullscreen mode

This is not desireable, as it would make the code nearly unreadable.

We could also use the window[] or globalThis[]-object to male all the DML-properties and functions global:

    import * as DML from "DML.js"
    window["h1"] = DML.h1
Enter fullscreen mode Exit fullscreen mode

This could be automated, but prevent any tree shaking.

My target is to use any DML function or definition without any manual import definition. But there should be a final process to remove all the dead code from the final project. The current DML-file is about 75 kB of code, but in most cases only a small fraction is really used.

Currently I´m checking esbuild.js as a "compiler". If there is any suggestion, this would really be great.

Collapse
 
artydev profile image
artydev • Edited

Hi Eckehard,

vitejs, the bundler used for MVU project, manage to translate TS files to JS files automatically at build times.

In the same project, you can perfectly mix TS and JS, vite will do the job.

In a TS file you can code in plain JS, only the Editor will complain, the build will run without any problem (unless you configure the builder to be strict)

const MVU = { m, dom, udom, render, html }
is equivalent to :
cont MVU = { m:m, dom:dom, udom:udom; html:html }

when the name of the keys and the names of the values are the same,
you can omit the values.

globalThis is an alias for "window"
so
globalThis["MVU"] = MVU, <=> window["MVU"] = MVU

Hope this helped

Regards

Thread Thread
 
efpage profile image
Eckehard • Edited

Ok, that explains a lot. Vite relies on Esbuild, which works really fine.

So, this enables you to use the commands directly

const {
      dom,
      udom,
      m,
      html,
      render,
  } = MVU;

  let h1 = m("h1");
Enter fullscreen mode Exit fullscreen mode

I did not know this works, nice! Why did you not apply the commands directly in MVU.ts ?

globalThis["m"] = m
globalThis["dom"] = dom
globalThis["udom"] = udom
globalThis["render"] = render
globalThis["html"] = html
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
artydev profile image
artydev • Edited

:-) glad you like it.

I simply wanted to avoid polluting global namespace and exporting only MVU (or DML)

Thread Thread
 
efpage profile image
Eckehard • Edited

It seems, this does the trick to use ES6-modules in the "recommended" way:

    import * as dml from "./dml.js"
    Object.assign(globalThis, dml)  // -> expose all definitions to the global Namespace
    h1("This is DML")
Enter fullscreen mode Exit fullscreen mode

It just comes with two drawbacks:

  • ES6-modules do not run locally, a web server is required
  • At least for DML, the export list is a mess. This is definitively not helpful and there are still definitions missing. This will also prevent tree shaking:
export {_base, _baseStack, _block, _onresizeElements, getLanguage, autobind, call, _import, loadCSS, extract, fitSelector, extractFit, joinOver, pretty, addPre, round, trunc, floor, exp10, log10, inRange, constrain, min, max, getMin, getMax, px, getpx, arrayvalue, smooth, smooth2, extractFilename, debounce, isTouchDevice, isMobileDevice, _init, setOptions, dragElement, selectBase, getBase, DMLgetSP, DMLsetSP, DMLchkSP, checkSP, unselectBase, chk_node, textNode, setAttributes, createAt, appendBase, _appendBase, make, addProps, putProps, appendChilds, elementById, br, nbsp, h1, h2, h3, h4, h5, h6, image, span, link, div, idiv, sdiv, sidiv, overlay, button, rbutton, textarea, expandableTextarea, println, label, blocktext, inputSelect, checkbox, inputText, inputNumber, msgBox, askBox, canvas2D, svg, svg_line, fieldset, radio, RadioValue, selectedRadioItem, setRadioValue, setRadioIndex, dml_fetch, exec_async, httpGet, httpGet2, sqliteGetTableNames, sqliteGetKeys, sqliteGetTable, slider, registerOnresize}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
artydev profile image
artydev

Thanks Eckehard,

Indeed to much stuff on export....

Thread Thread
 
efpage profile image
Eckehard

Yes, no satifying solution. The best thing would be to have a compiler, that excludes all the dead code.

Collapse
 
efpage profile image
Eckehard • Edited

Hy artydev,

i was looking for a link to github.com/artydev/mvu/blob/main/s..., it was not in the links above. Maybe you coud update the links.

Nice you adopted the core approach of DML, I´m thinking about the future of DML too. The initial version contains still a lot of "convenience" stupp which makes it a bit bulky. I have been working on compiled languanges too long, there you do not care for this overhead. Maybe we can do some tree shaking in the projects? This would make things much easier.

I suppose, using Typescript will enable tree shaking somehow (and minifying), but this will make the JS-code nearly impossible to read (which is also welcome to protect your interlectual property). Do you have any experience with debugging TS-code?

The MVU-aproach goes down to the bare metal, which might also not server for all cases. But I will check out your work in detail. Can you give some details about your toolchain, is it just TS?

So, what about the future?

The core approach of DML serves very well in my projects and Im totally sure that using JS to create the DOM solves the main issues of the current web. Did you read my post about reinventing the wheel again and again?.
The source of DML definitively needs some update. And possibly a new structure, that makes it easier to include the necessary codes without the overhead. A preprocessor would definitively have some advantages.

On the other hand: there is definitively a place for REACT, as this makes state management much easier. Given, we do not like JSX and the mixture of languages it provides? JSX is not REACT, so it should be possible to use the DML-approach in REACT too? We can also use morphdom, but there are far more people using REACT. So, maybe we can set up a REACT-version of DML? Or even a mixed approach, where you can decide to update the DOM directly or use the VDom as a double buffer. Maybe selectbase could be extended to apply to DOM nodes and to REACT-nodes? This would enable both approaches side by side. What do you think?