I added a JS package to my Phoenix project, specifically TipTap so I could have a text editor. They did not have Phoenix Framework specific install instructions so I used the Vanilla JS instructions and it seems to have worked locally but whenever I try to run fly deploy I get build errors now.
I have checked the following:
Tiptap package is correctly installed in the wordsmith/node_modules/@tiptap folder
My esbuild settings in the config/config.exs file are set to look inside the node_modules folder:
I assume that my issue is some kind of relative path problem? Iām just not pointing correctly to the node_modules folder? But this is my folder structure and I donāt see anything wrong with the relative paths I have.
If anyone could help point out what the trouble spot is here, Iād greatly appreciate it!
P.S. I forgot to add, I also tried:
using a relative path to the node_modules folder in the app.js import. That didnāt work.
marking the path as external (as suggested by the error message) but I must not have done it right because that also didnāt fix anything.
Dependencies are usually not copied over in the build/deploy environment. Esbuild is also not responsible for installing your dependencies, you have to run npm install specifically, how you do that on fly io is beyond my knowledge.
I did as you suggested and updated my Dockerfile and the mix.exs. I suspect there might be another step to your tweaks because I still got an error (albeit a different one now haha)
=> ERROR [builder 13/17] RUN mix assets.deploy 1.3s
------
> [builder 13/17] RUN mix assets.deploy:
1.260 npm ERR! The `npm ci` command can only install with an existing package-lock.json or
1.261 npm ERR! npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or
1.261 npm ERR! later to generate a package-lock.json file, then try again.
1.266
1.267 npm ERR! A complete log of this run can be found in:
1.267 npm ERR! /root/.npm/_logs/2024-05-06T14_03_53_690Z-debug.log
1.280 ** (exit) 1
1.280 (mix 1.16.1) lib/mix/tasks/cmd.ex:74: Mix.Tasks.Cmd.run/1
1.280 (mix 1.16.1) lib/mix/task.ex:478: anonymous fn/3 in Mix.Task.run_task/5
1.280 (mix 1.16.1) lib/mix/task.ex:544: Mix.Task.run_alias/6
1.280 (mix 1.16.1) lib/mix/cli.ex:96: Mix.CLI.run_task/2
1.280 /usr/local/bin/mix:2: (file)
------
Error: failed to fetch an image or build from source: error building: failed to solve: process "/bin/sh -c mix assets.deploy" did not complete successfully: exit code: 1
Iām not sure why this error is being thrown. I have a package-lock.json file in the root directory of my app. and it definitely has a lockfileVersion > 1:
And the other suggestion from the error has already been done. I ran npm install with version 10.5.0. It seems like maybe fly deploy it is not detecting the existence of my package-lock.json at all?
Iām including the above in case the error jogs more memory and you remember some other small facet I need to implement. Thanks for your previous suggestion!
OK. I got it working now. I also posted this question to r/elixir and got a suggestion there:
If you are using most other default configuration, youāll want to have your node_modules directory (along with the package.json etc.), inside of the assets folder.
So I moved package.json, package-lock.json, and the node_modules folder into my assets folder. That seems to have fixed things. The fly deploy ran successfully.
That poster also pointed out the documentation which I had read, but not clearly understood. It looks like there is a line there in option 2 that says āCall npm inside your assets directoryā. I didnāt think that was the option I was using, but it looks like I should have used npm install from the get-go from inside that directory and it would have created the node_modules folder where it needed to go.
I also left in the changes that @dfalling suggested, so Iām not sure if that is part of why things are working now, but Iām glad they are. Thanks again everyone.
If you want to keep that in the root, you can tweak the assets.deploy to not change the directory: ācmd ācd assets npm ciā. Personally I prefer what youāve done now with keeping the Javascript in the assets directory.