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!
Setting Up An App
The first job is to set up a Create React App. Let’s do this in a directory called scandi-test
.
% 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
Now that our Create React App based application is enabled for ScandiPWA plugin it’s time to make it extensible. Over in App.js
let’s create a new function called getData
and define it like so:
/** @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
In the parent directory of my-host-app
we create a peer directory called extension and initialize it as an NPM repo with some directories like so:
% 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
Now we can go back to the package.json
of my-host-app
and enable 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:
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
One the Blue Collar Coder channel we have a video that walks through getting this all working using a far more interesting example. Go have a look!
Conclusions
Pluggable architectures are a great way to move your highly verticalized application to something that is an extensible platform that folks can customize to match their requirements. This ScandiPWA webpack plugin (which can be used outside of CRA) allows you to specify extension points and override their functionality. That gives you a great new architectural tool for NodeJS applications.
Top comments (0)