node.jsnpmmonorepopnpmturborepo

Deploying monorepo projects to AWS Lambda with dependencies


I have set up a Node.js (Typescript) based Monorepo, and I am using Turborepo as the tool to manage the Monorepo. I am using pnpm as my package manager.

All my main projects are present in the apps folder, and reusable components that I want to share across projects are present in the package folder.

My project folder structure is as follows:

apps/
--- project 1/
  ---package.json
  ---app/
  ---node_modules/
  ...
--- project 2
  ---package.json
  ---app/
  ---node_modules/
  ...
packages/
---platform/
  ---package.json
  ---app/
  ---node_modules/
  ...
node_modules/
package.json
turbo.json
...

My code is written, and the build and lint are working as expected locally. I want to now proceed to deploy project 1 on my production system on AWS Lambda, and I tried with both Gitlab CI and AWS CodePipelines - My issues are similar.

My problem is that many of the dependencies are organised as symbolic/hard links. For example, project 1 depends on platform, but this dependency appears as a symbolic link. To publish project 1 to Lambda, I need it to be a standalone project with all dependencies present within the node_modules folder. Links are not useful when I zip project 1.

  1. I tried generating a deployable folder, and copying all dependencies from the root node_modules folder using cp -rL. However, that didn't seem to work with some errors:
cp: cannot overwrite non-directory 'apps/omnibus-comments-handler/node_modules/././typescript' with directory 'node_modules/./typescript'

However, even then I am not sure if that's the right solution as it copies unnecessary dependencies.

  1. I tried using npm instead as it installs dependencies in a flat style - However, even that doesn't seem to work due to similar challenges. For example, platform is a workspace dependency and is a symbolic link.

My objective is to run a "build" command in such a way that all the dependencies are present in the node_modules folder for project 1 so that I can zip it and deploy it to Lambda. What is the best way to achieve this?


Solution

  • Please try:

    turbo prune
    

    I think it's made precisely for this purpose.