How Add nodejs App to frappe & bench?

I have just been experimenting with this and can confirm that is works!

It took a while to pick through the various connections to fully understand what goes on, so as a reminder to myself and to help anyone else trying to get started with this, I have annotated the gist (for development mode)…

I have not tried in production, so I’ve left that β€œas an exercise for the student”. :smiling_imp:

Some things to notice:

  • the only linking information between the NGinx configuration and the NodeJs app is the port number

  • the only linking information between the NodeJs app and the Frappe configuration is the NodeJs entry-point file path specified in Procfile

  • the name you use in Procfile, (which is custom_app in this example), is the name that appears color coded in Frappe’s log files…

Screenshot_2020-04-14_09-08-33

Screenshot_2020-04-14_09-17-16

It seems as though changes you make to you NodeJs files can only be tested by killing your bench and then rerunning bench start the reloading the browser pages, a long slow pain in the ass. So, if you have a lot of coding and testing to do, it’s going to be better doing it in a separate auto-reloading NodeJs environment.

Update

Something else worth knowing – you can embed the NodeJs app within the directory hierarchy of a Frappe module/app.

So, if you do …

bench new-app library_management

… you’ll end up with:

erpdev@erpdev:~/frappe-bench$ tree -L 1 apps/library_management/
apps/library_management/
β”œβ”€β”€ MANIFEST.in
β”œβ”€β”€ README.md
β”œβ”€β”€ library_management
β”œβ”€β”€ library_management.egg-info
β”œβ”€β”€ license.txt
β”œβ”€β”€ requirements.txt
└── setup.py

3 directories, 5 files
erpdev@erpdev:~/frappe-bench$

Then you can do the following to start your NodeJs apps within it:

erpdev@erpdev:~$ pushd frappe-bench/apps/library_management/
~/frappe-bench/apps/library_management ~

erpdev@erpdev:~/frappe-bench/apps/library_management$ tree -L 1
.
β”œβ”€β”€ MANIFEST.in
β”œβ”€β”€ README.md
β”œβ”€β”€ library_management
β”œβ”€β”€ library_management.egg-info
β”œβ”€β”€ license.txt
β”œβ”€β”€ requirements.txt
└── setup.py

2 directories, 5 files
erpdev@erpdev:~/frappe-bench/apps/library_management$ mkdir -p services/isbn_service
erpdev@erpdev:~/frappe-bench/apps/library_management$ pushd services
~/frappe-bench/apps/library_management/services ~/frappe-bench/apps/library_management ~
erpdev@erpdev:~/frappe-bench/apps/library_management$ pushd isbn_service
~/frappe-bench/apps/library_management/services/isbn_service ~/frappe-bench/apps/library_management/services ~/frappe-bench/apps/library_management ~
erpdev@erpdev:~/frappe-bench/apps/library_management/services/isbn_service$ npm init
This utility will walk you through creating a package.json file.

   :
   :

About to write to /home/erpdev/frappe-bench/apps/library_management/services/isbn_service/package.json:

{
  "name": "isbn_service",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes) yes
erpdev@erpdev:~/frappe-bench/apps/library_management/services/isbn_service$ popd
~/frappe-bench/apps/library_management/services ~
erpdev@erpdev:~/frappe-bench/apps/library_management/services$ tree -L 2
.
└── isbn_service
    └── package.json

1 directory, 1 file

In this case, because of the changed directory path and because of the main setting in package.json, your Profile would have to read:

   :
   :
isbn_service: /usr/bin/node apps/library_management/services/isbn_service/index.js
   :
   :

Update 2020/05/06:

Node apps typically need to load environment variables and other settings.
It’s worth noting that Procfile will launch any non-terminating script.
So you can do for example:

File apps/library_management/services/isbn_service/do_it.sh:

#!/usr/bin/env bash
#
export BASE_DIR=$(dirname "$(realpath $0)");
cd ${BASE_DIR};
npm run nodemon_start;

where npm can handle pre-launch setups of any complexity.

In which case your Procfile would contain instead:

   :
   :
isbn_service: apps/library_management/services/isbn_service/do_it.sh;
   :
   :
7 Likes