DEV Community

loading...

React Apps with Plugins Using ScandiPWA

jherr profile image Jack Herrington Originally published at Medium on ・3 min read

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

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
},
Enter fullscreen mode Exit fullscreen mode

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": {
    }
  },
Enter fullscreen mode Exit fullscreen mode

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];
Enter fullscreen mode Exit fullscreen mode

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

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

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
Enter fullscreen mode Exit fullscreen mode

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]
  }
}
Enter fullscreen mode Exit fullscreen mode

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 
    }
  },
Enter fullscreen mode Exit fullscreen mode

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

"extension": "link:../extension",
Enter fullscreen mode Exit fullscreen mode

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

% cd my-host-app
% yarn
% yarn start
Enter fullscreen mode Exit fullscreen mode

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

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.

Discussion (0)

pic
Editor guide