How to deploy my express on netlify lambda function with folders inside src folder?

I just notice that the deployment of my netlify lambda function won’t read my sub folder in src folder and trying to find a solution to that so can anyone show me a proper way to do it?

Hi @Yato

Can you share more details about what you are trying to accomplish? Are you able to share the repository you are deploying from?

I want to deploy my express api with folder structures like this but i think the folder models and routers didn’t get included in production. However it runs fine with localhost
image

here is the repository https://github.com/SeakMengs/Confession-API

Thanks @Yato for confirming what I thought.

As mentioned in the included_files documentation

Paths are relative to the base directory.

The paths in the netlify.toml are relative to the src directory.

However, if you move the const routerModule = require('./routers/router') and const postModel = require('./models/models') lines to the top of the api.js file, there is no need to specify them as included_files (or external_modules) as the build system will automatically include them. From the same documentation

Although our build system includes statically referenced files (like require("./some-file.js")) by default…

Also, a good idea is to not commit a .env file with secrets in it. Use environment variables set via the UI instead.

@coelmay I moved const routerModule = require('./routers/router') and const postModel = require('./models/models') lines to the top of the api.js but it still doesn’t work, I try to get send a request to the api but I get the same 10second time out

And also thank for your concern I know the risk of commit a .env file with secrets in it, It’s just for practice purpose and I will regenerate a new one when I set my repository to private

Of course, the other issue in the netlify.toml is

[build]
    functions = "functions"

however the functions are in src.

Addition

If you run netlify functions:build --src src locally, you will see an api.zip file created. In this file is the bundled function including the models and routers directories.

Have you tried using Netlify CLI to develop/debug locally?

Addition 2
There is no need for the build script. Using the following configuration in the netlify.toml is enough

[build]
    functions = "src"
    publish = "dist"

There is no need to set a build command via the UI as the site doesn’t need building—only the functions so, and they are done automatically.

Remove

"scripts": {
  "start": "netlify-lambda serve src",
  "build": "netlify-lambda build src"
},

from the package.json as they are not required.

@coelmay honestly I have no idea what to do with that zip files :sweat_smile: and I have never used netlify cli before but I just install after u tell me

You don’t have to do anything with them. I was using them to demonstrate that the bundler is including the other files.

Netlify CLI (IMHO) is the tool to use, not netlify-lambda as is it continually added to and updated and far more useful for developing locally before deploying to Netlify (which you can do from the CLI too!)

@coelmay Oh I thought it was relate to anything xD. Btw I follow your instruction and notice that my deployment include models folder now but no routers folder :smiling_face_with_tear:
image

Though I cannot send a request on the route that I specify in my route

Also when I use netlify dev to try sending a request, for the first request it send back a respond and for the second request it shutdown my local server

Yes, I see that too. However, I cannot say why at this point.

@coelmay So it was because app.listen(port, () => {console.log(``Listening to port ${port} ``) }) this line of code, I commented and now It work fine with request on local host using netlify dev

@coelmay I changed router.js to routers.js and it shows on the functions but in production still cannot request from my specified route that I wrote in routers.js

You don’t need models and routers as built functions. They are components of the API. Consider changing the file structure to something like

src
├── api.js
└── components
    ├── models.js
    └── router.js

and change the require paths accordingly e.g. const routerModule = require('./components/router')

This then works (along with commenting out the port as you identified). The issue then is going to the /all route, the request takes longer than the 10 second execution limit.

1 Like

@coelmay thank you for continuous help but seems like all request routes that connect to the database doesn’t work. Only response from router.get("*", (req, res) => { res.send("This api route does not exist!"); }) works

@coelmay so apparently my API didn’t work because the .env file never get read, I remove .env put the mongodb link in api.js file and it work on production now!

mongoose.connect(
    "mongodb+srv://" + url.QueryEscape(username) + ":" + 
		url.QueryEscape(password) + "@" + cluster + ,
    { useNewUrlParser: true, useUnifiedTopology: true },
    function (err, res) {
        if (err) {
            console.warn(err);
        }
        try {
            console.log('Connected to Database');
        } catch (err) {
            throw err
        }
    } 
)

Thank you for your support throughout this tough time, really appreciate it :))

2 Likes

Thanks for the awesome suggestions here, @coelmay! Glad everything is working now, @Yato.

1 Like