The goal of using a single frontend codebase for both Confluence Server and Cloud environments enables the development team to provide the same feature set and UI of Excellentable on both platforms. It also allows new features to be added to both platforms on a quicker schedule, as there is no need to develop separate applications. Having a shared UI and frontend codebase also became increasingly important to us as we realized that the Excellentable Cloud app was lagging behind Excellentable Server in regards to the features offered and due to the increased priority of Atlassian on their cloud framework of Confluence would increase the demand for newer features of Excellentable Cloud. So we set about to update Excellentable cloud in an efficient manner that would not put a strain on the development team to meet the demands of both Excellentable applications.
The first step in the process was ensuring that the REST API and Database structure were standardized on both versions of Excellentable. Due to the fact that Excellentable Server was the more mature offering as well as the ability for us to easily make database changes on the Excellentable Cloud app without affecting the users, the majority of the standardization involved updates on the Excellentable Cloud database. These updates include things such as updates to the naming conventions of variables, modifying variable types, and adding variables that were missing. One variable that was added was an instance variable which would respond with whether the Excellentable is being requested for Cloud or Server. Similar modifications were needed on the API side, we needed to ensure that the REST endpoints that were being used on the frontend were present and standardized.
This was done using core webpack concepts, such as entry points, loaders, and plugins.
An entry point indicates which module webpack should use to begin building out its internal dependency graph. Webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly). Through the use of entry points, we were able to specify different entry points for Cloud and Server.
Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph. Loaders were used for three purposes.
Once we were able to get separate bundles, it was just a matter of updating our build and deployment processes to add the required bundles to their specific repositories.