Hi,
I’m trying to set up a frontend + backend based on create-react-app a simple express.js server and have them work with Netlify Dev and Netlify Functions. Originally, I had my project set up as a monorepo:
In the example project I’ve seen, the functions are usually placed inside the same project as the frontend and share the same package.json and node_modules folders. Does that necessarily have to be the case? As far as I can tell, there isn’t a step in the Netlify flow for the backend dependancies to be installed separately from the frontend build step.
Ideally I’d like to keep my existing project structure (or at least keep the front and back ends separate). Has anyone gotten a setup like this to work or do you know of a similar example project?
i’m not really sure what you’re trying to do with the backend. do you want a running express server? Netlify explicitly wants to encourage JAMstack, i.e. serverless.
Hey there, thanks for giving Netlify and Netlify Dev a try. I want to echo what @swyx said. The workflow for JAMstack projects is to ditch “the backend” as such and instead rely on serving static assets from a CDN, and rendering dynamic content as needed from an API. So we don’t use technologies such as Express, because we don’t need to spin up a server
This approach works really well for more sites and apps than you might think, initially. But if you can share more what you are needing the Express server for, we might be able to point you in the right direction. If you are thinking you need a server in order to do server-side things such as process a form or run some code, you can look into using #netlify-platform:functions in order to accomplish much of what a server might take care of back in the day.
If this is still feeling confusing, you might pop into #topics:opentalk , which is our free-form discussion area to discuss this topic in a more general way! Good luck!
Hi @stephencrowe, it’s possible to have separate dependencies for your Netlify Functions. In fact, we recently added the ability to include unbundled JS functions with dependencies stored in a variety of configurations (docs here).
In terms of how you structure your project, could you give a little more detail about the express server part of your project? Are you running express inside of a Netlify Function, or deploying it separately to a server-side service like Heroku (and you use Netlify Functions for something else)?
I am using express as a simple framework for organizing my API and using the package serverless-http to wrap the express app as a lambda function. Netlify actually has a very similar example posted (How to run Express.js apps with Netlify Functions) I think the express part of my question was a bit of a red herring. I am more trying to figure out how to organize a project and its dependancies with both frontend and backend components.
@verythorough, after I posted this question I found the bit in the documentation you pointed out. The missing bit of information I needed that you pointed to was that unbundled dependancies are resolved from the nearest package.json and node_modules.
After fiddling around with Netlify Functions a fair bit and from your answers, I think the following statements are true:
When Netlify pulls a project to build and deploy it, it runs a single build command from the base directory.
Netlify Functions are deployed from the functions folder you specify. They have no build step.
If the functions have dependancies (or are unbundled), the build bot will attempt to resolve them from the closest node_modules folder (e.g. ./node_modules, or …/node_modules, or …/…/node_modules, etc.). Again, the functions have no build step so the dependancies in package.json will not be installed automatically.
If the project has multiple package.json files between the frontend and backend, they each need to be installed using the single build command. I haven’t seen a reference example yet for how to do this but surely some sort of build script could accomplish it.
Please let me know if I misunderstood anything.
At the moment, I merged the dependancies in the two package.json files I have into a single one that the build bot parses and installs. I’d rather not have all my dependancies together but this setup works for the moment. When I have some time, I’ll try to separate them out again and either have them all install in the single build step or try using lerna to manage the dependancies.
What would be helpful is way to easily install dependancies from multiple package.json.
@stephencrowe We’re working on possible solutions for installing dependencies for unbundled functions automatically, but until then, you can string multiple build commands together in a single command, or you can take advantage of npm’s handy lifecycle methods that I just learned about from @DavidWells:
With that trick, if you’ve got your build command saved in your package.json scripts as, say, build (shocking! ), you can add another called prebuild with a command like, cd backend && npm install. Here’s an example in one of our sample repos:
I think the the relevant topics would be project structure, netlify function deployment, and managing dependancies from multiple package.json files. How about: “Structuring and deploying a repository with Netlify Functions and multiple packages”
Jumping late on the train. Is it possible I use NPM with Netlify Functions? I wanted to generate some PDFs and save too S3. Or would I need a microservice for this?
Sure. Can you clarify how you want to use NPM? You just need to have your function either zipped or bundled by the end of your build process. This means you can install your NPM dependencies during your build like you do with the rest of your site.
I wanted to install pdfmake, the server side one. I want the client to submit data, then for the functions to process it, create a pdf, and save to an S3 bucket for an admin type of user to view.
That should work, one thing to consider is that functions by default timeout at 10 seconds unless you are some of our paid plans and contact support to increase this to a maximum of 30 seconds (28/29 seconds realistically). You should check if the function completes within that default time limit.