Nx + Nest + Firebase = The dream
I’ve been using Nrwl.io Nx for Angular development for over 3 years now and love the developer experience with the ability to have multiple applications and libraries in a Monorepo.
In my recent development I started using Firebase and became increasingly frustrated with the way in which Firebase Functions are setup using a sub-directory under the main workspace. This did not gel with the Nx apps and libs development as Firebase Functions lived under a separate folder with its own package.json and node_modules installation.
This created many difficulties in being able to share code between the front-end application and the firebase back-end. I used hand crafted tsconfig.json file in the Firebase Functions folder to provide the ability to reference common code in the Nx workspaces. This just didn’t provide a great developer experience. I guess I feel spoiled with Nx functionality.
After reading through countless articles from the likes of Jeff Delaney and various Github issues I was able to finally stitch together and solve my developer experience issues and streamline my development in the process.
Whilst this may not be the most elegant solution I thought it would be of use to the community. A schematic could be written to automate this manual process.
Initialize Nx Workspace
Let’s get started by creating a new coffee app using Nx workspace with the following command:
> npx create-nx-workspace@latest
After specify the various configuration options for my Angular, Nx will scaffold out a workspace with apps and libs.
Open the newly generated workspace using your preferred IDE. Under the apps folder you should see two applications, coffee application and coffee-e2e for end to end tests .
All the following commands are to be run from the root of the workspace.
Nest Application
Installing the Nest Plugin
Installing the Nest plugin to a workspace can be done using the following:
> npm install -D @nrwl/nest
Generating Nest Application
Generating a new Nest application can be done with the following:
> nx generate @nrwl/nest:application <nest-app>
Example:
> nx generate @nrwl/nest:application coffee-api
Serving Nest Application
Your Nest application can be served with the following command:
> nx serve coffee-api
Nx will build and serve the API to the specified port. Any changes to the API will trigger the build process again.
The generated Nest application file structure should look like this:
Firebase
Next is to initialize firebase into the workspace, skip this section if you know what you are doing.
Firebase initialization
Ensure that the Firebase tools have been installed globally using:
> npm install -g firebase-tools@latest
Next is to initialize firebase into the current workspace.
> firebase init
Select the various options required for the Firebase deployment, Functions is required to be setup for the API.
Select an existing Firebase project or create a new one.
Accept all the Firebase defaults or modify as required. Ensure Typescript is selected as the language for Cloud Functions and do not install dependencies.
Specify each of the emulators to setup, ensuring Functions Emulator is selected.
Accept all the Firebase emulator defaults for the various ports. Note these can be changed later if required.
Firebase is now installed into the sub-directory called functions.
Transforming Nest to Firebase
To transform the current Nest application into a Firebase ready one takes a bit of manual intervention.
So let’s get started…
Install the various Firebase dependencies into your root workspace.
> npm install firebase-admin firebase-functions
Install dev dependencies into the workspace.
> npm install -D firebase-functions-test
Create a package.json inside the root source folder of the Nest application.
Next is to modify the angular.json in the root folder of the workspace. Search for the name of your application, in this case I’ve used coffee-api.
The configuration should look like this:
We need to modify the current behaviour of nx serve command as it will build and start the Nest application and listen for incoming requests. Firebase emulator needs to start the dev server for us.
Let’s get started
Rename build to build-node and add another entry under architect called build which will use the nx run command.
The new build command simply executes the build-node. This updates changes the behaviour of the serve command to just build and watch for changes.
Remember that package.json file this needs to make its way into the build output. Add entry into the assets folder like below:
Delete the Firebase functions folder in the root of the workspace as this is no longer required.
Update Nest application bootstrapping to connect express server to Firebase Functions.
Finally update firebase.json functions section, remove the predeploy as both lint and build is done via the deploy command, add source for firebase to know where the compile output is located and the ignore section so firebase does not package these up for deployment. More on deployment later.
Fire it up
Start the Nest application to watch for changes. Open a command prompt using the following:
> nx serve coffee-api
Once this has started, in another command windows start the Firebase emulator:
> firebase emulators:start --only functions --inspect-functions
This could be added as a npm script
After starting the Firebase emulators you will see in the output the API endpoint for making Http calls and also the Emulators status endpoint which can be used to inspect logs.
Setup Debugging
To configure a debugger for the running Nest application:
- Click on Run in menu
- Click create a launch.json file
- Select Node.js from the dropdown.
Modify the the configuration as per below.
This launch configuration will attach to the running Firebase emulator using default port 9229. Need to ensure that the outFiles points to the build output of the Nest application. It’s important to add the skipFiles as this speeds up the attachment of the debug breakpoints.
Deploying to Firebase
If you wish to streamline the build and deployment of Firebase functions you can add additional commands to the angular.json file.
The deploy command will first call build of the API and then call firebase deploy, to deploy only functions to the Firebase.
Let’s test out the deployment.
> nx deploy coffee-api
Summary
I’ve been using this setup of Nx — Nest — Firebase for almost 2 months now and love the developer experience.
I hope this helps the community out is some small way.
The complete source code used here can be found here:
References
The various points of reference that inspired this article.