express-gui

1.0.1 • Public • Published

Express GUI

ExpressJS basic file delivery with a small layer of templating provided by lodash.

| Should be paired with connect-modrewrite and conf-stack, more information below

Why?

  • Static files and dynamic files can overlap in url path (e.g /main-dynamic.html /static.html), as well as created files by a frontend build system (e.g artifacts)
  • Not only a static file server
  • Will attempt to provide a dynamic file if available otherwise it will provide a static one
  • A convention for delivering a small gui
  • Pairs well with the websdk
  • Promotes small GUIs (flat directory structure for dynamic and static dirs)

Info

  • Provides a route named /gui or a middleware only that you can bind to your own route.
  • Expects a directory named gui on your working directory or a directory path provided.
  • Expects 3 subdirectories the gui dir: dynamic, static and artifacts
  • Provides a standard configuration/data to all dynamic files (lodash templates)
  • Provides an error handler middleware with a json response
  • Expects you to have a common base for all of your api routes, like /api so any other route might deliver a file if available
  • Attempts to expose as data to all dynamic files the session and session.user if available, so dynamic files can render parts of that data if needed (the suggestion is to create a single properties.js)
  • If route is enabled, files are accesible through /gui?file=name/to/file.html or /gui/name/to/file.html

Installation

npm install express-gui

Using

On your main app file (server.js)


'use strict';

// Get a logger
var logger = console;

// Log some info
logger.log('Starting server process: '+process.pid);

var
  // Load some apis
  guiApi  = require('express-gui')

  // Get some references
  ,express    = require('express')
  ,confStack  = require('conf-stack')
  ,modrewrite = require('connect-modrewrite')

  // Create some instances
  ,app = express()

  // Load the configuration
  ,config = confStack()
;

// Add the logger to the app and a reference of it to the request
app.logger = logger;
app.use(function(req, res, next){
  req.logger = logger;
  next();
});

// Allow internal URL aliasing
logger.info('Config modrewrite is set to: ', config.modrewrite);
app.use(modrewrite(config.modrewrite||[]));

// Load dependency APIs
logger.log('Configuring GUI...');
guiApi(app, config);

// If not handled by now, provide the default url
app.use(function(req,res,next){
  res.send('Nothing here. Maybe will redirect to config.public.home');
});

// Start listening
app.listen(config.port);
logger.info('Server running at: ', config.port);

// Handle Errors sample
app.use(function handleError(err, req, res, next){
  logger.error(err);
  if(err.code === 'ENOENT'){ err.message = 'File not found'; }
  res.status(err.status).json({
    msg     : err.message
    ,id     : err.id
    ,status : err.status
  });
  next();
});

// Require the debugger and run node-inspector
// var inspector = require('delay-debug');
// inspector();

Configuration

Using conf-stack, create a conf directory and add the following to base.yaml, note that you will need to change /gui for whichever path the gui middleware is located at. Also pick a base path for your api, like /api and put all routes there

base.yaml

modrewrite:
  # Sample redirection, your api should be at api/base or so
  - "/some/url/from/api /api/redirect/here/as/last [L]"

  # Redirection for frontend
  - "^/sample(.+)?$ /gui/?file=app.html&appName=sample-app [L]" # To reuse an html for multilpe websdk builds
  - "^/$ /gui?file=app.html&appName=sample-app [L]" # Will serve app.html on root
    
  - "^/(?!gui(\\/)?)(.+\\..{2,5})$ /gui?file=$2 [L]" # If not for /gui, but has an extension then send the request to gui
  - "^/((?!api|gui\\/).+)*$ /gui?file=app.html&appName=sample-app [L]" # Any other request will always serve the app
  # - "^/(gui\\/)?((?!api\\/).+)*$ /gui?file=$2" # Everything that is not under /api/ goes to gui

expressgui:
  route: true # If it should automatically create a /gui route or not
  dir: gui # Which directory to load the gui file from
  root: <process.mainModule.filename directory> # Which directory to use as root, leave empty to use relative to the main file 

public:
  any: config set here will be delivered as config.json

NOTE: When using modrewrite and conf-stack (and defining routes other than in base.yaml) you might want to define modrewrite as an object with keys (0...100) and use the following to create the array var rewrites = Object.keys(config.modrewrite||[]).sort().map(it=>config.modrewrite[it]).filter(it=>it);, since confstack also merges arrays by index

How to deliver user data

Up to your implementation, but this is the suggested approach:

Create a properties.js within your gui/dynamic directory.

// Expose the properties globally
var PROPERTIES = {
  config : ${configStr}
  ,user  : "${user.username}"
}

In an app.html you can now load your propeties

<!DOCTYPE html>
<html>
<head>
<script src="properties.js"></script>
<script>
  console.log(PROPERTIES);
</script>
</head>
<body></body>
</html>

Data exposed to dynamic the dynamic page

configStr  : JSON.stringify(config.public)
,config    : config.public
,files     : dynamicFilesMap
,anonymous : (req.session && req.session.anonymous) ? req.session.anonymous : {} // If the session has anonymous data then use it
,user      : (req.session && req.session.user) ? req.session.user : {}
,session   : req.session || {}
,appName   : (req.query&&req.query.appName ? req.query.appName : 'main-app')
,query     : req.query
,body      : req.body
,req       : req
,res       : res

Need a debugger?

Use node-inspector through delay-debug

Useful server snippet

Refer to test directory. Use that setup.

Package Sidebar

Install

npm i express-gui

Weekly Downloads

1

Version

1.0.1

License

MIT

Last publish

Collaborators

  • juliostanley