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

electrode-react-webapp

v5.1.1

Published

Hapi plugin that provides a default React web app template

Downloads

638

Readme

Electrode React Webapp

NPM version Dependency Status devDependency Status npm downloads

This module helps render and serve your Electrode React application's index.html. It will handle doing server side rendering and embedding all the necessary JS and CSS bundles for your application.

All the defaults are configured out of the box, but your index page is extensible. You can specify your own index template file with the htmlFile or selectTemplate options.

See design for details on how the template can be extended.

Installing

$ npm install electrode-react-webapp --save

Usage

Registering with Hapi

You can use this plugin by registering it with your Hapi server.

const reactWebapp = server.register({
  register: require("electrode-react-webapp"),
  options: {
    pageTitle: "My Awesome React WebApp",
    paths: {
      "/{args*}": {
        content: "<h1>Hello React!</h1>"
      }
    }
  }
});

Registering with electrode-server

To use this with electrode-server, add to the config you pass to electrode-server:

const config = {
  plugins: {
    "electrode-react-webapp": {
      options: {
        pageTitle: "My Awesome React WebApp",
        paths: {
          "/{args*}": {
            content: "<h1>Hello React!</h1>"
          }
        },
        unbundledJS: {
          enterHead: [{ src: "http://cdn.com/js/lib.js" }]
        }
      }
    }
  }
};

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

Default options

This plugin has some default options but you can override them by setting your own value.

The current defaults are:

{
  pageTitle: "Untitled Electrode Web Application",
  webpackDev: process.env.WEBPACK_DEV === "true",
  renderJS: true,
  serverSideRendering: true,
  htmlFile: "node_modules/electrode-react-webapp/lib/index.html",
  devServer: {
    host: "127.0.0.1",
    port: "2992"
  },
  paths: {},
  stats: "dist/server/stats.json"
}

Options

| name | type | default | description | | -------------------------------------------- | ---------------------------- | -------- | ---------------------------------------------------------- | | pageTitle | String | | The value to be shown in the browser's title bar | | htmlFile | String | *1 | Absolute or relative path to the HTML template. | | selectTemplate | Function | | Callback to selecte HTML template base on request | | serverSideRendering | Boolean | false | Toggle server side rendering. | | webpackDev | Boolean | false | Running with webpack-dev-server | | paths | Object | | Specify route paths and content | | unbundledJS | Object | | Load external JavaScript into page | | devServer | Object | | webpack Dev Server Options | | prodBundleBase | String | "/js/" | Base path to the JavaScript, CSS and manifest bundles | | cspNonceValue | varies | | Used to retrieve a CSP nonce value. |

*1: Default for htmlFile is to use this module's built-in index.html

Paths and Content

Example:

{
  paths: {
    "/test": {
      // route specific options
    }
  }
}

Route speicific options can be:

| name | type | description | | ---------------------- | ---------- | ----------------------------------------------------------------- | | htmlFile | String | Absolute or relative path to the HTML template file. | | templateFile | String | | | insertTokenIds | Boolean | | | pageTitle | String | | | selectTemplate | Function | Callback to selecte HTML template for the route base on request | | responseForBadStatus | Function | | | responseForError | Function | |

| content | varies | Content generator for server-side rendering | | overrideOptions | Object | Specify any config for the given path to override top level options |

unbundledJS Details

Example:

{
  unbundledJS: {
    enterHead: [],
    preBundle: []
  }
}
  • enterHead - Array of script entries to be inserted in <head> before anything else
  • preBundle - Array of script entries to be inserted in <body> before the application's bundled JavaScript

The script entries can be:

  • object - { src: "path to file" } to insert a <script> that loads a file with src
    • To load scripts asynchronously use { src: "...", async: true } or { src: "...", defer: true }
  • string - literal JavaScript to insert within <script> tags

Webpack Dev Server Options

  • host (String) The host that webpack-dev-server runs on
  • port (String) The port that webpack-dev-server runs on

CSP nonce Value

The entry can be a Function, Object, or undefined:

  • Function - called with (request, type), where type can be 'script' or 'style'
    • It return the corresponding nonce
  • Object - it may have properties script, style or both, and the value for each should be the path from the request object to the nonce value
    • For example, if you put a nonce value at request.plugins.myCspGenerator.nonce, then you set cspNonceValue to { script: 'plugins.myCspGenerator.nonce' }.
      • The nonce, if present, will be included on any script or style elements that directly contain scripts or style
      • If this property is undefined, or if the value at that location is undefined, no nonce will be added.

htmlFile view details

The top level options can specify an optional value htmlFile.

Also each path can specify the same option to override the top level one.

This option specifies the view template for rendering your path's HTML output.

  • If it's undefined, then the built-in index.html view template is used.

  • If it's a string, then it must point to a valid view template file.

    • If it's not an absolute path, then process.cwd() is prepended.

You can see this module's build-in index.html for details on how to create your own view template.

See design doc for details on extending the template.

Content details

The content you specify for your path is the entry to your React application when doing Server Side Rendering. Ultimately, a string should be acquired from the content and will replace the SSR_CONTENT marker in the view.

It can be a string, a function, or an object.

string

If it's a string, it's treated as a straight plain HTML to be inserted as the SSR_CONTENT.

function

If it's a function, the function will be called with the web server's request object, and it should return a promise that resolves an object:

function myContent(req) {
  return Promise.resolve({
    status: 200,
    html: "<h1>Hello React!</h1>",
    prefetch: ""
  });
}

In an Electrode app, the module electrode-redux-router-engine and its render method is used to invoke the React component that's been specified for the route and the renderToString output is returned as the html.

object

If it's an object, it can specify a module field which is the name of a module that will be requireed. The module should export either a string or a function as specified above.

selectTemplate Function

You can provide a selectTemplate function to dynamically determine the htmlFile and tokenHandlers at run time.

The function signature is:

{
  selectTemplate: (request, routeOptions) => {};
}

It can return an object directly or with a Promise.

{
  htmlFile: "",
  tokenHandlers: [],
  options: {},
  cacheId: "",
  cacheKey: "" // mutually exclusive with cacheId
}
  • htmlFile - Path to HTML template. Its full path from path.resolve could also be used as cacheKey for the template instance.
  • tokenHandlers - Array of file paths to JS modules that implement token handlers.
  • cacheId - If non-empty string, then it's appended to htmlFile to use as cacheKey for the template instance.
  • cacheKey - Provide cacheKey for the template instance, overrides cacheId.
  • options - Specify some options for this route with this template:
    • pageTitle - change page title
    • responseForBadStatus - callback to generate response if non-200 HTTP status.
    • responseForError - callback to generate response in case of error.

You can access the template instance cache through routeOptions._templateCache

Disabling SSR

If you don't want any Server Side Rendering at all, you can set the option serverSideRendering to false, and you can skip setting content. This will make the server to not even load your React app.

For example:

const config = {
  plugins: {
    "electrode-react-webapp": {
      options: {
        pageTitle: "My Awesome React WebApp",
        paths: {
          "/{args*}": {}
        },
        unbundledJS: {
          enterHead: [{ src: "http://cdn.com/js/lib.js" }]
        },
        serverSideRendering: false
      }
    }
  }
};

Development

To run tests

% fyn
% clap check