Plugins Architecture


MapStore2 fully embraces both ReactJS and Redux concepts, enhancing them with the plugin concept.

A plugin in MapStore2 is a smart ReactJS component that is:

In addition a plugin:

Building an application using plugins

To use plugins you need to:

Declare available plugins

Create a plugins.js file where you declare all the needed plugins:

plugins.js:

module.exports = {
    plugins: {
        MyPlugin: require('../plugins/My')
    },
    requires: {}
};

Load / Create plugins configuration object

Use pluginsConfig.json to configure your plugins.

pluginsConfig.json:

{
    ...
    "standard": [
        {
            "name": "Map",
            "cfg": {
                "zoomControl": false,
                "tools": ["locate"]
            }
        },
        ...
    ],
    ...
}

Declare a plugins compatible Redux Store

Create a store that properly initializes plugins reducers and epics (see standardStore.js) :

store.js:

const {combineReducers} = require('../utils/PluginsUtils');
const {createDebugStore} = require('../utils/DebugUtils');

module.exports = (plugins) => {
  const allReducers = combineReducers(plugins, {
     ...
  });
  return createDebugStore(allReducers, {});
};

Use a PluginContainer to render all your plugins

In the root application component require plugins declaration and configuration and use them to initialize both the store and a PluginsContainer (see our PluginContainer.jsx):

App.jsx:

const {pluginsDef} = require('./plugins.js');
const pluginsCfg = require('./pluginsConfig.json');

const store = require('./store')(pluginsDef);

const plugins = PluginsUtils.getPlugins(pluginsDef);

ReactDOM.render(<PluginsContainer plugins={plugins} mode="standard" pluginsConfig={pluginsCfg}/>, ...container...);

Developing a plugin

An example is better than a thousand words:

My.jsx:


// this is a dumb component
const MyComponent = require('../components/MyComponent');
const {connect} = require('../utils/PluginsUtils');

// let's wire it to state and actions
const MyPlugin = connect((state) => ({
   myproperty: state.myreducer.property
}), {
   myaction
})(MyComponent);

// let's export the plugin and a set of required reducers
const myreducer = require('../reducers/myreducer');
module.exports = {
   MyPlugin,
   reducers: {myreducer}
};

The Plugins Example Application

The example shows the plugins infrastructure power in an interactive way.

The UI allows to add / remove plugins from the base applications, and to configure them using a JSON object with plugins configuration properties.