express-gui
v1.0.1
Published
ExpressJS basic file delivery with a small layer of templating provided by lodash
Downloads
2
Maintainers
Readme
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.