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
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
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
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 Webfolder into say /assets/vendor/fonts and rename the folder toInterWeb(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 toRoutes.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 https://github.com/semencov/tailwindcss-font-inter 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…
thiagomajesk
Great job @sergio! 
Now that Phoenix 1.6.0-rc.0 is out, I tried to migrate my app and this other post also provided me some insights: https://www.mitchellhanberg.com/how-i-handle-static-assets-in-my-phoenix-apps.
I ended up with something like this:
package.json
"scripts": {
"deploy": "npm-run-all --parallel deploy-styles deploy-files",
"deploy-styles": "NODE_ENV=production tailwindcss -i css/app.css -o ../priv/static/assets/app.css --minify",
"deploy-files": "cpx 'static/**/*' ../priv/static",
"watch": "npm-run-all watch-styles watch-files",
"watch-styles": "tailwindcss --input=css/app.css --output=../priv/static/assets/app.css --postcss --watch",
"watch-files": "cpx 'static/**/*' ../priv/static --watch"
}
[...]
"devDependencies": {
"autoprefixer": "^10.2.6",
"npm-run-all": "^4.1.5",
"postcss-import": "^14.0.2",
"tailwindcss": "^2.2.4"
}
dev.exs
watchers: [
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
npm: ["run", "watch", cd: Path.expand("../assets", __DIR__)]
]
PS.: Even though there’s too much configuration for my taste still, the recompilations are fast, really really fast now with esbuild.
Update: BTW: It seems you don’t need to have postcss installed at all if you are using just Tailwind for your styles. You can replace the deploy script with: NODE_ENV=production tailwindcss -i css/app.css -o ../priv/static/assets/app.css --minify
sergio
I couldn’t trigger that error on Alpine 3.5.1 (latest at time of writing) but the change to fix is straightforward. Thanks for pointing it out!







