• Stars
    star
    224
  • Rank 177,792 (Top 4 %)
  • Language
    JavaScript
  • License
    Other
  • Created over 8 years ago
  • Updated over 3 years ago

Reviews

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

Repository Details

Electrode's configurable web server using Hapi.js atop Node.js

Electrode Server NPM version Build Status Dependency Status

This is an imaginatively named, configurable web server using Hapi.js atop Node.js.

The aim is to provide a standardized node web server that can be used to serve your web application without the need for duplicating from another example, or starting from scratch.

The intention is that you will extend via configuration, such that this provides the baseline functionality of a Hapi web server, and within your own application you will add on the features, logic, etc unique to your situation.

This module requires Node v8.x.x+.

Table Of Contents

Installing

npm i --save electrode-server

Usage

Electrode Server comes with enough defaults such that you can spin up a Hapi server at http://localhost:3000 with one call:

require("electrode-server")();

Of course that doesn't do much but getting a 404 response from http://localhost:3000. To handle your routes, you should create a Hapi plugin to install your handlers. See below for configuration options on how to register your plugin through electrode-server.

Configuration

You can pass in a config object that controls every aspect of the Hapi server.

For example, if you want to spin up a server with HTTP compression off at port 9000:

const config = {
  connection: {
    port: 9000,
    compression: false
  }
};

require("electrode-server")(config);

However, for a more complex application, it's recommended that you use a config composer such as electrode-confippet to manage your app configuration.

Configuration Options

Here's what you can configure:

All properties are optional (if not present, the default values shown below will be used).

server.app.config is set to a object that's the combination of your config with electrode-server's defaults applied.

server (Object)

Default:

{
  server: {
    app: {
      electrode: true;
    }
  }
}

connection (Object)

  • Connection to setup for the Hapi server. Contains connection details for the server.
  • If you want multiple connections, you can start multiple instances of electrode-server

Default:

{
  connection: {
    host: process.env.HOST,
    address: process.env.HOST_IP || "0.0.0.0",
    port: parseInt(process.env.PORT, 10) || 3000,
    routes: {
      cors: true
    }
  }
}

connections Object in previous Electrode no longer supports multiple connections. Only the default is allowed.

      {
        connections: {
          default: {
            host: process.env.HOST,
            address: process.env.HOST_IP || "0.0.0.0",
            port: parseInt(process.env.PORT, 10) || 3000,
            routes: {
              cors: true
            }
          }
        }
      }

plugins (Object)

Default is just empty object:

{
  plugins: {
  }
}

listener (function)

  • A function to install event listeners for the electrode server startup lifecycle.

  • The following events are supported:

    • config-composed - All configurations have been composed into a single one
    • server-created - Hapi server created
    • plugins-sorted - Plugins processed and sorted by priority
    • plugins-registered - Plugins registered with Hapi
    • server-started - Server started
    • complete - Final step before returning

To receive events you must set config.listener before calling electrodeServer.

For example:

myConfig.listener = (emitter) => {
  emitter.on("server-created", (data, next) => {
    // do something
    next();
  });
});
  • The data object will contain these: emitter, server, config, and plugins.

  • Depending on the stage some may not be present. For example, server is not available until server-created event and plugins is not available until plugins-sorted event.

  • These are async events so you have to take and call a next callback.

http2 (Object)

Note: Requires version ^3.2.0 or ^2.4.0

To enable http2, set http2.enable to true. All options are passed to createSecureServer().

{
  "http2": {
    "enable": true,
    "key": Fs.readFileSync('./ssl/site.key'),
    "cert": Fs.readFileSync('./ssl/site.crt')
  }
}

keepAliveTimeout (integer)

NodeJS defaults to 5 seconds keep-alive timeout. electrode-server defaults to 60 seconds timeout. If you want a custom timeout, use the keepAliveTimeout option (in milliseconds).

{
  "electrode": {
    "keepAliveTimeout": 60000
  }
}

logLevel

You can control how much output the Electrode Server logs to the console by setting the logLevel.

  • Levels are "info", "warn", "error", "none".
  • A level of "warn" means only warnning and error messages will be printed.
  • Default is "info"

For example, to suppress the banner that is shown when the server starts up:

Hapi.js server running at http://mypc:4000

set the logLevel to "warn" or "error":

{
  electrode: {
    logLevel: "warn";
  }
}

electrode-confippet

To keep your environment specific configurations manageable, you can use electrode-confippet.

Once you have your config files setup according to the configuration files setup, you can simply pass the config object to electrode server.

const config = require("electrode-confippet").config;

require("electrode-server")(config);

Adding a Hapi plugin

You can have electrode-server register any Hapi plugin that you want through your configuration file.

{
  plugins: {
    "<plugin-id>": {
      enable: true,
      options: {},
      priority: 210,
      register: function () {}, // mutual exclusive with module
      module: "<plugin-module-name>",
      requireFromPath: process.cwd()
    }
  }
}

Plugin configs

  • <plugin-id> - ID for the plugin. Generally the module name for the plugin, which is used to load it for registration.
  • register - optional The register function to pass to Hapi. Overrides module.
  • module - optional name of the module to load for the plugin instead of the <plugin-id>
  • requireFromPath - optional The path from which to call require to load the plugin module
  • enable - optional if set to false then this plugin won't be registered. If it's not set then it's considered to be true.
  • options - optional Object that's passed to the plugin's register function.
  • priority - optional integer value to indicate the plugin's registration order
    • Lower value ones are register first
    • Default to Infinity if this field is missing or has no valid integer value (NaN) (string of number accepted)

About Plugin Priority

Priority allows you to arrange plugins to be registered in an order you prefer. The plugins with lower priority values are registered first.

More about register and module

If you don't want to use <plugin-id> to load the module, then you can optionally specify one of the following:

  • register - if specified, then treat as the plugin's register function to pass to Hapi, overides module
  • module - Only used if register is not specified
    • If it's a string the used as the name module to require for registration.
    • It it's false then electrode server will not load any module.
    • You can specify a require-from-path for the module using an object.
        {
          plugins: {
            myPlugin: {
              module: {
                requireFromPath: process.cwd(),
                name: "my-plugin-module"
              }
            }
          }
        }

Exporting your Hapi Plugin from a module

Electrode server will try to find your Hapi Plugin from your module by looking through these fields:

  1. mod.hapiPlugin
  2. mod.default.hapiPlugin
  3. mod.default
  4. mod itself

Examples:

  1. Exporting the plugin directly as the module:

CommonJS example:

module.exports = myHapiPlugin;

ES6 example:

export default myHapiPlugin;
  1. Exporting the plugin as a field named hapiPlugin:

CommonJS example:

module.exports.hapiPlugin = myHapiPlugin;

ES6 example:

const hapiPlugin = myHapiPlugin;
export hapiPlugin;

ES6 default:

export default {
  hapiPlugin: myHapiPlugin
};

More about requireFromPath

There are three places you can specify a path to call require from when loading your plugin modules.

  1. config.plugins.requireFromPath - The top one used for all plugins
  2. config.plugins.<plugin-id>.requireFromPath - Used for the specific plugin of <plugin-id>, overrides the one above
  3. config.plugins.<plugin-id>.module.requireFromPath - Used for the specific plugin of <plugin-id>, overrides the two above

For more information: check out require-from-path

Example: crumb

Here's an example using the crumb plugin:

First, install the plugin as you normally would from npm:

npm i --save crumb

Then, add your plugin to the config plugins section.

{
  plugins: {
    "crumb": {
      enable: true,
      options: {},
      priority: 210,
      requireFromPath: process.cwd()
    }
  }
}

Above config tells electrode-server to require from CWD the module by its <plugin-id> "crumb" and register it as a plugin with Hapi.

API

The electrode server exports a single API.

electrodeServer

electrodeServer(config, [decors], [callback])

  • config is the electrode server config

  • decors - Optional extra config or array of config. In case you have common config you want to put inside a dedicated module, you can pass them in here.

    • If it's an array like [ decor1, decor2, decor3 ] then each one is composed into the main config. ie: something similar to _.merge(mainConfig, decor1, decor2, decor3).
  • callback is an optional errback with the signature function (err, server)

    • where server is the Hapi server
  • Returns: a promise resolving to the Hapi server if callback is not provided

Contributions

Make sure you sign the CLA. Checkout the contribution guide

To run tests

% npm i
% clap test

To run tests and coverage

% clap check

To run sample server

% npm run sample

Hit http://localhost:9000

Publishing

  • Require access to npmjs.org to publish this package.
  • Run npm version to update the version. Commit with tags
  • Run npm publish to publish
  • Update CHANGELOG.md

License

Copyright 2016-present WalmartLabs

Licensed under the Apache License, Version 2.0.

More Repositories

1

electrode

Web applications with node.js and React
HTML
2,101
star
2

electrode-native

A platform to ease integration&delivery of React Native apps in existing mobile applications
TypeScript
725
star
3

electrode-io.github.io

The public website of the Electrode platform
HTML
336
star
4

electrode-react-ssr-caching

Optimize React SSR with profiling and component caching
JavaScript
316
star
5

electrode-explorer

An Electrode application that showcases all of your components in a live demo
JavaScript
254
star
6

electrode-electrify

Electrify is an webpack visualizer for analyzing webpack bundles.
JavaScript
230
star
7

electrode-ota-server

Electrode Over The Air Server for hot deployment of React Native and Cordova mobile apps
JavaScript
204
star
8

electrode-csrf-jwt

Stateless Cross-Site Request Forgery (CSRF) protection with JWT
JavaScript
126
star
9

above-the-fold-only-server-render

An Electrode component for optionally skipping server side render of components outside of Above the fold
JavaScript
117
star
10

electrode-confippet

node.js environment aware application configuration
TypeScript
108
star
11

isomorphic-loader

Webpack isomorphic loader tools to make Node require handle files like images for Server Side Rendering (SSR)
JavaScript
68
star
12

electrode-archetype-njs-module-dev

A WalmartLabs flavored NodeJS Module archetype
JavaScript
67
star
13

electrode-bundle-analyzer

Analyze your webpack deduped and minified bundle JS file.
JavaScript
66
star
14

electrode-webpack-reporter

A HTML based reporter for webpack dev server
JavaScript
59
star
15

electrode-gulp-helper

Helper functions for using gulp
JavaScript
59
star
16

electrode-check-dependencies

An Electrode module to verify component dependencies against a list
JavaScript
58
star
17

electrode-docgen

A custom metadata extractor and documentation generator for the Electrode framework
JavaScript
57
star
18

fynpo

πŸ› οΈπŸ“¦ a node.js monorepo manager
JavaScript
55
star
19

electrode-static-paths

Electrode server decor to serve static files
JavaScript
55
star
20

react-native-electrode-bridge

Electrode Native - Bridge
Java
44
star
21

xarc-run

npm run scripts concurrently and serially, and more.
JavaScript
42
star
22

memcache

Node.js memcached client with the most efficient ASCII protocol parser
TypeScript
37
star
23

electrode-ota-desktop

Electrode OTA Desktop Client
JavaScript
22
star
24

electrode-ota-ui

[Deprecated for electrode-ota-server/electrode-ota-ui] Electrode OTA Web/Client UI
JavaScript
17
star
25

ern-navigation

Electrode Native solution for React Native navigation
JavaScript
12
star
26

movies-reloaded-miniapp

Our new movie miniapp built on the Electrode Native Navigation.
JavaScript
10
star
27

car-buying-instructions

JavaScript
9
star
28

movielist-miniapp

Electrode Native - Movie List MiniApp (Getting Started)
Objective-C
8
star
29

fastify-server

Electrode using Fastify
TypeScript
6
star
30

moviedetails-miniapp

Electrode Native - Movie Details MiniApp (Getting Started)
JavaScript
6
star
31

electrode-keepalive

node.js HTTP agent with customized keep alive
JavaScript
6
star
32

kax

TypeScript
5
star
33

react-native-livebundle

LiveBundle Native Module
Java
3
star
34

livebundle

LiveBundle CLI
TypeScript
3
star
35

electrode-native-starter-manifest

Electrode Native - Starter Manifest
3
star
36

react-native-ernnavigation-api

Electrode Native - Navigation API (Getting Started)
Swift
3
star
37

electrode-native-manifest

Electrode Native - Master Manifest
Java
3
star
38

electrode-native-showcaseapp-android

Native application that showcases electrode native MiniApps and APIs.
Java
2
star
39

electrode-native-sample-cauldron

Sample Electrode Native Cauldron
2
star
40

fynpo-old

Supplement tools for using fyn with lerna
JavaScript
2
star
41

car-buying-service

mock service for car buying app
JavaScript
2
star
42

car-buying

A sample car buying app
JavaScript
2
star
43

ern-bundle-store

Electrode Native Bundle Store Server
TypeScript
2
star
44

electrode-native-website

The site and docs for Electrode Native
JavaScript
2
star
45

react-native-ernmovie-api

Electrode Native - Movie API (Getting Started)
Swift
2
star
46

ernnavigation-api-impl-native

Native implementation of ernnavigation-api
Objective-C
2
star
47

electrode-demo-app

Demo application generated by Electrode platform unmodified
JavaScript
1
star
48

react-native-ernmovie-api-impl

Objective-C
1
star
49

ern-sourcemap-store

Electrode Native sourcemap store server
TypeScript
1
star
50

electrode-native-binarystore

Electrode Native - Binary Store
JavaScript
1
star
51

ern-container-transformer-xcframework

Electrode Native XCFramework Container Transformer
Shell
1
star
52

ern-container-publisher-maven

Electrode Native Maven Container Publisher
TypeScript
1
star
53

resolve-alias

set virtual module aliases for resolve and require
JavaScript
1
star
54

ern-base-composite-starter

Electrode Native Base Composite Starter
JavaScript
1
star
55

electrode-native-showcaseapp-ios

Swift
1
star
56

react-native-ernmovie-api-impl-js

JavaScript
1
star