0x80 / firebase-tools-with-isolate

The Firebase CLI with isolate-package integrated to support monorepos
MIT License
24 stars 0 forks source link

codebase support #4

Closed leemhenson closed 7 months ago

leemhenson commented 7 months ago

Hi. So I've been happily using firebase-tools-with-isolate for a little while, on a monorepo with a single monolithic firebase backend package. I've reached the point where I'd like to split that up into separate chunks using firebase codebases. For example:

/packages
  /firebase-backend
    /codebases
      /chunk1
      /chunk2
    /firebase.json
    /src
      /some-other-firebase-functions-and-definitions-here

with firebase.json containing:

{
  "functions": [{
    "source": ".",
    "runtime": "nodejs20",
    "isolate": true,
    "codebase": "default"
  },
  {
    "source": "codebases/chunk1",
    "runtime": "nodejs20",
    "isolate": true,
    "codebase": "chunk1"
  },
  {
    "source": "codebases/chunk2",
    "runtime": "nodejs20",
    "isolate": true,
    "codebase": "chunk2"
  }]
}

I was unable to get Firebase to attempt to deploy the codebases unless they were part of the /packages/firebase-backend tree, and when it did deploy it kept uploading the default codebase bundle instead of the bundle for each codebase.

I did some digging and ended up patching firebase-tools-with-isolate and isolate-package so that it does now correctly deploy each codebase bundle. There's two PRs for discussion, one here and one for isolate-package, and I fully expect that these don't work for other usecases so take them simply as a point of discussion to see if there's a way forward that would work for all scenarios.

The changes in this PR are just to correctly set cwd when running isolate() so that the process.cwd() calls in isolate-package operate within the codebase directory, instead of the firebase root. That allowed me then to write an isolate.config.json file within each codebase, to correctly point far enough up the tree to reach the workspace root.

{
  "workspaceRoot": "../../../.."
}

The isolate-package changes are basically about preventing it from caching any config, so each call to isolate() starts from scratch and doesn't get confused with previously created state.

leemhenson commented 7 months ago

isolate-package PR is here: https://github.com/0x80/isolate-package/pull/75

0x80 commented 7 months ago

@leemhenson Support for multiple firebase packages has been there from the start. It was one of the motivations for creating isolate-package, because I also wanted to split up my codebase.

However, nested structure for packages is not common and seem to complicate things unnecessarily. The prerequisites section of the isolate-package readme talks about this, and Turborepo also does not support it.

For an example you can also have a look at my ts-mono boilerplate.

Let me know if things are unclear, but I think your PRs can be closed.

leemhenson commented 7 months ago

I cannot see an example in ts-mono or elsewhere where there are multiple codebases in a single firebase project. Is there one somewhere?

0x80 commented 7 months ago

I'm not sure what you mean with "codebases in a single firebase project". In a monorepo, each package is self-contained, and packages are typically not nested, because they depend on each other using normal dependency declarations in their package manifest files.

In the case of mono-ts, you can find 2 packages under "services", each deploy to the same firebase project (or different projects if you have a use-case for that). They use the "codebase" property inside firebase.json to give each a unique namespace within the firebase project, which then acts as a prefix for any firebase functions (this allows each package to deploy functions with the same name and not clash)

I do not keep a firebase.json file in the root of my monorepo. But there is only ever one package that deploys firestore rules and indexes, or storage rules, because those can only exist in one place.

In one of my projects I am moving towards grouping each domain in its own package deploying to the same firebase project. This makes bundle sizes smaller and should reduce cold start and deployment times.