nikkomiu / phoenix_inline_svg

Inline SVG module for Phoenix Framework
https://hex.pm/packages/phoenix_inline_svg
MIT License
61 stars 35 forks source link

Undefined function svg_image #25

Closed gregjopa closed 3 years ago

gregjopa commented 5 years ago

I'm working on migrating an app from using the old way to the new way.

Old way: import PhoenixInlineSvg.Helpers

New way: use PhoenixInlineSvg.Helpers, otp_app: :phoenix_inline_svg_example

When running the project locally everything works fine. However, it fails when building the app for deployment during the mix deps.compile step. Here's the error message:

== Compilation error in file lib/phoenix_inline_svg_example_web/views/button_view.ex ==
** (CompileError) lib/phoenix_inline_svg_example_web/views/button_view.ex:9: undefined function svg_image/2
    (elixir) src/elixir_locals.erl:98: :elixir_locals."-ensure_no_undefined_local/3-lc$^0/1-0-"/2
    (elixir) src/elixir_locals.erl:99: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:229: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

I'm using phoenix_inline_svg@1.3.1. Any idea how to resolve this error? Please let me know if there's more info I can provide.

mhanberg commented 5 years ago

Do you compile your phoenix app before you compile your assets?

If yes, I believe this is what this #20 fixes.

The problem is the macro attempts to read the assets out of priv during compilation, but your assets are copied there during brunch/webpack compilation, which usually comes after your elixir app compiles.

This PR moves to reading it out of assets which solves the problem.

cc/ @nikkomiu

gregjopa commented 5 years ago

@mhanberg you're right. Thanks for explaining what's going on!

I can reproduce this error when the svgs are missing from the priv directory.

I created an example repo to demo the issue: https://github.com/gregjopa/phoenix_inline_svg_example. Here are the steps to reproduce this error:

  1. rm -rf priv/static/svg/
  2. mix deps.compile phoenix_inline_svg --force
  3. mix phx.server

    == Compilation error in file lib/phoenix_inline_svg_example_web/views/button_view.ex ==
    ** (CompileError) lib/phoenix_inline_svg_example_web/views/button_view.ex:9: undefined function svg_image/2
        (elixir) src/elixir_locals.erl:98: :elixir_locals."-ensure_no_undefined_local/3-lc$^0/1-0-"/2
        (elixir) src/elixir_locals.erl:99: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
        (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
        (elixir) lib/kernel/parallel_compiler.ex:229: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

Adding the svgs back to priv resolves this error (cp -avr assets/static/svg priv/static). This was tricky to figure out. I'm +1 with the change that PR #20 introduces with reading the svgs from assets/static instead of priv.

mhanberg commented 5 years ago

@gregjopa Cool, I will get mergeable and we'll see what @nikkomiu thinks.

gregjopa commented 5 years ago

I'm going to close this. The solution is make sure svgs exist in priv/static before compiling.

mhanberg commented 5 years ago

FWIW, I don't think that is a robust solution, and this limitation shouldn't dictate your deployment process.

gregjopa commented 5 years ago

@mhanberg agreed. We are not changing our deployment process. We are sticking with the old way using import PhoenixInlineSvg.Helpers due to this issue.

jherdman commented 4 years ago

To throw my hat in the ring, I'll definitely be sticking with the old way as well. The limitation imposed by the "new way" seems to run against the grain.

nikkomiu commented 4 years ago

Because there is enough attention against this and the desire to replace outright the old way with the new way I will re-open it with the anticipated fix being #20

jonator commented 4 years ago

I'm having this same issue. And I don't believe @mhanberg 's solution of reading from assets is ideal, this may break some deployments that use phx digest and or mix release.

Perhaps checking for these conditions then raising specific exceptions can help a developer troubleshoot these asset-related problems. I may be missing something, but worth a thought

mhanberg commented 4 years ago

I did realize that phoenix projects that are generated with --no-webpack do not have an assets directory. So to make it backwards compatible with those projects, the default directory should still be in priv, and the need to change the directory due to using webpack/brunch should be documented.

So to sum things up, I agree that it shouldn't read out of assets by default, but it needs to be configured to behave that way if the user is using something like webpack/brunch.

I will need to clarify this again by looking at the code, but the current implementation for configurable svg directory won't work in this case, but it should be easy to implement.

I can make some progress on this in the next few days.

jonator commented 4 years ago

As a tip; I've mainly run into this problem when building multi stage docker files. To prevent this, all you need to do is make sure webpack runs (npm run deploy) before elixir deps are compiled.

sveredyuk commented 4 years ago

+1 to this issue? Should I wait for merge or pick fork?

nikkomiu commented 4 years ago

The PR for it has a few issues that needed to be addressed, but it's been a while since that PR has been changed. Otherwise I'd still review a PR to fix this issue! I've been busy on other work so haven't had the chance to fix this myself.

Preen commented 4 years ago

+1

Fudoshiki commented 4 years ago

Any fix?

heroku deploy

warning: undefined function svg_image/2
  lib/do_delivers_web/templates/account/settings/_security.html.eex:9
== Compilation error in file lib/do_delivers_web/views/account/settings_view.ex ==
** (CompileError) lib/do_delivers_web/templates/account/settings/_profile.html.eex:5: undefined function svg_image/2
    (elixir 1.10.3) src/elixir_locals.erl:114: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
    (stdlib 3.13) erl_eval.erl:680: :erl_eval.do_apply/6
 !     Push rejected, failed to compile Elixir app.
 !     Push failed
johannesE commented 4 years ago

How can this issue be here for more than a year? This doesn't even work out of the box in development. Now I'm going to have to adjust my release pipeline too? (npm run deploy) The maintainer of this repo requested so many changes that the PR #20 got closed. Something is seriously wrong with this repository. I mean there is a config for what should appear when an image is not found. config :phoenix_inline_svg, not_found: "<strong class=\"is-hidden\">ICON NOT FOUND</strong>" Then why the #$$#% does this fail if the directory is not found?

Sidenote: The floki thing (fixed, but not released for months => I have to use github instead of hex) was already making me suspicious.

Please excuse my angry post. What I really meant to say was:

+1

nikkomiu commented 3 years ago

Should be fixed on v1.4.0