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
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 |
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)
}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())
}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)
}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.
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)
}
}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)
}
}
})