Skip to content

Plugins architecture

mbarto edited this page May 19, 2016 · 9 revisions

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:

  • connected to a Redux store, so that some properties are automatically wired to the standard MapStore2 state
  • wired to standard actions for common events

In addition a plugin:

  • declares one or more reducers that need to be added to the Redux store
  • is fully configurable to be easily customized to a certain level

Building an application using plugins

To use plugins you need to:

  • declare available (required) plugins, properly requiring them from the root application component
  • load / declare plugins configuration
  • create a store that dynamically includes plugins required reducers
  • use a PluginsContainer component as the container for your plugins enabled application slice (can be the whole application or just a part of it)

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

Create a pluginsConfig.js file where you configure your plugins:

pluginsConfig.js:

module.exports = {
   "standard": ["My"]
}

Declare a plugins compatible Redux Store

Create a store that properly initializes plugins reducers:

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:

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');

// 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.