0.23.2 • Published 2 months ago

roosevelt v0.23.2

Weekly downloads
603
License
CC-BY-4.0
Repository
github
Last release
2 months ago

Roosevelt MVC web framework

Build Status codecov npm

Roosevelt is a web application development framework based on Express that aims to be the easiest web framework on the Node.js stack to learn and use.

Some notable features:

  • Boilerplate minimized. Teddy Roosevelt — referred to by Cracked magazine as the "the most badass President of all-time" — curtailed the abuse of monopolists, so there's no way he would ever put up with all the indecipherable boilerplate common to other web frameworks.

    • By contrast, the Express framework itself adopts a very minimalist philosophy. If you build a vanilla Express app yourself, you will need to manually include and configure a lot of additional modules to handle very basic things such as handling POST requests, file uploads, logging, security hardening, template parsing, CSS/JS preprocessing and bundling, etc. Roosevelt includes these and configures them properly for you.
  • MVC-based default directory structure.

  • Teddy HTML templates by default which are much easier to read and maintain than common alternatives. Can be configured to use any templating system that supports Express.
    • Need some extra speed in template parsing? Consider writing your templates in PHP! The Roosevelt team also built a view engine that lets you use PHP as your templating engine in a Roosevelt app or any other Express application. PHP should be faster than any JS-based templating engine for complex templates since its parser is written in C rather than JS.
  • LESS preconfigured out of the box to intelligently minify your external-facing CSS files via clean-css. There's also built-in support for Sass and Stylus. Other CSS preprocessors can be used as well with a bit of extra configuration.
  • Webpack fully integrated providing an easy to use interface for bundling and minifying your frontend JS.
  • Code-reloading in development mode via nodemon for server-side changes and reload for frontend changes.
  • HTML validation done automatically in development mode for your post-server rendered HTML powered by express-html-validator.

Teddy Roosevelt's facial hair is a curly brace.

This is documentation for the current version of Roosevelt. If you need API documentation for a previous version of Roosevelt, look here.

Table of contents

Create and run a Roosevelt app

Prerequisites

First you will need to install Node.js. Both the current and LTS version of Node.js are supported. It is recommended that you have both the current and LTS versions of Node.js installed on your system. To do that, it is recommended that you install Node.js using a Node.js version manager like nvm or nvm-windows rather than the official installer, as a version manager will allow you to switch between multiple versions of Node.js easily.

Roosevelt app generator

The Roosevelt app generator is a command line script based on Yeoman that can create a sample Roosevelt app for you.

To use it, simply run the following command:

npx mkroosevelt

Then follow the prompts.

You can also optionally install the app generator to your system if you like so that it doesn't need to be refetched from npm each time you want to create a new app. To do that, first globally install Yeoman and the Yeoman-based Roosevelt app generator:

npm i -g yo generator-roosevelt

Then create a Roosevelt app using the Roosevelt app generator:

yo roosevelt

Then follow the prompts.

After creating your app, cd to your app's directory and:

  • Install dependencies: npm i
  • Run the app in development mode: npm run development
    • Default shorthands:
      • npm run dev
      • npm run d

See available npm scripts for more ways to run the app.

Create a Roosevelt app manually

It is also possible to create a Roosevelt app without using the app generator. This will result in a more minimalist default configuration (e.g. no CSS or JS preprocessors enabled by default).

To do that:

  • First create a new folder and cd into it.

  • Then npm i roosevelt. This will create a node_modules folder with Roosevelt and its bare minimum dependencies.

  • Create a file named app.js.

  • Put this code in app.js:

    require('roosevelt')({
      'makeBuildArtifacts': true
    }).startServer()
  • Then node app.js. If the makeBuildArtifacts parameter is set to true like the above code example, an entire Roosevelt app with bare minimum viability will be created and the server will be started. See configure your app with parameters for more information about parameter configuration.

Use Roosevelt as a static site generator

Create a Roosevelt app using one of the methods above, then set the makeBuildArtifacts param to the value of 'staticsOnly' which will allow Roosevelt to create static files but skip the creation of the MVC directories:

require('roosevelt')({
  makeBuildArtifacts: 'staticsOnly'
}).init()

You will also need to set viewEngine if you want to render HTML templates into static pages and supply data to the templates:

require('roosevelt')({
  makeBuildArtifacts: 'staticsOnly',
  viewEngine: 'html: teddy',
  onServerInit: (app) => {
    app.get('htmlModels')['index.html'] = {
      hello: 'world!'
    }
  }
}).init()

If model data is not supplied by configuration, Roosevelt will try to automatically load a model from a JS file with the same name alongside the template if it exists instead. For example if an index.js file exists next to index.html and the model is not defined by configuration like in the example above, then the index.js file will be used to set the model so long as it exports either an object or a function that returns an object.

Available npm scripts

Roosevelt apps created with the app generator come with the following notable npm scripts prepopulated in package.json:

  • npm run production: Runs the app in production mode.
    • Default shorthands:
      • npm run prod
      • npm run p
      • npm start
    • Script is short for: nodemon app.js --production-mode
  • npm run development: Runs the app in development mode.
    • Default shorthands:
      • npm run dev
      • npm run d
    • Script is short for: nodemon app.js --development-mode
  • npm run production-proxy: Runs the app in production mode, but with localhostOnly set to true and hostPublic set to false. This mode will make it so your app only listens to requests coming from localhost and does not serve anything in the public folder. This mode is useful when you want to host your app behind a reverse proxy from a web server like Apache or nginx and is considered a best practice for Node.js deployments.
    • Default shorthands:
      • npm run prodproxy
      • npm run x
    • Script is short for: nodemon app.js --production-proxy-mode
  • npm run generate-certs: Generates self-signed HTTPS certs for your app.
    • Script is short for: node ./node_modules/roosevelt/lib/scripts/certsGenerator.js
  • npm run generate-session-secret: Generates a secret key for the express-session module.
    • Script is short for: node ./node_modules/roosevelt/lib/scripts/sessionSecretGenerator.js
  • npm run generate-secrets: Generates self-signed HTTPS certs and a express-session secret.
  • npm run audit-config: Scans current rooseveltConfig and scripts in package.json and warns about any parameters or npm scripts that don't match the current Roosevelt API:
    • Script is short for: node ./node_modules/roosevelt/lib/scripts/configAuditor.js
    • This will run automatically whenever you run npm i or npm ci as well.

Available command line arguments

  • node app.js --production-mode: Runs the app in production mode.
    • Default shorthands:
      • --prod
      • -p
  • node app.js --development-mode: Runs the app in development mode.
    • Default shorthands:
      • --dev
      • -d
  • node app.js --build: Only runs the build scripts and doesn't start the app.
    • Default shorthands:
      • -b
  • node app.js --webpack=verbose: Enables webpack to print verbose errors to the console.
    • Default shorthands:
      • --wp=verbose
      • -w=verbose
  • node app.js --webpack=verbose-file: Enables webpack to print verbose errors to the console as well as write a webpackError file to the app's root directory containing the full error.
    • Default shorthands:
      • --wp=verbose-file
      • -w=verbose-file
  • node app.js --production-proxy-mode: Runs the app in production mode, but with localhostOnly set to true and hostPublic set to false. This mode will make it so your app only listens to requests coming from localhost and does not serve anything in the public folder. This mode is useful when you want to host your app behind a reverse proxy from a web server like Apache or nginx and is considered a best practice for Node.js deployments.
    • Default shorthands:
      • --prodproxy
      • -x
  • node app.js --enable-validator: Forces the HTML validator to be enabled.
    • Default shorthands:
      • --html-validator
      • -h
  • node app.js --disable-validator: Forces the HTML validator to be disabled.
    • Default shorthands:
      • --raw
      • -r

Combining npm scripts and command line arguments

The npm scripts can be combined with the command line flags.

For example, running npm run d -- -r will run your app in development mode and force the HTML validator to be disabled.

Recognized environment variables

The following is a list of environment variables that Roosevelt listens for.

  • NODE_ENV:
    • Set to production to force the app into production mode.
    • Set to development to force the app into development mode.
  • NODE_PORT: Default HTTP port to run your app on.
  • HTTP_PORT: Default HTTP port to run your app on. Takes precedence over NODE_PORT.
  • HTTPS_PORT: Default HTTPS port to run your app on.
  • DISABLE_HTTPS: When set to true, the HTTPS server will be disabled and the app will revert to HTTP regardless of what is set in the rooseveltConfig.

Environment variable precedence:

Default directory structure

Below is the default directory structure for an app created using the Roosevelt app generator:

  • Application logic:

    • app.js: Entry point to your application. Feel free to rename this, but make sure to update package.json's references to it.

    • lib: Random includable JS files that don't belong in any of the other directories. It has been added to the require stack so you can simply require('lib/someFile').

    • mvc: Folder for models, views, and controllers. All configurable via parameters (see below).

      • controllers: Folder for controller files; the "C" in MVC. This is where your HTTP routes will go.
      • models: Folder for model files; the "M" in MVC. This is where you will get data to display in your views e.g. by querying a database or do other business logic.
      • views: Folder for view files; the "V" in MVC. This is where your HTML templates will go.
  • Static files:

    • public: All contents within this folder will be exposed as static files.

    • statics: Folder for source CSS, image, JS, and other static files. By default some of the contents of this folder are symlinked to from public, which you can configure via params. See configure your app with parameters for more information about parameter configuration.

      • css: Folder for source CSS files.
      • images: Folder for source image files.
      • js: Folder for source JS files.
      • pages: Folder for HTML templates that get rendered and minified into static pages.
  • Application infrastructure:

    • .gitignore: A standard file which contains a list of files and folders to ignore if your project is in a git repo. Delete it if you're not using git. The default .gitignore file contains many common important things to ignore, however you may need to tweak it to your liking before committing a fresh Roosevelt app to your git repo.
      • Some notable things ignored by default and why:
        • node_modules: This folder is created when installing dependencies using the npm i step to set up your app. It's generally not recommended to commit the node_modules folder or any other build artifacts to git.
        • public: It's recommended that you don't create files in this folder manually, but instead use the statics parameter detailed below to expose folders in your statics directory to public via auto-generated symlinks.
        • secrets: A folder for "secret" files, e.g. session keys, HTTPS certs, passwords, etc. Since this folder contains sensitive information, it should not be committed to git.
    • node_modules: A standard folder created by Node.js where all modules your app depends on (such as Roosevelt) are installed to. This folder is created when installing dependencies using the npm i command.

    • package.json: A file common to most Node.js apps for configuring your app.

    • package-lock.json: An auto-generated file common to most Node.js apps containing a map of your dependency tree. This is created after you run npm i for the first time.
    • rooseveltConfig.json: Where your Roosevelt config is stored and what your params are set to. See configure your app with parameters for more information about parameter configuration.
    • secrets: A folder for "secret" files, e.g. session keys, HTTPS certs, passwords, etc. It is added to .gitignore.

Configure your app with parameters

Roosevelt is designed to have a minimal amount of boilerplate so you can spend less time focused on configuration and more time writing your app. All parameters are optional. As such, by default, all that's in app.js is this:

require('roosevelt')().startServer()

Roosevelt will determine your app's name by examining "name" in package.json. If none is provided, it will use Roosevelt Express instead.

There are multiple ways to pass a configuration to Roosevelt:

  • A rooseveltConfig.json file located in the root directory of your app.
  • Via package.json under "rooseveltConfig".
  • Programmatically via Roosevelt's constructor like so:

    require('roosevelt')({
      paramName: 'paramValue',
      param2:    'value2',
      etc:       'etc'
    }).startServer();
    • This is particularly useful for setting parameters that can't be defined in package.json or rooseveltConfig.json such as event handlers.

In addition, all parameters support template literal style variable syntax that you can use to refer to other Roosevelt parameters. For example:

{
  "port": 4000,
  "https": {
    "port": "${port + 1}"
  },
  "css": {
    "sourcePath": "css",
    "output": ".build/${css.sourcePath}"
  }
}

Resolves to:

{
  "port": 4000,
  "https": {
    "port": 4001
  },
  "css": {
    "sourcePath": "css",
    "output": ".build/css"
  }
}

MVC parameters

  • controllersPath: Relative path on filesystem to where your controller files are located.
    • Default: String "mvc/controllers".
  • modelsPath: Relative path on filesystem to where your model files are located.
  • viewsPath: Relative path on filesystem to where your view files are located.

  • secretsDir: Directory that stores certs, keys, and secrets.

    • Default: String secrets.

    • Important: Changing this value will require updating .gitignore.

Development mode parameters

  • frontendReload: Settings to use for the reload module which automatically reloads your browser when your frontend code changes. This feature is only available in development mode.

    • Default: Object

      {
        "enable": true,
        "port": 9856,
        "httpsPort": 9857
      }
  • htmlValidator: Parameters to send to express-html-validator. This feature is only available in development mode.

    • enable: Boolean Enables or disables the built-in HTML validator.

    • exceptions: A set of params that can be used to prevent validation in certain scenarios.

      • header String: A custom header that when set will disable the validator on a per request basis.

        • Default: 'Partial'.
      • modelValue String: An entry in your data model passed along with a res.render that when set will disable validation on the rendered HTML.

        • Default: '_disableValidator'.
    • validatorConfig Object: html-validate configuration that determines what errors the validator looks for.

      • The full list of available validator rules can be found here.

      • This configuration can also be set by a .htmlValidate.json file placed in your app root directory.

    • Default: Object

      {
        "enable": true,
        "exceptions": {
          "requestHeader": "Partial",
          "modelValue": "_disableValidator"
        },
        "validatorConfig": {}
      }

Deployment parameters

  • hostPublic: Whether or not to allow Roosevelt to host the public folder. By default in production-proxy mode Roosevelt will not expose the public folder. It's recommended instead that you host the public folder through another web server, such as Apache or nginx that is better optimized for hosting static files.

  • https: Object params for configuring the HTTPS server. HTTPS is disabled by default in apps created manually and enabled by default in apps generated with generator-roosevelt.

    • Default: Object {}.
    • Object members:

      • enable: Enable HTTPS server.
      • Default: Boolean false.
      • port: The port your app will run the HTTPS server on.
    • force: Disallow unencrypted HTTP and route all traffic through HTTPS.

    • autoCert: Will create self-signed HTTPS certificates in development mode as long as they don't already exist.
    • authInfoPath: Object Specify either the paths where the server certificate files can be found or set the appropriate parameters to be a PKCS#12-formatted string or certificate or key strings.

      • Default: Object undefined.
      • Object members:

        • p12: Object Parameter used when the server certificate/key is in PKCS#12 format.
          • Default: Object undefined.
          • Object members:
            • p12Path: String Either the path to a PKCS#12-formatted file (e.g. a .p12 or .pfx file) or a PKCS#12-formatted string or buffer (e.g. the result of reading in the contents of a .p12 file).
              • Default: undefined.
        • authCertAndKey: Object Parameter used when the server certificate and key are in separate PEM-encoded files.

          • Object members:

            • cert: String Either the path to a PEM-encoded certificate file (e.g. .crt, .cer, etc.) or a PEM-encoded certificate string.

              • Default: undefined.
            • key: String Either the path to a PEM-encoded key file (e.g. .crt, .cer, etc.) or a PEM-encoded key string for the certificate given in cert.

              • Default: undefined.
    • passphrase: String Shared passphrase used for a single private key and/or a P12.

      • Default: undefined.
    • requestCert: Boolean Set whether to request a certificate from the client attempting to connect to the server to verify the client's identity.
      • Default: undefined.
    • rejectUnauthorized: Boolean Set whether to reject connections from clients that do no present a valid certificate to the server. (Ignored if requestCert is set to false.)
      • Default: undefined.
    • caCert: String Either the path to a PEM-encoded Certificate Authority root certificate or certificate chain or a PEM-encoded Certificate Authority root certificate or certificate chain string. This certificate (chain) will be used to verify client certificates presented to the server. It is only needed if requestCert and rejectUnauthorized are both set to true and the client certificates are not signed by a Certificate Authority in the default publicly trusted list of CAs curated by Mozilla.
      • Default: undefined.
  • localhostOnly: Listen only to requests coming from localhost in production mode. This is useful in environments where it is expected that HTTP requests to your app will be proxied through a more traditional web server like Apache or nginx. This setting is ignored in development mode.

  • mode: Decides whether your app starts in production mode or development mode by default.

  • port: The HTTP port your app will run on. This setting is ignored if the app is set to force HTTPS-only mode.

  • shutdownTimeout: Maximum amount of time in milliseconds given to Roosevelt to gracefully shut itself down when sent the kill signal.

    • Default: Number 30000 (30 seconds).

App behavior parameters

  • appDir: Root directory of your application.

    • Default: String The directory where your app's package.json is located.
  • bodyParser: Parameters to supply to the body-parser module which handles POST requests.

  • csrfProtection: Whether to enable Cross-Site Request Forgery protection.

    • Default: Boolean true.
    • To exempt certain routes from protection, supply an object as your config with an array of exemptions.

      {
        "exemptions": [
          "/foo",
          "/bar",
          "/baz"
        ]
      }
  • enableCLIFlags: Enables parsing of command line flags. Disable this if you want to handle them yourself or if you don't want Roosevelt to listen to the command line flags it listens for by default.

  • errorPages: Relative path on filesystem to where your various error page controller files are located. If you do not supply them, Roosevelt will use its default ones instead:

  • expressSession: Parameter(s) to pass to the express-session module.

    • Default: Boolean true.

      • If expressSession is set to true, it will supply to following configuration to express-session:

        {
          "secret": [an auto-generated secret],
          "resave": false, // usually a bad idea to set to true
          "saveUninitialized": false, // usually a bad idea to set to true
          "cookie": {
            "secure": false, // will automatically be set to true if https is enabled
            "sameSite": "strict", // adds same site enforcement
            "maxAge": 347126472000 // sets expiration very far in the future (~11 years) to basically never expire
          }
          "store": [the expressSessionStore.instance Roosevelt param]
        }
        • Roosevelt sets express-session to use memorystore as the default session store.

        • The default setting for maxAge is ~11 years. You should set that to be shorter in use cases where you want sessions to expire regularly, e.g. if you want users to reauthorize and login again frequently for security reasons.

    • If you supply your own parameters to express-session, it is recommended you take the above default configuration and modify it.

  • expressSessionStore: Define a custom session store to use with express-session instead of the default one provided by Roosevelt. This is recommended if you plan to shard your app across multiple separate processes or scale it to multiple servers.

    • filename: Name of the session file.
      • Default: String sessions.sqlite
    • instance: Object A store instance. See this list for compatible stores.
    • preset: String Available presets provided by Roosevelt. Only used if instance is not provided.
      • Available options:
        • default: Use Roosevelt's default session store, which is better-sqlite3-session-store.
        • express-session-default: Use express-session's default session store (not recommended).
    • presetOptions: Options to pass to the preset session store if one is selected. Only used if instance is not provided.

      • Default: Object
        • checkPeriod: How long, in milliseconds, the memory store will check for expired items.
          • Default: Number 86400000 (1 day).
        • ttl: How long, in milliseconds, before a session is expired.
          • Default: Number the value of checkPeriod.
        • max: The maximum size of the cache, checked by applying the length function to all values in the cache.
    • Either instance or preset must be set for this param to work properly.

  • formidable: Parameters to pass to formidable using formidable's API for multipart form processing (file uploads). Access files uploaded in your controllers by examining the req.files object. Roosevelt will remove any files uploaded to the upload directory when the request ends automatically. To keep any, be sure to move them before the request ends.

    • Default: Object

      {
        "multiples": true // enables multiple files to be uploaded simultaneously
      }
    • To disable multipart forms entirely, set formidable to false.

  • helmet: Parameters to pass to the helmet module. This module helps secure Express apps by setting HTTP response headers.

    • Default: Object The default options are specified in the helmet docs, with the following exceptions that Roosevelt makes to the default Content-Security-Policy settings:
      • The upgrade-insecure-requests directive has been removed. This change prevents this bug.
      • The script-src directive has been set to 'unsafe-inline'. This makes it possible to use inline scripts.
      • The form-action directive has been set to null. This makes it possible to submit forms to other domains.
      • You can reverse any of these changes by configuring helmet yourself.
    • To disable helmet entirely, set the param to false.
  • logging: Parameters to pass to roosevelt-logger. See roosevelt-logger parameters documentation for configuration options.

    • Default: Object

      {
        "methods": {
          "http": true,
          "info": true,
          "warn": true,
          "error": true,
          "verbose": false
        }
      }
  • makeBuildArtifacts: When enabled Roosevelt will generate user-specified directories, CSS/JS bundles, etc.

    • Default: Boolean false for apps created manually.

    • Will be set to true in apps generated with generator-roosevelt.

    • Can also accept a value of 'staticsOnly' which will allow Roosevelt to create static files but skip the creation of the MVC directories.
  • routePrefix: String A prefix prepended to your application's routes. Applies to all routes and static files.

    • Example: When set to "foo" a route bound to / will be instead be bound to /foo/.

    • This prefix is exposed via the routePrefix Express variable which should be used for resolving the absolute paths to statics programmatically.

      • Example: An image located at /images/teddy.jpg can be resolved in a prefix-agnostic way via `${app.get('routePrefix')/images/teddy.jpg}`.
    • Default: null.

  • viewEngine: What templating engine to use, formatted as String "fileExtension: nodeModule".

    • Default: String "none" for apps created manually.

    • Will be set to "html: teddy" in apps generated with generator-roosevelt.

    • Also by default when using the generator, the module teddy is marked as a dependency in package.json.

    • To use multiple templating systems, supply an array of engines to use in the same string format. Each engine you use must also be marked as a dependency in your app's package.json. Whichever engine you supply first with this parameter will be considered the default.

    • Example configuration using multiple templating systems: Object

      {
        "viewEngine": [
          "html: teddy",
          "php: php",
          "ejs: ejs"
        ]
      }

Isomorphic parameters

  • clientViews: Object Allows you to expose view (template) file code to frontend JS for client-side templating.

    • exposeAll: Boolean Option to expose all templates.

    • blocklist: Array of Strings List of files or folders to exclude when exposeAll is enabled.

    • Can also be set declaratively by putting a <!-- roosevelt-blocklist --> tag at the top of any template.

    • allowlist: Object of Arrays List of JS files to create mapped to which view files to expose.

      • Default: Object {}.

      • Example:

        {
          "mainLayouts.js": ["baseLayout.html", "footer.html"],
          "forms.js": ["forms/formTemplate.html"]
        }
      • Can also be set declaratively by putting a <!-- roosevelt-allowlist <filepath> --> tag at the top of any template.

    • defaultBundle: String File name for the default JS view bundle.

    • output: String Subdirectory within publicFolder to write JS view bundles to.

    • minify: Boolean Option to minify templates that are exposed via this feature.

    • minifyOptions: Object Parameters to supply to html-minifier's API.

      • Uses the params you set in html.minifier.options if empty.
    • Default: Object

      "clientViews": {
        "exposeAll": false,
        "blocklist": [],
        "allowlist": {},
        "defaultBundle": "views.js",
        "output": "js",
        "minify": true,
        "minifyOptions": {}
      }
  • isomorphicControllers: Object Allows you to expose controller (route) file code to frontend JS for client-side routing.

    • file: String File name for the default JS controller auto-loader file. Set to null to disable this feature.

      • Default: null.
    • output: String Subdirectory within publicFolder to write JS controller auto-loader file to.

    • Default: Object

      "isomorphicControllers": {
        "file": null
        "output": "js"
      }

Statics parameters

  • css: Object How you want Roosevelt to configure your CSS preprocessor:

    • sourcePath: Subdirectory within staticsRoot where your CSS files are located. By default this folder will not be made public, but is instead meant to store unminified CSS source files which will be minified and written to the public folder when the app is started.

    • compiler: Object Which CSS preprocessor (if any) to use.

      • enable: Boolean Whether or not to use a preprocessor.

      • module: String Node module name of the CSS preprocessor you wish to use.

        • Currently less, sass, and stylus are supported.

        • Your chosen CSS preprocessor module must also be marked as a dependency in your app's package.json.

      • options: Object Parameters to send to the CSS preprocessor if it accepts any.

    • minifier: Object Params pertaining to CSS minifcation.

      • enable: Boolean Whether or not to minify CSS.
        • Can also be disabled by the minify param.
    • options: Object Parameters to pass to the CSS minifier clean-css, a list of which can be found in the clean-css docs.

    • allowlist: Array of CSS files to allow for compiling. Leave undefined to compile all files. Supply a : character after each file name to delimit an alternate file path and/or file name for the minified file.

      • Example array member: String example.less:example.min.css compiles example.less into example.min.css.
    • output: Subdirectory within publicFolder where compiled CSS files will be written to.

    • versionFile: If enabled, Roosevelt will create a CSS file which declares a CSS variable containing your app's version number from package.json. Enable this option by supplying an object with the member variables fileName and varName. Versioning your static files is useful for resetting your users' browser cache when you release a new version of your app.

      • Example usage (with LESS): Object

        {
          "fileName": "_version.less",
          "varName": "appVersion"
        }
      • Assuming the default Roosevelt configuration otherwise, this will result in a file statics/css/_version.less with the following content:

        /* do not edit; generated automatically by Roosevelt */ @appVersion: '0.1.0';
      • Some things to note:

        • If there is already a file there with that name, this will overwrite it, so be careful!

        • It's generally a good idea to add this file to .gitignore, since it is a build artifact.

    • Default: Object

      {
        "sourcePath": "css",
        "compiler": {
          "enable" : false,
          "module": "less",
          "options": {}
        },
        "minifier": {
          "enable": true,
          "options": {}
        },
        "allowlist": null,
        "output": "css",
        "versionFile": null
      }
  • favicon: String Location of your favicon file.

  • html: Generate static HTML pages:

    • sourcePath: Subdirectory within staticsRoot where your static HTML files are located. By default this folder will not be made public, but is instead meant to store unminified / unprocessed HTML template source files which will be rendered, minified, and written to the public folder when the app is started.

    • allowlist: Array of Strings List of templates to render, minify, and write to the public folder when the app is started. If the list is empty, all templates in your sourcePath will be sourced. Supports wildcard matching, e.g. dir/*.

    • blocklist: Array of Strings List of templates in your sourcePath to skip. Supports wildcard matching, e.g. dir/*.

    • models: Data to pass to templates by file path / file name.

      • Example:

        {
          "models": {
            "index.html": {
              "some": "data"
            },
            "subdirectory/otherFile.html": {
              "someOther": "data"
            }
          }
        }
      • If this data is not supplied by configuration, Roosevelt will try to automatically load a model from a JS file with the same name alongside the template if it exists instead. For example if an index.js file exists next to index.html and the model is not defined by configuration like in the example above, then the index.js file will be used to set the model so long as it exports either an object or a function that returns an object.

    • output: Subdirectory within publicFolder where parsed and minified HTML files will be written to.

    • minifier: How you want Roosevelt to minify your HTML:

      • enable: Boolean Whether or not to minify HTML.

        • Can also be disabled by the minify param.
        • Minification is automatically disabled in development mode.
      • exceptionRoutes: Array List of controller routes that will skip minification entirely. Set to false to minify all URLs.

      • options: Object Parameters to supply to html-minifier's API.

    • Default: Object

      {
        "sourcePath": "pages",
        "allowlist": null,
        "blocklist": null,
        "models": {},
        "output": "",
        "minifier": {
          "enable": true,
          "exceptionRoutes": false,
          "options": {
            "removeComments": true,
            "collapseWhitespace": true,
            "collapseBooleanAttributes": true,
            "removeAttributeQuotes": true,
            "removeEmptyAttributes": true
          }
        }
      }
  • js: Object How you want Roosevelt to handle module bundling and minifying your frontend JS:

    • sourcePath: Subdirectory within staticsRoot where your JS files are located. By default this folder will not be made public, but is instead meant to store unminified JS source files which will be minified and written to the public folder when the app is started.

    • webpack: Parameters related to bundling JS with Webpack:

      • enable: Enable Webpack bundling.

      • bundles: Array Declare one or more Webpack configurations to bundle JS with.

        • env: String Bundle only in dev or prod mode. Omitting env will result in bundling in both modes.

        • config: Object or String The Webpack configuration to send to Webpack. Can also be a path to a Webpack config file relative to the app directory.

        • Examples: Array of Objects

          • Webpack bundle example declaring one bundle:

            [
              {
                "config": {
                  "entry": "${js.sourcePath}/main.js",
                  "output": {
                    "path": "${publicFolder}/js",
                    "filename": "bundle.js"
                  }
                }
              }
            ]
          • Webpack bundle example declaring one bundle only used in dev mode:

            [
              {
                "env": "dev",
                "config": {
                  "entry": "${js.sourcePath}/main.js",
                  "output": {
                    "path": "${publicFolder}/js",
                    "filename": "bundle.js"
                  }
                }
              }
            ]
          • Webpack bundle example declaring multiple bundles:

            [
              {
                "config": {
                  "entry": "${js.sourcePath}/main.js",
                  "output": {
                    "path": "${publicFolder}/js",
                    "filename": "bundle.js"
                  }
                }
              },
              {
                "config": {
                  "entry": "${js.sourcePath}/moreStuff.js",
                  "output": {
                    "path": "${publicFolder}/js",
                    "filename": "bundle2.js"
                  }
                }
              },
              etc...
            ]
      • verbose: string Enable Webpack verbose error handler.

    • Default: Object for manually created apps.

      {
        "sourcePath": "js",
        "webpack": {
          "enable": false,
          "bundles": [],
          "verbose": false
        }
      }

      Default: Object for apps generated with generator-roosevelt:

      {
        "sourcePath": "js",
        "webpack": {
          "enable": true,
          "bundles": [{
            "config": {
              "entry": "${js.sourcePath}/main.js",
              "devtool": "source-map",
              "output": {
                "path": "${publicFolder}/js"
              },
              "resolve": {
                "alias": {
                  "fs": false,
                  "path": false
                },
                "modules": ["${js.sourcePath}", "${publicFolder}/js", "${appDir}", "node_modules"]
              }
            }
          }]
        }
      }
  • publicFolder: All files and folders in this directory will be exposed as static files in development mode or when hostPublic is enabled.

  • staticsRoot: Relative path on filesystem to where your source static assets are located. By default this folder will not be made public, but is instead meant to store unprocessed or uncompressed source assets that will later be preprocessed and exposed in public.

  • symlinks: Array Declare one or more symlinks to be generated at runtime.

    • source: String Path to be linked to.

      • Roosevelt will not attempt to generate a symlink to a source path that does not exist.
    • dest: String Path to place symlink.

      • If this destination path already exists it will not be overwritten.
    • Default: Array of Objects [].

      • Will be set to the following in apps generated with generator-roosevelt:

        [
          {
            "source": "${staticsRoot}/images",
            "dest": "${publicFolder}/images"
          }
        ]
  • minify: Enables HTML and CSS minification. This feature is automatically disabled during development mode.

  • versionedPublic: If set to true, Roosevelt will prepend your app's version number from package.json to your public folder. Versioning your public folder is useful for resetting your users' browser cache when you release a new version.

Events

Roosevelt provides a series of events you can attach code to by passing a function to the desired event as a parameter to Roosevelt's constructor like so:

require('roosevelt')({
  onServerStart: (app) => { /* do something */ }
})

Event list

  • onServerInit(app): Fired when the server begins starting, prior to any actions taken by Roosevelt. Some Express variables exposed by Roosevelt are not available yet during this event.
  • onStaticAssetsGenerated(app): Fired when the server finishes init but before the server starts.
  • onServerStart(app): Fired when the server starts.
  • onAppExit(app): Fired when the app recieves a kill signal.
  • onReqStart(req, res, next): Fired at the beginning of each new request.
    • req: The request object created by Express.
    • res: The response object created by Express.
    • next: Callback to continue with the request. Must be called to continue the request.
  • onReqBeforeRoute(req, res, next): Fired just before executing the controller.
    • req: The request object created by Express.
    • res: The response object created by Express.
    • next: Callback to continue with the request. Must be called to continue the request.
  • onReqAfterRoute(req, res): Fired after the request ends.
  • onClientViewsProcess(template): Fired to preprocess templates before being exposed to the client.
    • template: A string containing a template written in any JS-based templating engine (e.g. Teddy, Pug, ejs, etc)

Making model files

Place a file named dataModel.js in mvc/models.

Here's a simple example dataModel.js data model:

module.exports = () => {
  return {some: 'data'}
}

In more complex apps, you might query a database to get your data instead.

Making view files

Views by default are Teddy templates. See the Teddy documentation for information about how to write Teddy templates.

You can also use different templating engines by tweaking Roosevelt's MVC parameters.

Making controller files

Controller files are places to write Express routes. A route is the term Express uses for URL endpoints, such as http://yoursite/blog or http://yoursite/about.

Controllers bind models and views together.

To make a new controller, make a new file in the controllers directory. For example:

module.exports = (router, app) => {
  // router is an Express router
  // and app is the Express app created by Roosevelt

  // standard Express route
  router.route('/about').get((req, res) => {

    // load a data model
    let model = require('models/dataModel')()

    // render a template and pass it the model
    res.render('about', model)
  })
}

Sometimes it is also useful to separate controller logic from your routing. This can be done by creating a reusable controller module.

An example would be creating a reusable controller for "404 Not Found" pages:

// reusable controller "notFound.js"
module.exports = (app, req, res) => {
  let model = { content: 'Cannot find this page' }
  res.status(404)
  res.render('404', model)
}

Reusable controller modules differ from standard controller modules in that they accept req and res arguments in addition to app. They are meant to be called from within routes rather than define new routes.

This allows them to be called at will in any other controller's route when needed:

// import the "notFound" controller logic previously defined
const throw404 = require('controllers/notFound')

module.exports = (router, app) => {
  router.route('/whatever').get((req, res) => {

    // test some logic that could fail
    // thus triggering the need for the 404 controller
    if (something) {

      // logic didn't fail
      // so render the page normally
      let model = require('models/dataModel')
      res.render('whatever', model)
    }
    else {

      // logic failed
      // so throw the 404 by executing your reusable controller
      throw404(app, req, res)
    }
  })
}

Making isomorphic controller files

You can also write isomorphic controller files that can be shared on both the client and the server:

// isomorphic controller file about.js
module.exports = (router, app) => {
  router.route('/about').get((req, res) => {
    let model

    // do any pre-render server-side stuff here
    if (router.server) {
      // populate the model with database queries and other transformations that are exclusive to the server
      // isoRequire allows you to require a file only on the server; it will always return false on the client
      // this makes it possible to share this file with frontend module bundlers without server-exclusive files
      // being included in your bundle
      model = router.isoRequire('models/global')(req, res) // get some data common to all pages

      // do things you only need to do if it's a server-side render (when serving HTML from the server, not JSON)
      if (router.serverSideRender(req)) {
        // do SSR-exclusive things here
      }
    }

    // do any pre-render client-side stuff here
    if (router.client) {
      model = window.model // assuming this was fetched from somewhere at some point beforehand
    }

    // do any pre-render stuff common to both the backend and frontend here before calling the render method
    model.content.pageTitle = 'About'

    // if it's an API request (as defined by a request with content-type: 'application/json'), then it will send JSON data
    // if not, it will render HTML
    router.apiRender(req, res, model) || res.render('about', model)

    if (router.client) {
      // do any post-render client-side stuff here (e.g. DOM manipulation)
    }
  })
}

roosevelt-router

When using controller files on the client, you will need to include and configure roosevelt-router in your main JS bundle before loading your controller files:

// main.js — frontend JS bundle entry point

// require and configure roosevelt-router
const router = require('roosevelt/lib/roosevelt-router')({

  // your templating system (required)
  templatingSystem: require('teddy'),

  // your templates (required)
  // requires use of clientViews feature of roosevelt
  templateBundle: require('views'),

  // supply a function to be called immediately when roosevelt-router's constructor is invoked
  // you can leave this undefined if you're using teddy and you don't want to customize the default SPA rendering behavior
  // required if not using teddy, optional if using teddy
  onLoad: null,

  // define a res.render(template, model) function to render your templates
  // you can leave this undefined if you're using teddy and you don't want to customize the default SPA rendering behavior
  // required if not using teddy, optional if using teddy
  renderMethod: null
})

// load all isomorphic controllers
// leverages isomorphicControllers roosevelt feature
require('controllers')(router)

router.init() // activate router
API

Constructor parameters:

When you call roosevelt-router's constructor, e.g. const router = require('roosevelt/lib/roosevelt-router')(params), the params object can accept the following methods:

  • templatingSystem (required): Which HTML templating system you would like to use. Supply the Node.js module. teddy is recommended, but not required.
  • templateBundle (required): A JavaScript object containing a bundle of HTML templates. It is recommended that you use the clientViews feature of Roosevelt to supply this, but not required.
  • onLoad: A function that will be called immediately after roosevelt-router's constructor is invoked. You can leave this undefined if you're using Teddy and you don't want to customize the default SPA rendering behavior.
    • Optional if using Teddy. Required if not using Teddy.
  • renderMethod: Define a res.render(template, model) function to render your templates. You can leave this undefined if you're using Teddy and you don't want to customize the default SPA rendering behavior.
    • Optional if using Teddy. Required if not using Teddy.

Instance members:

When you get a router object after instantiating roosevelt-router e.g. const router = require('roosevelt/lib/roosevelt-router')(params), the following properties and methods are available to you:

  • router.isoRequire(module): Function Like require but designed to fail silently allowing || chaining.

    • Example: let model = router.isoRequire('models/dataModel') || window.model.
      • Thus, if models/dataModel does not exist, it will fall back to window.model.
  • router.apiRender(req, res, model): Function Server-side method to send JSON data in response to the request instead of HTML, but only when the request's content-type is application/json. Otherwise, fails silently allowing || chaining.

    • Arguments:

      • req: Express request object for this request.
      • res: Express response object for this request.
      • model: Data model to send to the template.
    • Example: router.apiRender(req, res, model) || res.render('about', model).

  • router.onSubmit(callback): Function Client-side convenience method for handling form submits to the server in a SPA-friendly way. You can of course define your own DOM events however you like, but router.onSubmit gives you some stuff for free, such as preventing the page reload when the form is submitted, automatically sending a fetch to the server with the form data, automatically detecting if the response is JSON or text, and giving you an easy callback interface to handle the response with minimal boilerplate.

    • Arguments:

      • callback: Callback function to execute when the request is complete. The callback function will be provided with two arguments: a standard event object for the DOM event and the data that was sent back from the request.
    • Example:

      • router.onSubmit((e, data) => {
          // e is the submit event object
          // data is the response from the server
        })
  • router.updatePage(markup, targetContainer): Function Convenience method for replacing some or all of the page with new markup.

    • Arguments:

      • markup: String of markup to update the page with.
      • targetContainer: What DOM element will be the container for your new markup. If none is specified, the entire <body> tag will be replaced and the <title> tag will be updated if the markup fragement containts a <title> tag.
    • Example with a targetContainer: router.updatePage(markupFragment, document.getElementById('some-container))

    • Example without a targetContainer: router.updatePage(fullPageMarkup)
  • router.serverSideRender(req) and router.ssr(req): Function Server-side method to check to see if the request is full page load (a server-side render) or if it's an API request. Retruns true if it's a full page load or returns false if it is an API request.

    • Arguments:
      • req: Express request object for this request.
  • router.backend: Boolean True if the execution context is the Node.js server.

  • router.server: Boolean True if the execution context is the Node.js server.

  • router.frontend: Boolean True if the execution context is the browser.

  • router.client: Boolean True if the execution context is the browser.

Express variables exposed by Roosevelt

Roosevelt supplies several variables to Express that you may find handy. Access them using app.get('variableName').

Express variableDescription
expressThe Express module.
routerInstance of router module used by Roosevelt.
routePrefixPrefix appended to routes via the routePrefix param. Will be '' if not set.
routesList of all routes loaded in the Express app by Roosevelt.
viewEngine e.g. teddy by defaultAny view engine(s) you define will be exposed as an Express variable. For instance, the default view engine is teddy. So by default app.get('teddy') will return the teddy module.
view engineDefault view engine file extension, e.g. .html.
formidableThe formidable module Roosevelt uses internally. Used for handling multipart forms.
morganThe morgan module Roosevelt uses internally. HTTP request logger middleware.
expressSessionThe express-session module Roosevelt uses internally. Session middleware.
loggerThe roosevelt-logger module Roosevelt uses internally. Used for console logging.
modelsPathFull path on the file system to where your app's models folder is located.
viewsPath or viewsFull path on the file system to where your app's views folder is located.
controllersPathFull path on the file system to where your app's controllers folder is located.
staticsRootFull path on the file system to where your app's statics folder is located.
publicFolderFull path on the file system to where your app's public folder is located.
htmlPathFull path on the file system to where your app's HTML static page source files are located.
cssPathFull path on the file system to where your app's CSS source files are located.
jsPathFull path on the file system to where your app's JS source files are located.
htmlRenderedOutputFull path on the file system to where your app's rendered and minified staic HTML files are located.
cssCompiledOutputFull path on the file system to where your app's minified CSS files are located.
clientViewsBundledOutputFull path on the file system to where your app's client-exposed views folder is located.
envEither development or production.
paramsThe parameters you sent to Roosevelt.
appDirThe directory the main module is in.
appNameThe name of your app derived from package.json. Uses "
0.23.2

2 months ago

0.23.1

2 months ago

0.23.0

3 months ago

0.22.16

5 months ago

0.22.15

5 months ago

0.22.12

6 months ago

0.22.11

6 months ago

0.22.14

6 months ago

0.22.13

6 months ago

0.22.10

6 months ago

0.22.9

6 months ago

0.22.8

6 months ago

0.22.7

6 months ago

0.22.6

7 months ago

0.22.5

7 months ago

0.22.4

7 months ago

0.22.3

7 months ago

0.22.2

7 months ago

0.22.1

8 months ago

0.22.0

8 months ago

0.21.16

11 months ago

0.21.14

12 months ago

0.21.15

12 months ago

0.21.13

1 year ago

0.21.12

1 year ago

0.21.10

1 year ago

0.21.11

1 year ago

0.21.8

2 years ago

0.21.7

2 years ago

0.21.9

2 years ago

0.21.6

2 years ago

0.20.1

2 years ago

0.20.0

2 years ago

0.21.5

2 years ago

0.21.4

2 years ago

0.21.3

2 years ago

0.21.2

2 years ago

0.21.1

2 years ago

0.21.0

2 years ago

0.19.13

2 years ago

0.19.14

2 years ago

0.19.12

3 years ago

0.19.11

3 years ago

0.19.10

3 years ago

0.19.9

3 years ago

0.19.8

4 years ago

0.19.7

4 years ago

0.19.6

4 years ago

0.19.5

4 years ago

0.19.4

4 years ago

0.19.3

4 years ago

0.19.2

4 years ago

0.19.0

4 years ago

0.19.1

4 years ago

0.18.3

4 years ago

0.18.2

4 years ago

0.18.1

4 years ago

0.18.0

5 years ago

0.17.1

5 years ago

0.17.0

5 years ago

0.16.2

5 years ago

0.16.1

5 years ago

0.16.0

5 years ago

0.15.1

5 years ago

0.15.0

5 years ago

0.14.6

5 years ago

0.14.5

5 years ago

0.14.4

5 years ago

0.14.3

5 years ago

0.14.2

6 years ago

0.14.1

6 years ago

0.14.0

6 years ago

0.13.0

6 years ago

0.12.2

6 years ago

0.12.1

6 years ago

0.12.0

6 years ago

0.11.9

7 years ago

0.11.8

7 years ago

0.11.7

7 years ago

0.11.6

7 years ago

0.11.5

7 years ago

0.11.4

7 years ago

0.11.3

7 years ago

0.11.2

7 years ago

0.11.1

7 years ago

0.11.0

7 years ago

0.10.8

7 years ago

0.10.7

7 years ago

0.10.6

7 years ago

0.10.5

7 years ago

0.10.4

7 years ago

0.10.3

7 years ago

0.10.2

7 years ago

0.10.1

7 years ago

0.10.0

7 years ago

0.9.4

7 years ago

0.9.3

7 years ago

0.9.2

7 years ago

0.9.1

7 years ago

0.9.0

7 years ago

0.9.0-beta.1

7 years ago

0.8.18-beta.1

7 years ago

0.8.17

7 years ago

0.8.16

7 years ago

0.8.15

7 years ago

0.8.14

7 years ago

0.8.13

7 years ago

0.8.12

7 years ago

0.8.11

7 years ago

0.8.10

7 years ago

0.8.9

7 years ago

0.8.8

7 years ago

0.8.7

7 years ago

0.8.6

7 years ago

0.8.5

7 years ago

0.8.4

8 years ago

0.8.3

8 years ago

0.8.2

8 years ago

0.8.1

8 years ago

0.8.0

8 years ago

0.7.12

8 years ago

0.7.11

8 years ago

0.7.10

8 years ago

0.7.9

8 years ago

0.7.8

8 years ago

0.7.7

8 years ago

0.7.6

8 years ago

0.7.5

8 years ago

0.7.4

8 years ago

0.7.3

8 years ago

0.7.2

8 years ago

0.7.1

8 years ago

0.7.0

8 years ago

0.6.33

8 years ago

0.6.32

8 years ago

0.6.31

8 years ago

0.6.30

8 years ago

0.6.29

8 years ago

0.6.28

8 years ago

0.6.27

8 years ago

0.6.26

8 years ago

0.6.25

8 years ago

0.6.24

8 years ago

0.6.23

8 years ago

0.6.22

8 years ago

0.6.21

9 years ago

0.6.20

9 years ago

0.6.19

9 years ago

0.6.18

9 years ago

0.6.17

9 years ago

0.6.16

9 years ago

0.6.15

9 years ago

0.6.14

9 years ago

0.6.13

9 years ago

0.6.12

9 years ago

0.6.11

9 years ago

0.6.10

9 years ago

0.6.9

9 years ago

0.6.8

9 years ago

0.6.7

9 years ago

0.6.6

9 years ago

0.6.5

9 years ago

0.6.4

9 years ago

0.6.3

9 years ago

0.6.2

9 years ago

0.6.1

9 years ago

0.6.0

10 years ago

0.5.34

10 years ago

0.5.33

10 years ago

0.5.32

10 years ago

0.5.31

10 years ago

0.5.30

10 years ago

0.5.29

10 years ago

0.5.28

10 years ago

0.5.27

10 years ago

0.5.26

10 years ago

0.5.25

10 years ago

0.5.24

10 years ago

0.5.23

10 years ago

0.5.22

10 years ago

0.5.21

10 years ago

0.5.20

10 years ago

0.5.19

10 years ago

0.5.18

10 years ago

0.5.17

10 years ago

0.5.16

10 years ago

0.5.15

10 years ago

0.5.14

11 years ago

0.5.13

11 years ago

0.5.12

11 years ago

0.5.11

11 years ago

0.5.10

11 years ago

0.5.9

11 years ago

0.5.8

11 years ago

0.5.7

11 years ago

0.5.6

11 years ago

0.5.5

11 years ago

0.5.4

11 years ago

0.5.3

11 years ago

0.5.2

11 years ago

0.5.1

11 years ago

0.5.0

11 years ago

0.4.33

11 years ago

0.4.32

11 years ago

0.4.31

11 years ago

0.4.30

11 years ago

0.4.29

11 years ago

0.4.28

11 years ago

0.4.27

11 years ago

0.4.26

11 years ago

0.4.25

11 years ago

0.4.23

11 years ago

0.4.22

11 years ago

0.4.21

11 years ago

0.4.20

11 years ago

0.4.19

11 years ago

0.4.18

11 years ago

0.4.17

11 years ago

0.4.16

11 years ago

0.4.15

11 years ago

0.4.14

11 years ago

0.4.13

11 years ago

0.4.12

11 years ago

0.4.11

11 years ago

0.4.10

11 years ago

0.4.9

11 years ago

0.4.8

11 years ago

0.4.7

11 years ago

0.4.6

11 years ago

0.4.5

11 years ago

0.4.4

11 years ago

0.4.3

11 years ago

0.4.2

11 years ago

0.4.1

11 years ago

0.4.0

11 years ago

0.3.3

11 years ago

0.3.2

11 years ago

0.3.1

11 years ago

0.3.0

11 years ago

0.2.9

11 years ago

0.2.8

11 years ago

0.2.7

11 years ago

0.2.6

11 years ago

0.2.5

11 years ago

0.2.4

11 years ago

0.2.3

12 years ago

0.2.2

12 years ago

0.2.1

12 years ago

0.2.0

12 years ago

0.1.4

12 years ago

0.1.3

12 years ago

0.1.2

12 years ago

0.1.1

12 years ago

0.1.0

12 years ago