• Stars
    star
    188
  • Rank 205,563 (Top 5 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created about 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Build JSX structures, then decide at runtime which pragma you want to use to render them.

JSX Pragmatic

build status code coverage npm version

  • Build JSX templates
  • Decide at runtime how you want to render them
  • Easily build custom renderers - render to HTML, DOM, or anything else!

Because JSX is pretty useful, even without React!

Build an abstract jsx component

First we'll build a small component. We're not tying ourselves to any particular framework yet, or any render target.

/* @jsx node */

import { node } from "jsx-pragmatic";

function Login({ prefilledEmail }) {
  return (
    <section>
      <input type="text" placeholder="email" value={prefilledEmail} />
      <input type="password" placeholder="password" />
      <button>Log In</button>
    </section>
  );
}

Render on the server

Let's say we're on the server-side, and we want to render the jsx to html to serve to a client. Just pass html() to the renderer:

/* @jsx node */

import { node, html } from "jsx-pragmatic";
import { Login } from "./components";

function render() {
  return (<Login prefilledEmail="[email protected]" />).render(html());
}

Render on the client

Now let's render the same jsx template on the client-side, directly to a DOM element:

/* @jsx node */

import { node, dom } from "jsx-pragmatic";
import { Login } from "./components";

function render() {
  return (<Login prefilledEmail="[email protected]" />).render(dom());
}

Render in a React app

Or if we're using the same component in React, we can render it as a React component:

/* @jsx node */

import { node, react } from "jsx-pragmatic";
import { Login } from "./components";

function render() {
  return (<Login prefilledEmail="[email protected]" />).render(react({ React }));
}

Render in a Preact app

Or if we're using the same component in Preact, we can render it as a Preact component:

/* @jsx node */

import { node, preact } from "jsx-pragmatic";
import { Login } from "./components";

function render() {
  return (<Login prefilledEmail="[email protected]" />).render(preact({ Preact }));
}

Write your own renderer

Renderers are just functions!

  • Write a factory like customDom. This will take some options and return our renderer.
  • Return a renderer which takes name, props and children and renders them in whatever way you want!

This example renders the jsx directly to DOM elements:

/* @jsx node */

import { node, NODE_TYPE } from "jsx-pragmatic";
import { Login } from "./components";

function customDom({ removeScriptTags } = { removeScriptTags: false }) {
  let domRenderer = (node) => {
    if (node.type === NODE_TYPE.COMPONENT) {
      return node.renderComponent(domRenderer);
    }

    if (node.type === NODE_TYPE.TEXT) {
      return document.createTextNode(node.text);
    }

    if (node.type === NODE_TYPE.ELEMENT) {
      if (removeScriptTags && node.name === "script") {
        return;
      }

      let el = document.createElement(node.name);

      for (let [key, val] of Object.entries(node.props)) {
        el.setAttribute(key, val);
      }

      for (let child of node.children) {
        el.appendChild(child.render(domRenderer));
      }

      return el;
    }
  };

  return domRenderer;
}

Then when you're ready to use your renderer, just pass it into .render() and pass any options you want to use to configure the renderer.

function render() {
  return (<Login prefilledEmail="[email protected]" />).render(
    customDom({ removeScriptTags: true })
  );
}

Use Fragments

You can either import Fragment from jsx-pragmatic:

/* @jsx node */

import { node, Fragment } from "jsx-pragmatic";

function Login({ prefilledEmail }) {
  return (
    <Fragment>
      <input type="text" placeholder="email" value={prefilledEmail} />
      <input type="password" placeholder="password" />
      <button>Log In</button>
    </Fragment>
  );
}

Or use the @jsxFrag comment, and the new <> </> syntax for Fragments, providing you're using Babel 7:

/* @jsx node */
/* @jsxFrag Fragment */

import { node, Fragment } from "jsx-pragmatic";

function Login({ prefilledEmail }) {
  return (
    <>
      <input type="text" placeholder="email" value={prefilledEmail} />
      <input type="password" placeholder="password" />
      <button>Log In</button>
    </>
  );
}

Why?

JSX is a neat way of parsing and compiling templates to vanilla javascript. Right now most people use JSX with React. But in reality, the technology is decoupled enough from React that it can be used to render anything:

  • HTML
  • XML
  • DOM Nodes

This library helps you do that.

Can't you do that with Babel?

Yep, Babel provides a neat pragma option which lets you choose what your jsx is compiled to; if you don't want to use React.createElement, you can write your own pragma to convert the jsx to anything else.

The only problem with that is, the decision of which pragma to use is made entirely at build-time. Let's say you have a template which needs to be:

  • Rendered as an html string on the server side.
  • Rendered directly as a DOM element in some client environments.
  • Rendered as a React component in other client environments.

jsx-pragmatic helps you achieve that by allowing you decide when you render what your jsx should be transformed into.

It also abstracts away some of the stuff in jsx that's a little tricky to deal with; like nested children arrays, dealing with basic element vs function components, and fragments -- leaving you to focus on the renderer logic.

Quick Start

Install

npm install --save jsx-pragmatic

Getting Started

  • Fork the module
  • Run setup: npm run setup
  • Start editing code in ./src and writing tests in ./tests
  • npm run build

Building

npm run build

Tests

  • Edit tests in ./test/tests

  • Run the tests:

    npm run test

Testing with different/multiple browsers

npm run karma -- --browser=PhantomJS
npm run karma -- --browser=Chrome
npm run karma -- --browser=Safari
npm run karma -- --browser=Firefox
npm run karma -- --browser=PhantomJS,Chrome,Safari,Firefox

Keeping the browser open after tests

npm run karma -- --browser=Chrome --keep-open

Publishing

Before you publish for the first time:
  • Delete the example code in ./src, ./test/tests and ./demo
  • Edit the module name in package.json
  • Edit README.md and CONTRIBUTING.md
Then:
  • Publish your code: npm run release to add a patch
    • Or npm run release:path, npm run release:minor, npm run release:major

More Repositories

1

kraken-js

An express-based Node.js web application bootstrapping module.
JavaScript
4,948
star
2

zoid

Cross domain components
JavaScript
2,008
star
3

lusca

Application security for express apps.
JavaScript
1,787
star
4

post-robot

Cross domain post-messaging on the client side using a simple listener/client pattern.
JavaScript
734
star
5

kappa

A hierarchical npm-registry proxy
JavaScript
557
star
6

swaggerize-express

Design-driven apis with swagger 2.0 and express.
JavaScript
354
star
7

grumbler

A template for writing distributable front-end javascript modules.
JavaScript
292
star
8

beaver-logger

Client-side logging w/ super powers
JavaScript
252
star
9

hapi-openapi

Build design-driven apis with OpenAPI (formerly swagger) 2.0 and hapi.
JavaScript
210
star
10

express-enrouten

An express route initialization and configuration module.
JavaScript
172
star
11

levee

A circuit-breaker pattern implementation with fallback support.
JavaScript
171
star
12

fetch-robot

Proxy fetch through an iframe
JavaScript
157
star
13

makara

An internationalization module for kraken and express
JavaScript
135
star
14

cross-domain-utils

Cross Domain utilities
JavaScript
131
star
15

adaro

A Dust.js view renderer for express
JavaScript
127
star
16

kraken-example-with-shoppingcart

An example Kraken app showing off a shopping cart
JavaScript
116
star
17

generator-kraken

Yeoman generator for kraken.js apps
JavaScript
110
star
18

jwt-csrf

Stateless CSRF protection using jsonwebtoken (JWT)
JavaScript
108
star
19

shush

A simple module for reading JSON files that may have comments.
JavaScript
92
star
20

meddleware

Middleware configuration for express.
JavaScript
88
star
21

generator-swaggerize

Yeoman generator for design-driven apis with swagger 2.0 and krakenjs/swaggerize tools.
JavaScript
70
star
22

confit

Environment-aware configuration.
JavaScript
61
star
23

zoid-demo

A clonable demo project for xcomponent
JavaScript
61
star
24

swaggerize-routes

Swagger document driven route builder.
JavaScript
58
star
25

zalgo-promise

Release zalgo with synchronous promises
JavaScript
57
star
26

shortstop

Enables use of protocols in configuration.
JavaScript
55
star
27

kraken-example-with-passport

An example integrating kraken with passport authentication
JavaScript
53
star
28

caller

A node module for enabling a module to determine its caller.
JavaScript
47
star
29

nemo

node.js selenium-webdriver/mocha based combined testing framework
JavaScript
43
star
30

kraken-devtools

Development-time tools for kraken.js applications.
JavaScript
40
star
31

cross-domain-safe-weakmap

Cross-domain safe WeakMap shim
JavaScript
33
star
32

grabthar

Hot install and activation of npm modules
JavaScript
23
star
33

karka

A simple rule parser
JavaScript
21
star
34

belter

Miscellaneous browser utilities
JavaScript
17
star
35

good-influxdb

HapiJS good-reporter for use with InfluxDb
JavaScript
16
star
36

angular-remove-di-loaders

Webpack loaders to remove Angular DI (Dependency Injection)
JavaScript
16
star
37

freshy

An (admittedly naïve) node module (un|re)loader/refreshener.
JavaScript
15
star
38

endgame

A tiny module for ensuring uncaught exceptions are handled in Node.js
JavaScript
15
star
39

shortstop-handlers

Common protocol handlers for use with the shortstop node module.
JavaScript
15
star
40

passport-saml-encrypted

A strategy for Passport authentication that supports encrypted SAML responses
JavaScript
14
star
41

pine

A logging wrapper for winston.
JavaScript
14
star
42

react-redux-krakenjs-swaggerize-express

React client app, redux stage management, passport oauth2, paypal rest api and swagger based krakenjs node.js server
JavaScript
14
star
43

spud

A content store parser, reading a java .properties-like format
JavaScript
14
star
44

kraken-example-with-i18n

An example Kraken app showing off internationalization support
JavaScript
11
star
45

kraken-example-with-specialization

An example Kraken app showing off template specialization features.
JavaScript
11
star
46

bundalo

Manage localized sets of content files (be they property/json/etc) which may require rendering with data models
JavaScript
10
star
47

engine-munger

A helper module to insert specialization and i18n in the render workflow
JavaScript
10
star
48

memcookies

Persist cookies on the client-side, useful for supporting cookies disabled browsers
JavaScript
9
star
49

subprocess-robot

Create processes, process pools, and message between processes
JavaScript
8
star
50

grumbler-scripts

Build scripts for grumbler modules
JavaScript
6
star
51

universal-serialize

Universal serializer allowing for custom types
JavaScript
5
star
52

reverend

DEPRECATED: Merge an express-style path string with data to create a valid path.
JavaScript
5
star
53

sync-browser-mocks

Synchronous browser mocks for testing
JavaScript
4
star
54

webpack-mem-compile

Compile webpack to and from memory
TypeScript
3
star
55

hotware

JavaScript
3
star
56

localizr

A library and tool to apply localization to dust templates before rendering
JavaScript
3
star
57

neff

nconf & express based feature flags
JavaScript
3
star
58

krakenjs.github.io

Source for the kraken website
JavaScript
3
star
59

construx

Compile-on-the-fly and other development tools for use when building express applications.
JavaScript
2
star
60

spundle

command line tool and library to package localization files as json
JavaScript
2
star
61

dust-makara-helpers

Server-side configuration of helpers for makara
JavaScript
2
star
62

nodejs_deployment

Design and architecture details of node.js deployment solutions
JavaScript
2
star
63

node-benchmarker

Runs benchmarks and publishes results
JavaScript
2
star
64

grabthar-release

Release scripts for grabthar modules
JavaScript
2
star
65

express-promisified

Express with promises
JavaScript
2
star
66

webpack-promise-shim-plugin

Plugin to shim in Promise polyfill into webpack core
JavaScript
2
star
67

file-resolver

Used in kraken based projects for resolving files given the locale , file name, and the file extension.
JavaScript
2
star
68

beaver-logger-ios

Beaver Logger client for iOS
Swift
2
star
69

anemone-machina

express view engine and browser renderer for React and react-router
JavaScript
1
star
70

findatag

A specialized tokenizer for finding dust-style tags ({@tagname [attributes]})
JavaScript
1
star
71

construx-webpack

web pack dev middleware for krakenjs
JavaScript
1
star
72

express-bcp47

Locale handling middleware for Express
JavaScript
1
star
73

dustjacket

Loader middleware for dustjs
JavaScript
1
star
74

strict-merge

Strict deep merge of objects
JavaScript
1
star
75

makara-languagepackpath

Middleware for exposing the path to a language pack to templates
JavaScript
1
star