Yarn handling in the Dockerfile doesn't account for modern installs
During the build, the dockerfile will pull across the node_modules directory to the final image. This has a few ramifications:
- Assumes Yarn 1/2 is being used
- Yarn 3
pnpstores packages in.yarninstead - Yarn 3 can be set to use the
node_moduleslinker which still stores packages innode_modules, but requires overriding through.yarnrc.yml, which is also not copied across in the Dockerfile
This should probably be a config option (yarn classic/modern):
Classic: copies node_modules across
Modern: copies .yarn and .yarnrc.yml, and respects node-linker, which means copying either node_modules or .yarn across
Instead of a config option, is it possible to tell via inspecting the contents of the files on the machine what the right thing to do is?
Yes - the presence of .yarnrc.yml indicates the user is running Yarn 3+. Parsing .yarnrc.yml and pulling out the value of nodeLinker (either node-modules for legacy behaviour or pnp for modern behaviour, default pnp if no value) will let you determine whether the we need to copy .yarn/ (modern, nodeLinker: pnp), node_modules/ (classic), or both (modern, nodeLinker: node-modules).
A typical Dockerfile produced for a Rails application using a jsBundler looks like the following:
https://github.com/fly-apps/dockerfile-rails/blob/main/test/results/esbuild/Dockerfile#L74-L76
What options are you specifying?
I realised I was missing that info yesterday when I was thinking about it - this is specifically for --precompile=defer. In fairness that's an edge case, and so the purpose of this issue may just be document the issue for others to come across, rather than provide a solution.
To the contrary, that's totally fair. When I started looking into it I came to the conclusion that it would only apply in that case, and was wondering if I was missing something.