ESBuild (and Yarn ?) not allowing import of Phoenix and LiveView suite in the app.js file

Hi everyone,

This is one is simple to describe (I hope).

As soon as I create the Phoenix app with mix phx.new test --no-ecto I can’t have it to work with LiveView activated.

When I try to launch the server with mix phx.server I get the following :

[info] Running TestWeb.Endpoint with cowboy 2.10.0 at 127.0.0.1:4000 (http)
[info] Access TestWeb.Endpoint at http://localhost:4000
[watch] build finished, watching for changes...
✘ [ERROR] Could not resolve "phoenix_html"

    js/app.js:19:7:
      19 │ import "phoenix_html"
         ╵        ~~~~~~~~~~~~~~

  The Yarn Plug'n'Play manifest forbids importing "phoenix_html" here because it's not listed as a dependency of this package:

    ../../../../../../../.pnp.cjs:45:33:
      45 │           "packageDependencies": [
         ╵                                  ^

  You can mark the path "phoenix_html" as external to exclude it from the bundle, which will remove this error.

✘ [ERROR] Could not resolve "phoenix"

    js/app.js:21:21:
      21 │ import {Socket} from "phoenix"
         ╵                      ~~~~~~~~~

  The Yarn Plug'n'Play manifest forbids importing "phoenix" here because it's not listed as a dependency of this package:

    ../../../../../../../.pnp.cjs:45:33:
      45 │           "packageDependencies": [
         ╵                                  ^

  You can mark the path "phoenix" as external to exclude it from the bundle, which will remove this error.

✘ [ERROR] Could not resolve "phoenix_live_view"

    js/app.js:22:25:
      22 │ import {LiveSocket} from "phoenix_live_view"
         ╵                          ~~~~~~~~~~~~~~~~~~~

  The Yarn Plug'n'Play manifest forbids importing "phoenix_live_view" here because it's not listed as a dependency of this package:

    ../../../../../../../.pnp.cjs:45:33:
      45 │           "packageDependencies": [
         ╵                                  ^

  You can mark the path "phoenix_live_view" as external to exclude it from the bundle, which will remove this error.

3 errors
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme

Rebuilding...

Done in 339ms.

In the priv folder there is no js content.

I am on MacOs Monterey
Phoenix 1.7.6
Elixir 1.14.5
OTP 25

Any idea what could be causing this, since I haven’t even modify any file yet ?

Thanks in advance for your help.

Of course I have read the error message and looked at other issues that somehow look similar but were for umbrella apps (which is not the case here).

I also don’t see why I should make any modification for LiveView and Phoenix to work out of the box (I’m not against it, but I see nothing in that regard when reading the documentation).

I’m not using yarn so I don’t know what the reason is exactly for the error, but the first result on Google seems to hint at a solution: yarnpkg - The Yarn Plug'n'Play manifest forbids importing "XYZ" here because it's not listed as a dependency of this package - Stack Overflow

1 Like

Neither am I.

I don’t even know why it is even mentioned. Might be part of the ESBuild bundling process.

Do you have any Node version on your system? If so which version? Maybe you’re using pnpm?

Esbuild uses a package manager under the hood to a degree as evidenced by needing to deploy it to the Docker file generated whenever you add a new dependency. It shouldn’t have a problem with the existing deps though. I thought hex brought those in.

Have you tried generating a new project? I’ve seen things get weird during the deps step. I’ve always had a node version, typically a major revision or 2 behind latest so I haven’t tried Phoenix without it. You could also try mix assets.setup, mix assets.build or mix assets.deploy to see if something different happens. Assets.setup is one thing that happens in the initial generation stage and it’s possible that got skipped, using another version of the tailwind and esbuild binaries.

1 Like

Not that it solves your problem, but it is probably not a good idea to call your project Test… because it might collide with Tests

1 Like

You’re using yarn instead of npm. Apparently yarn has some stricter rules about what dependencies it’s expecting in package.json.
That is the reason for the error. As you can see on the stack overflow post. I don’t know why yarn has these stricter rules though.

A new phoenix project doesn’t use package.json so if yarn expects this, it will be an error. I don’t think esbuild has anything to do with this. It’s all yarn.

Possible solutions:

  1. Change the yarn config like shown in my previous post
  2. Use npm instead of yarn
  3. Create a package.json yourself with the necessary dependencies

Thanks all for your feedbacks

Yes: Node 18.12.1, I am not using pnpm

Yes, I did it around 10 times even trying to get the shortest pwd just in case, and making sure I don’t have any space in folders’ names

I have tried the three and for mix assets.setup nothing happens, for the last 2 I got the same error.

You’re right, I should not use such generic name, It was just for the sake of example, I used many other genuine names and still the same.

As I said in my previous answer, I am not using Yarn. Actually Yarn is not even installed in my machine since I faced an issue migrating to Yarn 2, I then decided to remove it completely.

I don’t see why I should be manipulating package.json (or Yarn config for someone using Yarn) when starting on a brand new Phoenix app.

As stated earlier, the app has just been created without any extra dependancy than the ones available by default.

Question: Where do we define if ESBuild should be using npm or Yarn ? Since it looks like it is using Yarn under the hood I think a potential solution should be to force it to use npm.

You can find here : https://hexdocs.pm/phoenix/asset_management.html that esbuild will extract app.js in priv/static/assets/js/app.js

The strange thing is that this is not happening in my case, nothing is created.

Do you maybe have some yarn global config files hanging around?

1 Like

Yes I had a ~/.config/yarn/global. , I have removed the yarn folder completely.

The yarn command was not working anyway but just in case…

Esbuild does some yarn detection: esbuild/internal/resolver/resolver.go at 8d46f763792cd0e52f7ca0840cfbf857b24f4fe0 · evanw/esbuild · GitHub

On my phone so hard to dive into how it detects yarn, but I guess it would be related to detection of config files.
If you can remove those I guess it should be fixed.

1 Like

Thanks for the suggestion.

I had several mentions of yarn in my ~/.zshrc

export PATH="$PATH:/opt/yarn-1.22/bin"
export PATH="$PATH:/Users/fahedmahidi/.yarn/bin"

and also a .yarnrc

I have typed the following commands :
rm -rf /usr/local/bin/yarn
rm -rf /usr/local/bin/yarnpkg
rm -rf ~/.yarn

which yarn gives yarn not found

yarn --version gives zsh: command not found: yarn

No trace of Yarn left in ~/.bashrc, ~/.zshrc , ~/.profile, ~/.bash_profile

Yet, I still get the error.

Assets.setup is supposed to download both tailwind and esbuild. Can you type both tailwind and esbuild in another separate directory like your home directory? I think it does nothing if the files already exist but I thought it downloads them to the local project directory. It could download them to a global path but I feel like that shouldn’t be the case.

Have you restarted since removing yarn? Are those steps the recommended uninstall?

Are you using asdf or another version manager? I ask because one great way of moving around a gunked up Node install is to move to 19 or downgrade. You lose everything without a reshim if it’s global or you can override it locally to the directory and get the same effect. I’d try that after a reboot though just in case. There’s also the nuclear option of nuking node and all of its local caching directories. Moving versions has a similar effect though and I’d only nuke it in extreme circumstances. I’d make backups just in case because I have a lot of other things depending on Node compared to most people.

It does kinda sound like yarn is being detected somehow. I’ve used yarn before but in very limited capacities and I’ve never seen this.

Have you looked at this: esbuild/internal/resolver/resolver.go at 8d46f763792cd0e52f7ca0840cfbf857b24f4fe0 · evanw/esbuild · GitHub

There you can see which files are used to detect the yarn manifest mode.

I didn’t get this part. When I type esbuild or tailwind outside nothing happens.

Yes I have restarted. I don’t think they are the recommended uninstall. I did the recommended steps a long time ago. I have mentioned these ones as extra steps I took to ensure Yarn is not here anymore.

Yes I use NVM. I have switched node versions without any change.

I think it is within esbuild process when trying to build based on dependencies, and not on something related to folders out of the project itself. But it is just a hypothesis of mine.

I looked at the file but GO is still foreign language to me. Yet, I tried to look at what it does to find npm, because it is surprising to me that it goes for Yarn first. But I could not figure this out. When I look at what I understand from the code it looks like it is going through the project dependencies’ folders and figure it out for each dependency and not based on the project folder. But I could be wrong.

Yet, looking at the way it goes for checking that Yarn is present I have searched the mentioned files, and could not find it.

I have to say, it’s sad, but I have tried removing phoenix 1.7.6, and use 1.7.0 and now I don’t have any error.

If the issue was coming from my environment such light downgrading should not make any difference, right ?

That’s not too surprising but it may not be easy to find the root cause without upgrading to each version. We on the outside could do a diff and maybe if we’re lucky find just the right dependency or change that triggered it.

I’m sure if you isolated it and could submit a bug report the Phoenix team could likely track it down but thats work on top of work you’ve done. I doubt either one of us could replicate the state your system is in unfortunately so I don’t know if this is something that could be fixed in 1.7.7 or later otherwise. You would be doing future you a favor. Your system shouldn’t be the problem but this is a bug likely caused by code + environment. The code can be technically correct but an environment blind spot can trigger this very easily.

The docs for esbuild are at Esbuild — esbuild v0.7.0 and mention where the executable for esbuild is downloaded to whenever you run assets.setup. Both esbuild and tailwind should be installed there and in your path to work correctly, or so I thought. The mix commands don’t point to that specific path outlined in the docs, they run just the command which again should work anywhere because it’s a global path.

I also haven’t used nvm in years to know how it segregates versions. I just know that for asdf if I don’t reshim I will sometimes forget I have to download all of my global packages again for the new version. Nothing carries over which is why I mentioned it. It’s possible nvm uses shared locations and asdf does have a shared cache but it has to sprinkle that throughout each version you enable when you reshim. I don’t know if that’s accurate but it feels true.

One extra wrinkle that could happen now is that since you have it working in 1.7.0, that you could potentially upgrade to 1.7.6 and not see it again. My guess is there is something around the npm -g that installs the node-managed esbuild vs the go-managed esbuild.

Well, I’m just running into this same issue myself.

mix archive.install hex phx_new
mix phx.new --no-ecto TestTailwind
cd tailwind_test/
mix phx.server
...
✘ [ERROR] Could not resolve "phoenix_html"

    js/app.js:19:7:
      19 │ import "phoenix_html"
         ╵        ~~~~~~~~~~~~~~

  The Yarn Plug'n'Play manifest forbids importing "phoenix_html" here because it's not listed as a dependency of this package:
...

I have no time to look at this right now, but will try to find out what’s wrong.