simondotm / nx-firebase

Firebase plugin for Nx Monorepos
https://www.npmjs.com/package/@simondotm/nx-firebase
MIT License
180 stars 31 forks source link

`.runtimeconfig.json` does not get copied on incremental builds #37

Closed simondotm closed 1 year ago

simondotm commented 3 years ago

Since .runtimeconfig.json is added to .gitignore, nx does not class it as a dependency, so even though it is listed as an asset for the firebase app, incremental builds will not detect any changes to this file and therefore re-run the build target and copy the asset.

if .runtimeconfig.json is removed from .gitignore it will be added to node_modules/.cache/nx/nxdeps.json as a dependency

but we cant have it as a non-ignored file, since it might get checked into version control. can't put it into dist either, because that folder gets cleaned prior to build.

possibly, emulate may need to have a pre-step that runs getconfig target for every emulation session.

tricky one this.

simondotm commented 3 years ago

I've resolved this in my own repo by calling the getconfig target as a command prior to running the emulate target. This ensures the emulator session:

  1. Builds the project to dist
  2. Copies the latest config to dist post build
  3. Ensures the .runtimeconfig file exists before the emulator starts up.

Will make this change to the next release

ciriousjoker commented 2 years ago

When will this be released? We're currently using a workaround that calls the OS's copy function in some cases, but that's pretty ugly.. This also applies for the .secret.local file used in GCP's Secret Manager.

simondotm commented 1 year ago

So I've been looking into this, and it's a royal pain.

I've confirmed that files in build.options.assets (such as .runtimeconfig.json) are only copied to dist if they are dependencies, and .gitignore files are not dependencies. So there's no play here, unless I add something in the plugin to copy this manually (maybe someday).

The best I've come up with is this:

    "emulate": {
      "executor": "@nrwl/workspace:run-commands",
      "options": {
        "commands": [
          "node -e 'setTimeout(()=>{},5000)'",
          "kill-port --port 9099,5001,8080,9000,5000,8085,9199,9299,4000,4400,4500",
          "firebase functions:config:get --project <project> --config firebase.<app>.json > dist/apps/functions/.runtimeconfig.json",
          "firebase emulators:start --project <project> --config firebase.<app>.json"
        ],
        "parallel": false
      }
    },
    "serve": {
      "executor": "@nrwl/workspace:run-commands",
      "options": {
        "commands": [
          "nx build functions --watch",
          "nx run functions:emulate"
        ],
        "parallel": true
      }
    },

The serve target starts the build with --watch, and also runs the emulate target in parallel.

The emulate target runs commands in series, but waits for 5 seconds before:

The 5 second delay allows the serve target some time to build & start watching the project before the emulators starts.

Emulate no longer runs a build; its there if folks want to start the emulator, but assumes they've done a build first. this is clearer I think.

I dont really like the delay or the need to call the firebase functions:config:get command for every emulator start, but meh.

So its all a bit hacky. Cant think of a better solution rn.

adamstret commented 1 year ago

What exactly is the reason behind the 5sec delay? Can't we just run 1.buildWatch 2.killPorts 3.getConfig 4.emulatorsStart one after another?

simondotm commented 1 year ago

@adamstret The watch command is long running, so we cannot run these commands in series. The 5 second delay allows the initial build & watch to complete before starting the emulator, otherwise we could have a scenario where the emulator starts before the initial build is completed and functions are not ready.

simondotm commented 1 year ago

If anyone has a better solution I'm all ears. 👍

adamstret commented 1 year ago

@simondotm I still don't get it. You're saying that "we could have a scenario where the emulator starts before the initial build is completed...". We can wait for one process to complete (eg. the 'initial build & watch'), before starting the next one (eg. starting the emulator). Or am I missing something?

simondotm commented 1 year ago

You are forgetting that watched builds do not complete.

adamstret commented 1 year ago

I'm not forgeting it, I didn't know it :) thanks for clarifying it for me.

simondotm commented 1 year ago

Maybe we can add exclusion rules to .nxignore Such as !.runtimeconfig

simondotm commented 1 year ago

Incoming PR #137 will fix this.