React Apps with Plugins Using ScandiPWA

With the move to NodeJS we lost the architectural pattern of creating pluggable applications. Java application servers can be configured at runtime to override pluggable elements, like database drivers, etc. Can we get there with NodeJS? Yep! With the webpack plugin from ScandiPWA we can have our cake and eat it too!

Banner Image

Setting Up An App

% mkdir scandi-test
% cd scandi-test
% yarn create react-app my-host-app

Once that’s done we can go into the host application and update it to use scandipwa-scripts

% cd my-host-app
% yarn add @scandipwa/scandipwa-scripts

With that installed we can change the package.json to change the start and build scripts to be:

"scripts": {
"start": "scandipwa-scripts start",
"build": "scandipwa-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},

There are other tools that work like this; craco, and react-app-rewired.

We then add a scandipwa key to the package.json like so:

  "scandipwa": {
"type": "theme",
"extensions": {
}
},

This registers the application as a host application. In ScandiPWA parlance this is called a “theme” because ScandiPWA is a company that produces a theme for Magento, and this plugin extensibility layer allows ScandiPWA customers the ability to customize that theme down to the function, class, member variable, and more, level.

Making The App Extensible

/** @namespace my-host-app/getData */
const getData = () => [1,2,3,4];

And lets re-define our App React component like so:

function App() {
return (
<div>{JSON.stringify(getData())}</div>
);
}

Is this going to be pretty? Heck no! But we aren’t concerned with looks, we want that yummy functionality. So let’s get to building out our extension.

Building The Extension

% mkdir extension
% cd extension
% yarn init -y
% mkdir -p src/plugin
% touch src/plugin/extension.plugin.js

This is where it starts getting good! Next let’s define our plugin by updating the contents of extension.plugin.js to:

export default {
"my-host-app/getData": {
function: () => [10,20,30,40,50]
}
}

Enabling the Extension

  "scandipwa": {
"type": "theme",
"extensions": {
"extension": true
}
},

This will enable the extension. And while we are in package.json let’s go to dependencies and add:

"extension": "link:../extension",

So let’s start up your application and see where we’ve gotten to:

% cd my-host-app
% yarn
% yarn start

That first yarn establishes the link with the extension project and the second one launches the application.

If everything works you should see:

The override data shown in the host application

I know it doesn’t look like much. But think about the potential. You can mark anything in your application is extensible and have one or more extensions installed that override the functionality.

Right now with this tooling you can override:

  • Functions (as we did)
  • Classes
  • Static member variables
  • Member variables
  • Member functions

Where To Go Next

Associated video for this article

Conclusions

I YouTube as the Blue Collar Coder on advanced FE topics. Check it out!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store