Proper way to reference files relative to application root in Node.JS

I have a Node.JS application running on Linux at AWS EC2 that uses the fs module to read in HTML template files. Here is the current structure of the application:

/server.js
/templates/my-template.html
/services/template-reading-service.js

The HTML templates will always be in that location, however, the template-reading-service may move around to different locations (deeper subdirectories, etc.) From within the template-reading-service I use fs.readFileSync() to load the file, like so:

var templateContent = fs.readFileSync('./templates/my-template.html', 'utf8');

This throws the following error:

Error: ENOENT, no such file or directory './templates/my-template.html'

I'm assuming that is because the path './' is resolving to the '/services/' directory and not the application root. I've also tried changing the path to '../templates/my-template.html' and that worked, but it seems brittle because I imagine that is just resolving relative to 'up one directory'. If I move the template-reading-service to a deeper subdirectory, that path will break.

So, what is the proper way to reference files relative to the root of the application?

To get an absolute filesystem path to the directory where the node process is running, you can use process.cwd(). So assuming you are running /server.js as a process which implements /services/template-reading-service.js as a module, then you can do the following from /service/template-reading-service.js:

var appRoot = process.cwd(),
    templateContent = fs.readFileSync(appRoot + '/templates/my-template.html', 'utf8');

If that doesn't work then you may be running /service/template-reading-service.js as a separate process, in which case you will need to have whatever launches that process pass it the path you want to treat as the primary application root. For example, if /server.js launches /service/template-reading-service.js as a separate process then /server.js should pass it its own process.cwd().

sorry, no repo enough to just comment:

accepted answer is wrong. hardcoding path.join(__dirname, '../templates') will do excatly what is not wanted, making the service-XXX.js file break the main app if it moves to a sub location (as the given example services/templating)

using process.cwd() will return the root path for the file that initiaded the running process (so, as example a /Myuser/myproject/server.js returns /Myuser/myproject/ )

this is a duplicate of question Determine project root from a running node.js application.

on that question, the __dirname answer got the proper whipping it deserves. beware of the green mark, passers-by

Try

var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8');