__dirname appears to be incorrectly set in lambda function

I have a small express app running in a lambda function. It sets the view directory like so:

const viewsDir = path.join(__dirname, '..', 'render');
app.set('views', viewsDir);
app.set('view engine', 'ejs');
app.engine('ejs', ejs.__express); // without this Netlify function can't find ejs

This works fine locally but when I run in Netlify lambda function I see errors in the function logs:

Error: Failed to lookup view "layouts/layout" in views directory "/render"

Why does the path get set incorrectly?

[Update: I forgot to mention that I’m using netlify-lambda to build the app for deployment, so all the modules should be available in the lambda function, right?]

I tried setting the views directory in a different way:

const viewsDir = path.join(process.cwd(), 'lib', 'render');

The logs show that the function is looking in a directory that looks like it could be the correct path, but still doesn’t find the views:

Error: Failed to lookup view "layouts/layout" in views directory "/var/task/lib/render"

I’m thinking now that the ejs files don’t get pulled in to the build when the bundler traverses the code tree. Is the reason the views directory never makes it into the build created by netlify-lambda that they aren’t javascript files?

I also tried adding the render directory to the functions directory since according to the docs You can have subfolders inside the netlify-lambda folder, but those are only for supporting files to be imported by your top level function.

I also tried adding the render directory to the .netlify/functions folder after functions are compiled. In both cases the error persists.

How do you include non-javascript files into Netlify functions? Is it possible?

[Update: btw I followed this post to get the express app running in the lambda function, now it’s just the template rendering that is an issue]

I’ve been thinking about this in the wrong way - the form page should be a static file generated at build time, and the function used to receive the post request, so no need for templates in the lambda express app.

I need to have the form behind a login. I was planning on using auth in express similar to this tutorial. I guess have express redirect to the form page only when the user logs in, and have the post route check for auth.

I’m still a bit unsure about how this would work in practice, so any advice would be appreciated.

Hi there,

Before we cna help, can you tell us more about what your app is doing and what you’re trying to accomplish? Also is the entire app server-rendred in express in lambda functions or do you have a static site that’s being served? Is your repo public? if so, can you share a link?

It’s mostly just html files rendered at build time, that part is working fine. Now I’m trying to add a form that is behind a login.

It’s mostly working but I am having issues reading files in the site deploy directory. I’ve tried using __dirname and process.cwd() to build the path, works locally but errors in netlify lambda.

How do I get the path to the deploy directory inside the function?

There isn’t a traditional filesystem inside the function, @mjgs - so, not sure that you will be able to precisely.

I guess you could try something like using exec() on /bin/pwd to get the directory name, but I am not sure it will help when actually running in AWS…

Yeah I discovered this though a similar approach using a nodejs directory listing library. During the static build the directory is something like /opt/build/repo/_site but then in the function this changes to /mnt/task.

I took a different approach - I found a way to convert the ejs templates into javascript files:

module.exports = `
<html><%= somevariable %></html>

I then require these in the app, render the html and send back to the client. Since the files are javascript files, they get included by the netlify-lambda bundler.

It’s a bit tricky to get nested templates (i.e. with includes) to render, but it’s possible. Using this ‘ejs-in-js’ approach I’ve been able to render pages in netlify functions, so far no major issues apart from loosing syntax highlighting of the templates in the editor.

1 Like