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

nomplate

v1.3.28

Published

Nomplate: Node template engine

Downloads

35

Readme

Nomplate

(pronounced, Gnome-plate)

Nomplate is a microscopic (< 6kb), insanely fast (<30ms to interaction) client and server side template engine and component system that makes it dead simple to create, compose, test and deploy visual components using Plain Old JavaScript wherever it runs.

Gnome Plate

What does it look like?

/src/key_presses.js

const dom = require('nomplate').dom;

const keysPressed = [];

// Define the render function.
function keyPresses() {

  // Return a nomplate element with zero or more children.
  return dom.div((update) => {
    function onKeyUp(event) {
      console.log('onKeyUp with:', event.keyCode);
      keysPressed.push(event.keyCode);
      // Schedule a re-render from the outer div in.
      update();
    }

    dom.input({type: 'text', onkeyup: onKeyUp});
    dom.ul({className: 'my-list'}, () => {
      keysPressed.forEach((keyCode) => {
        dom.li(keyCode);
      });
    });
  })
}

module.exports = keyPresses;

Every HTML node name is available on the dom object as a method (e.g., div, span, li, ul, section, header, footer, etc.).

The method signature can accept attributes, text content or a handler that itself calls more methods on dom. These arguments are optional, starting on the left in order to make callers more succinct.

If nested handlers declare a parameter, they will be sent a method that, when called will schedule a re-render of the associated component and it's children.

// Attributes and children
dom.div({className: 'abcd'}, () => {
  // Just text content
  dom.div('Some Text Content');
  // Just attributes
  dom.div({className: 'fake-attr'});
  // Just children
  dom.div((update) => {
    dom.span('Now: ' + Date.now());
    // Re-render every second
    setTimeout(update, 1000);
  });
});

Configure your Express server:

const express = require('express');
// NOTE: nomplate/express is required independently in order to avoid
// polluting the client binary with functionality that is only relevant
// on the server.
const nomplateExpress = require('nomplate/express');

const app = express();

// Configure static files from dist
app.use('/static', express.static('dist'));

// Configure Nomplate
app.engine('.js', nomplateExpress);
app.set('view engine', 'js');
// Configure the default layout (/views/main.js)
app.set('view options', {layout: 'main', pretty: process.env.NODE_ENV !== 'production'});
app.set('views', path.resolve(__dirname + '/views'));

// Create a route and return a named template at /views/app.js
app.get('/', (req, res) => {
  res.render('app');
});

app.listen(8080, () => {
  console.log('Listening on localhost:8080');
});

The /views/main.js layout:

const dom = require('nomplate').dom;

function main(options, renderView) {
  return dom.html({lang: 'en'}, () => {
    dom.head(() => {
      dom.meta({charset: 'utf8'});
      dom.title('Nomplate Test');
      dom.link({rel: 'stylesheet', href: 'static/some-styles.css'});
      dom.script({src: '/static/some-bundle.js', type: 'text/javascript'});
    });
    dom.body(() => {
      // This call will render the selected view.
      renderView();
    });
  });
}

module.exports = main;

The /views/app.js template

const dom = require('nomplate').dom;

function app(options) {
  return dom.section({id: 'my-app'});
}

module.exports = app;

Configure the client

const keyPresses = require('./src/key_presses');
const ready = require('nomplate').ready;
const renderElement = require('nomplate').renderElement;

// Elements can be created immediately (i.e., before the entire page loads).
const element = renderElement(keyPresses(), document);

ready(document, () => {
  // Wait for page load before attaching elements:
  const parent = document.getElementById('my-app');
  parent.appendChild(element);
});

TODO MVC?

Here's an early prototype of the famous TODOMVC application implemented as a fully client side Nomplate application.

Get a reference to a real DOM element

const dom = require('nomplate').dom;

function myView(options) {
  function onHeaderRendered(elem) {
    console.log('header elem:', elem);
    elem.textContent = 'Hello World';
  }

  return dom.div({id: 'my-view'}, () => {
    // The provided function will be given a reference to the element
    // after the element is updated.
    dom.h1({onRender: onHeaderRendered});
  });
}

module.exports = myView;

Here are some highlights:

  • 6kb minified and gzipped for the entire library AND application
  • < 80ms time to fully rendered and interactive application
  • Fully unit tested with tests that finish in around 100ms
  • Components are composable and easily comprehensible

Contributing

The build system is only proven to work on Linux and OS X, though it may work on Windows if your path and Node are configured properly.

mkdir nomplate
cd nomplate
git clone https://github.com/lukebayes/nomplate.git .
source setup-env.sh
make dev-install
# Wait for node and npm modules to be installed
source setup-env.sh # Yeah, do it again...
make test

Watch files for changes and run tests on change:

make test-w

Lint all files:

make lint

Build a distributable library into "dist" folder:

make build

Remove all artifacts

make clean