Skip to content

Latest commit

 

History

History
155 lines (129 loc) · 6.32 KB

File metadata and controls

155 lines (129 loc) · 6.32 KB

IMS Application Bootstrapper

Available starting in v3.5.0, the bootstrapper provides a consistent means for creating IMS client react application. The bootstrapper replaces the following files that were previously implemented in each application:

  • src/app/containers/App/AppComponent.js
  • src/app/containers/App/index.js
  • src/app/store/createStore.js
  • src/app/store/reducers.js
  • src/app/store/sagas.js

Usage

Import the ImsBootstrapper function and execute the function in the main entry point for your application with configuration options.

import { ImsBootstrapper } from 'ims-shared-client/app'

// Other imports

ImsBootstrapper({
  // config options
})

Configuration options is object with the following signature:

Property Type Description
config* object The ims.js file generated by the build process.
configureHMR function Function to configure hot module reloading. See configure-HMR
isDev boolean Indicates if in development mode. If true will enable hot module reloading.
onAppWillMount function Function to be executed during componentWillMount of the root App module. See App Will Mount
reducers object Global reducers to be loaded into the store at start up. key = reducer name; value = reducer function
routes* function Function to load application routes object or array. See routes
sagas object Global sagas to be loaded into store at start up. key = saga name; value = root saga generator function
stateInitializer.url* string URL path to execute a GET request to load initial state. See State Initializer
tracking object Override options for the configuring the ActionTracker redux middleware. See Tracking

Configure HMR

The configureHMR options is a callback function used to define hot reload points. The function will be called with the following arguments when isDev is true:

  • callback - function with no arguments that will trigger a hot reload of the application

Example

function configureHMR (callback) {
  module.hot.accept('./routes/index', callback)
}

App Will Mount

The onAppWillMount function is called during the componentWillMount lifecycle method of the root App component. This function can be used to dispatch redux actions to run when the application is first loaded.

  • store - instance of the redux store for the application

Example

function onAppWillMount (store) {
  store.dispatch(initializeApp())
}

Routes

The routes function is executed when application is first rendered and when the hot module reloading triggers an application refresh. The function is called with an instance of the redux store and should require the routes path in order for hot reloading to work properly.

  • store - instance of the redux store for the application

Example

function routes (store) {
  return require('./routes/index').default(store)
}

State Initializer

When local storage does not have all the properties for the initial state, the initial state is loaded by making an API request. The stateInitializer.url configuration option tells the boostrapper where to make the request. A GET request is made to this server endpoint. If the refresh token cookie has been set, the cookie will be available in the request on the server as long as the request is to the same origin.

The state initializer API should return a JSON object with the following structure at a minimum:

{
  "success": true,
  "result": {
    // object containing your initial state data
  }
}

The entire result object received from the server is stored in local storage under the IMS-initialState key. The next time the site is loaded, the IMS-initialState key is reloaded from local storage and provided as the initial state for to the client application. Then, a request is made to the server to get an updated initial state. The updated initial state from the server is stored in local storage and merged with the current application state.

Tracking

The tracking configuration option is used to provide overrides to the default ActionTracker options outlined below.

const defaultActionTrackerOptions = {
  user: initialState.global ? initialState.global.currentUser : {},
  sessionId: new Date().getTime(),
  interval: 5,
  path: '/events',
  logging: false,
  method: 'POST',
  include: ['@@router/LOCATION_CHANGE'],
  shouldTrackAction: (a) => {
    const trackPattern = /.+_SAVE|_SELECT_TREE_NODE|_ADD_ITEM|_CREATE_NEW|_CANCEL/
    return a['_track'] || trackPattern.test(a.type)
  }
}

Full Example

main.js

import { ImsBootstrapper } from 'ims-shared-client/app'
import imsConfig from '../shared/ims'
import {
  default as globalReducer,
  rootSaga as globalSagas,
  initializeApp
} from './modules/global'
import {
  default as packagesReducer,
  rootSaga as packagesSagas
} from './modules/packages'

ImsBootstrapper({
  config: imsConfig,
  configureHMR: (callback) => {
    module.hot.accept('./routes/index', callback)
  },
  isDev: __DEV__,
  onAppWillMount: (store) => {
    store.dispatch(initializeApp())
  },
  reducers: {
    global: globalReducer,
    packages: packagesReducer
  },
  routes: (store) => {
    return require('./routes/index').default(store)
  },
  sagas: {
    global: globalSagas,
    packages: packagesSagas
  },
  stateInitializer: {
    url: '/api/state/initialize'
  },
  tracking: {
    shouldTrackAction: (a) => {
      const trackPattern = /.+_SAVE|_DELETE|_SELECT_TREE_NODE|_ADD_ITEM|_CREATE_NEW|_CANCEL/
      return a['_track'] || trackPattern.test(a.type)
    }
  }
})