npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

emjay

v0.3.0

Published

Convert Jade templates to Mithril virtual DOM structures

Downloads

13

Readme

emjay

Convert Jade template snippets to Mithril virtual DOM

What's this?

Mithril is fantastic at expressing DOM as a function of state & input, but the structural requirements of DOM - often dictated by esoteric accessibility and styling concerns - don't play well at scale with the punctuation of JS. One of the worst things in Mithril is reading (let alone debugging!) a mismatched closing bracket in a structure like this:

      } )
    ] )
  )
}

Necessarily complex DOM can end up sharing the appearance of the pyramid of doom.

Indentation isn't so much of a problem in strucural code (the 'pyramid' is only a problem in code if the glaring indentation is useless or counter-intuitive in interpreting the meaning of the code it shapes), but trailing brackets are especially ugly and unhelpful in reading view functions.

That's why 'designers love HTML'

Traditionally the DOM has always been a dynamic abstration of structures written in HTML, so you can understand why people feel comfortable sticking to HTML-like representations such as JSX. Closing tags solve the problem of noisy and semantically ambiguous closing tokens by providing big fat tokens that clearly label the thing being closed. Our example above would look like this, which is far more meaningful:

      } }
      </input>
    </label>
  </form>
}

If you like the sound of that, use MSX.

But I contest the idea that XML-like languages are the best idiom for view functions: XML notation promotes tag structure to excess, drowning out the salient points of logic and dynamic interpolation with semantically slim but visually heavy tags. It's ironic that XML-like JSX was introduced alongside ES6 features: ES6 arrow functions allow you to express a function minimally (input => output), freeing us from having to write function and return everywhere, focusing instead on the contents and behaviour. In contrast, XML is downright regressive. Far better would be to omit structural closing tags altogether:

      } }
}

How?

The first argument accepted by m recognises that XML is too verbose, and uses well-known and intuitive CSS selector syntax to express the static aspects of tags instead. This isn't new: Jade, a very popular back-end templating language for Node, was doing this ages ago. Jade uses indentation alone to determine nesting.

Emjay uses the same lexer and parser as Jade, and converts the output into a Mithril virtual DOM structure.

Use it as an ES6 template tag function for minimal punctuation:

import j from 'emjay'

export default {
  view : ( ctrl, { inputs } ) => j`
    h1#title.
      The forest, and the trees

    form( target='postbackFrame' )
      ${ inputs.map( input =>
        j`
          label
            | ${ input.name }
            input( value=${ input.value } )
        `
      ) }

    h2.
      Clarity of structural content and logical expression in harmony

    iframe( name='postbackFrame' )
  `
}

What's the catch?

  • No tests!
  • It's currently impossible to fold JS non-primitives (objects and functions) as attributes into nodes opened in Jade syntax. I'm working on it!
  • This places source code elegance above performance. Running this in production means parsing text as Jade & converting it into virtual DOM on every view execution. Ideally this function would be partially pre-compiled according to similar principles as Pat Cavit's Mithril objectify