sergio

sergio

Phoenix 1.6.0 LiveView + esbuild + Tailwind JIT + AlpineJS - A brief tutorial

I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into the next-gen of Phoenix!

Most Liked

praveenperera

praveenperera

For people following this guide if you get errors with AlpineJS you need to change the target from es2016 to a minimum of es2017.

# Configure esbuild (the version is required)
config :esbuild,
  version: "0.13.10",
  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__)}
  ]

For google the errors you’ll see are:

module.esm.js:1635 Alpine Expression Error: func(...).catch is not a function

module.esm.js:1701 Uncaught TypeError: func(...).catch is not a function
    at module.esm.js:1701
    at tryCatch (module.esm.js:1628)
    at evaluate (module.esm.js:1646)
    at module.esm.js:2998
    at Function.<anonymous> (module.esm.js:2390)
    at flushHandlers (module.esm.js:1757)
    at stopDeferring (module.esm.js:1762)
    at deferHandlingDirectives (module.esm.js:1765)
    at initTree (module.esm.js:1953)
    at module.esm.js:1921
reisub

reisub

Just to offer an alternative solution how to add a font file, you can also include the font using the postcss-url plugin as follows. (cc @cvkmohan )

1. Place the font in assets/fonts

I only need the one variable font file in WOFF2 format so for me it’s at assets/fonts/Inter.var.woff2.

2. Add postcss-url dependency

npm install postcss-url --save-dev

3. Add the plugin to assets/postcss.config.js

Mine looks like this after adding it:

module.exports = {
  plugins: {
    'postcss-import': {},
    'postcss-url': { url: 'inline' },
    tailwindcss: {},
    autoprefixer: {},
  }
}

4. Add the @font-face definition to your app.css

@font-face {
  font-family: 'Inter';
  font-weight: 1 999;
  src:
    url('../fonts/Inter.var.woff2') format('woff2-variations');
}

The above configuration will inline the font into your CSS like this:

@font-face { font-family: "Inter"; src: url("data:font/woff2;base64,d09G[...]d6eMC") format("woff2-variations"); font-weight: 1 999; }

If you prefer to keep the font(s) in separate files, use copy instead of inline.

outlog

outlog

not quite as easy as @thomas.fortes suggests..

but close if you are OK with a seperate css file for the font (face) and thus using esbuild for it..

  • download the font Inter font family
  • copy the Inter Web folder into say /assets/vendor/fonts and rename the folder to InterWeb (need to avoid spaces!)
  • change the esbuild args in config.exs to:
    ~w(js/app.js vendor/fonts/InterWeb/inter.css --bundle --loader:.woff2=file --loader:.woff=file --target=es2016 --outdir=../priv/static/assets),
  • notice that the app.js is now outputted inside a js folder
    go to your layout and change the js script src to Routes.static_path(@conn, "/assets/js/app.js")
  • above your app.css stylesheet do a:
    <link phx-track-static rel="stylesheet" href="<%= Routes.static_path(@conn, "/assets/vendor/fonts/InterWeb/inter.css") %>"/>

for bonus points:
add GitHub - semencov/tailwindcss-font-inter: TailwindCSS Plugin to integrate with Inter Typeface · GitHub by doing:
npm install --save-dev tailwindcss-font-inter (in the assets folder)
and then add the plugin in the tailwind config:

  plugins: [require('tailwindcss-font-inter')({ 
    importFontFace: false,
  })]

now you can use the css class font-inter wherever you want..

Last Post!

lszyba1

lszyba1

For this one specific error. I wanted to comment, that this error means that you did not install it. And what it usually means is that you don’t have npm as one of the dependencies to do npm install --prefix /assets.

More on a solution here:

It took some time to realize what the error actually meant.
Hope this helps future searchers that find this page on google.
Thanks
Lucas

Where Next?

Popular in Guides/Tuts Top

emilsoman
Hello, While answering a StackOverflow question on how to debug an elixir node running remotely, I thought it may be helpful to write a ...
New
pel_daniel
Hi! I created some animations to explain what happens internally with map &amp; reduce functions. The code is open source. Any feedback...
New
Eiji
Hey, today I give amnesia library a try and found a few problems. I would like describe how to setup it properly and solve problems which...
New
zenw0lf
Hello all! For those wanting to try your hands at Elixir / Phoenix, I wrote a comprehensive tutorial on doing a simple JSON API with sai...
New
bluegene
Hi guys, I’ve been on a personal journey to learn Elixir for the past two years. During this journey I’ve been using the spaced repetiti...
New
hauks96
Hello everyone, I created a deployment tutorial for Phoenix applications with Kubernetes (microk8s) a few months back with the goal of s...
New
georgeguimaraes
Another cool plugin for Neovim, GitHub - jmbuhr/otter.nvim: Just ask an otter! 🦦 · GitHub makes it possible to run linters for embedded c...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
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
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement