Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yarn install in the isolated package to fix lockfile #32

Closed
macksal opened this issue Nov 28, 2023 · 10 comments
Closed

yarn install in the isolated package to fix lockfile #32

macksal opened this issue Nov 28, 2023 · 10 comments

Comments

@macksal
Copy link

macksal commented Nov 28, 2023

Currently, yarn lockfiles are copied to the isolated package as-is. However, I think there's an easy solution. Running yarn install in the isolated package will prune unused entries from the lockfile. I believe the resulting lockfile will pin the dependencies of the isolated package to the same dependencies that were pinned in the monorepo. It will also pin the file: dependencies as expected, so there shouldn't be any issue installing the package with --frozen-lockfile in a deploy environment.

It's important that yarn doesn't consider the isolated package as a workspace, but otherwise it seems sound.

Does this seem sensible?

I'll test this in my own repo by running yarn install in a script after isolate. My use case is also Firebase functions.

@0x80
Copy link
Owner

0x80 commented Nov 28, 2023

@macksal If that works it would be too easy! I spent multiple days last week trying to get PNPM lockfiles to work and it wasn't fun 😅 I did figure it out eventually though.

@macksal
Copy link
Author

macksal commented Nov 28, 2023

So far it seems to work as expected. I'm in the middle of the monorepo refactor, so I haven't tested an actual deploy yet. I confirmed the following:

  • Note the contents of yarn.lock for the functions package
  • Make all packages including the functions package into workspaces
  • Install the monorepo
  • Run isolate script, copy lockfile into isolate and yarn install
  • yarn.lock in the isolate directory now matches the original lockfile! (except for the workspace dependencies that were previously using file: or link:)

@0x80
Copy link
Owner

0x80 commented Nov 28, 2023

@macksal Sounds great, but in order to verify that the lockfile doesn't include newer dependencies I think it is important that your original lockfile had some outdated dependencies at least. Is that true in your case?

Because if you generate a fresh lockfile on the root of your monorepo, and then compare that to a re-genareted lockfile in your isolate directory, then everything might be using the latest versions and you can't verify that the generated lockfile is actually still locking the older versions from the original lockfile.

In other words, the generated lockfile should be different between copying and no having copied the original lockfile.

@0x80
Copy link
Owner

0x80 commented Nov 28, 2023

By the way, I have created a monorepo example that uses isolate-package and the firebase-tools fork I released yesterday called firebase-tools-with-isolate. I recommend using that because it will preserve live code updates when running the emulators.

https://github.com/0x80/mono-ts

@macksal
Copy link
Author

macksal commented Nov 28, 2023

Sorry, I should have specified - before moving to a monorepo, each package had it's own lockfile. They each pinned versions that were certainly out of date.

I generated the root lockfile based on the combination of these lockfiles. I can't remember the exact process, I think I did something silly like just concatenating all the individual lockfiles, wiping all node_modules and reinstalling. Yarn seems to normalise the format. I did nohoist all dependencies of my main app, so I think there weren't any conflicting versions.

Then, run isolate on the package containing firebase functions, copy in the lockfile and yarn install it. After all this, the lockfile matches the one in the functions package from right at the start. (Only additions were for isolate-package and its dependencies).

Yarn generally seems pretty sound with regards to lockfiles. After install ,it prunes the unnecessary version locks - it's the same as if you had removed dependencies from package.json.

@macksal
Copy link
Author

macksal commented Nov 28, 2023

By the way, I have created a monorepo example that uses isolate-package and the firebase-tools fork I released yesterday called firebase-tools-with-isolate. I recommend using that because it will preserve live code updates when running the emulators.

I hadn't considered the emulators. I suppose the emulator will serve from the same source that's deployed which is annoying.

I'm not sure I want to rely on a fork of firebase-tools for now. I only deploy from CI so I'd feel okay about just replacing my functions package in-place with the isolated version before deploying instead. It's also possible to rewrite the source property before deploying, or just use separate firebase.json files for emulation/deploy. Not pretty solutions but all are lightweight.

Long term it would be great for firebase-tools to support package isolation natively. For a while I just stored my common code inside my functions package but it's ugly 🤷

I don't really need the other features from your template, my frontend is a react native app and I have no need for bundling. Typescript project references seem to be doing the trick for now. Cool boilerplate though!

@0x80
Copy link
Owner

0x80 commented Nov 28, 2023

👍 I plan to keep the fork in sync with the original fairly regularly. The integration itself changes nothing about the workings of the other parts of the tools, so personally I'm not worried about using this in production apps.

@macksal
Copy link
Author

macksal commented Dec 5, 2023

Update on this: I'm all set up with workspaces. My functions package has a script "predeploy": "yarn build && yarn isolate && yarn --cwd isolate install". My firebase.json has:

"functions": {
    "source": "firebase-functions/isolate",
    "predeploy": [
        "yarn --cwd $PROJECT_DIR/firebase-functions predeploy"
    ]
},

Everything works with a CI deploy to my development environment! Looks like copying in the lockfile and installing is the way to go. It's a little annoying because it wastes time writing node_modules even though it's not uploaded to Firebase. But the version pinning is correct.

@0x80
Copy link
Owner

0x80 commented Dec 5, 2023

Thanks for reporting back!

I will see if I can test and integrate this in the coming weeks...

@0x80
Copy link
Owner

0x80 commented Dec 17, 2023

I have integrated it for yarn classic and it works 👍 Thanks for bringing it under my attention!

I have also forked firebase tools to integrate isolate-package, so you can run the local emulators with live code updates. For more info see this thread firebase/firebase-tools#653 (comment)

@0x80 0x80 closed this as completed Dec 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants