kevinlang

kevinlang

Adding assets/vendor to NODE_PATH for vendored JS dependencies

Even for JS-minimal Phoenix apps, there is often a need to add external JS dependencies. The simplest way is to load the script by adding a link to the relevant CDN in the <head>. Another way is to vendor that same asset by committing the UMD artifact into the repository. This is what Phoenix already does for the topbar dependency it uses.

Another approach I found is to not only vendor it, but to instruct esbuild to look into that same vendor directory when it does module resolution. This allows one to specify a module name instead of the relative path. This is particularly useful when one needs to vendor TWO dependencies where one depends on the other.

All one needs to do is to modify config.exs to have an additional NODE_PATH directory. E.g.,

config :esbuild,
  version: "0.17.11",
  default: [
    args:
      ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
    cd: Path.expand("../assets", __DIR__),
    env: %{"NODE_PATH" => "#{Path.expand("../deps", __DIR__)}:#{Path.expand("../assets/vendor", __DIR__)}"}

Then drop the relevant files in assets/vendor. These compiled UMD artifacts can be gotten from e.g., cdnjs.com. In my case, I wanted to add tippy which also depends on @poppyjs/core. I fetched both of those from unpkg.com and saved those into that directory. The final tree looking like:

assets/
  vendor/
    @poppyjs/
      core.js
    tippy.js
    topbar.js

Then I could use tippy as expected in my app.js:

import tippy from "tippy";

I opened a proposal on the phoenix-core mailing list to have this be configured by default for new applications, as I think it is the most clear way to add external dependencies before one needs to step up to something more structured like NPM and such.

Cheers,

Where Next?

Popular in Discussions Top

PragTob
Hello everyone, I know we had quite some threads (read through lots of them) about background job processing but it remains a hotly deba...
New
mikl
I wanted to capitalize a string, and tried using String.capitalize(). That generally works well, until you try to capitalize a word like...
New
thojanssens1
It would be nice to be able to define a redirect from one route to another from the router.ex file. E.g.: redirect "/", UserController, ...
New
arpan
Hello everyone :wave: Today I am very excited to announce a project that I have been working on for almost 3 months now. The project is...
New
chuck
Let me start by stating an assumption: Phoenix is a great approach to building REST APIs. There are many reasons for this, but I will ass...
New
lucaong
Hello Elixir and Nerves community, I have been working for a while on an open-source embedded key-value database for Elixir, that I call...
230 14027 124
New
AlexMcConnell
The reason that Rails is as popular as it is is because it’s very easy for relatively inexperienced developers to get a lot of work done....
588 19652 166
New
shishini
I think this twitter post and youtube video didn’t get as much attention as I hoped I am still new to Elixir, so can’t really judge ...
New
und0ck3d
Hello everyone! A few days ago I’ve created a topic here about how people were creating CMSs with Elixir and Phoenix. I’ve been studying...
New
pdgonzalez872
If this has been asked here before, please point me to where it was asked as I didn’t find it when I searched the forum. Maybe a mailing ...
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 127089 1222
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement