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?]
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’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.
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?
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:
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.