Runtime Domain Model

Reactium comes with built-in capability to generate run-time modules that can be loaded in your applications. The Reactium opinion makes it easy for your applications to be naturally extended.

umd.js and reactium-umd*.js

Sometimes you need to create a service worker or other separate javascript bundle (separate from the ordinary webpack runtime), that can be loaded into the browser. This can be accomplished easily by creating a reactium-umd.js file in any domain. These files will automatically be collected as separate entries for webpack, and will be compiled into their own UMD (Universal Module Definition) at build-time.

This occurs once during the build in the umdLibraries libraries gulp task. Before this runs, a manifest is generated by the umdManifest gulp task, and the UMD manifest is stored in .tmp/umd-manifest.json

The default UMD javascript module compilation (performed under ./core/umd.webpack.config.js configuration), is meant to be flexible enough for the needs of two primary use cases:

  • A service-worker or worker module.

  • A runtime plugin to extend Reactium

umd-config.json

Optionally found in the same directory as umd.js, when you wish to configure the webpack UMD library generation behavior for the module.

For example, below is the default umd-config.js than can be found in src/sw/umd-config.json in stock Reactium:

umd-config.json
{
    "libraryName": "service-worker",
    "globalObject": "this",
    "babelPresetEnv": false,
    "babelReact": false,
    "babelLoader": false,
    "externals": {},
    "addDefines": true
}

UMD Configuration

Option

Default

Description

libraryName

Basename of current domain directory.

Used as the output filename of the UMD file generated by the webpack UMD library compiled from umd.js

globalObject

window

When external dependencies are provided for your UMD module, this is where they can be found within the module. (Webpack will expect that some other code will have provided the module, for instance by loading from a CDN)

externals

See below

When using umd.js to create a Reactium runtime plugin, this configuration is provided to webpack to designate modules that will be found on the window object.

babelPresetEnv

true

Boolean whether to include the babel env preset in the UMD webpack compilation. (Recommend false for service workers)

babelReact

true

Boolean whether to include the React preset in the UMD webpack compilation. (Recommend false for service workers)

babelLoader

true

Boolean whether to include the babel loader in the UMD webpack compiliation. (Recommend false for service workers)

Make sure to set globalObject to this when creating a service worker, as window does not exist in the running service worker. The default value of window is expected for Reactium runtime plugins.

You will probably also need to prevent loading all babel presets to prevent errors in your service worker from transpilation and webpack runtime issues. Set babelPresetEnv, babelReact, and babelLoader to false for workers.

Set externals to an empty object, to prevent webpack from attempting to create external module dependencies that are inaccessible to the service worker.

Default UMD Externals

Reactium core automatically exports a number of modules on window to make them available for your umd (Universal Module Definition) bundle, when you are making a runtime loadable plugin for Reactium:

default value of "externals" property
{
      "axios": "axios",
      "classnames": "classnames",
      "copy-to-clipboard": "copy-to-clipboard",
      "moment": "dayjs",
      "dayjs": "dayjs",
      "object-path": "object-path",
      "prop-types": "prop-types",
      "react": "react",
      "react-router-dom": "react-router-dom",
      "redux": "redux",
      "redux-super-thunk": "redux-super-thunk",
      "react-dom": "react-dom",
      "/reactium-core/sdk$/": "/reactium-core/sdk$/",
      "semver": "semver",
      "shallow-equals": "shallow-equals",
      "underscore": "underscore",
      "uuid": "uuid",
      "xss": "xss"
}

Externals explained:

Ordinarily, when webpack encounters a require/import statement, it will "bundle" the imported module into your javascript.

When webpack encounters an "external", instead it instructs the javascript where it can find the module externally, usually on the window object. Reactium core provides the above module on window, so you don't have to bundle them into your runtime plugin.

This provides some benefits: 1. you will not incur additional size to your module, when loading it in the browser 2. you will be using the same version of the dependency as core Reactium 3. this exposed the Reactium SDK and named exports to your runtime plugin 4. this allows you to write code for your runtime module in much the same way you would if it were bundled with your application. This helps the local development workflow for runtime plugins immensely.

Last updated