Phoenix Framework is a Web Application Framework built in Elixir. With the recent 1.6
version release, Phoenix has no nodejs
dependency. Prior to that, Phoenix used webpack
as the build framework for static assets, CSS and JS. However, from version 1.6, Phoenix uses Esbuild as the build tool. The Esbuild package for Phoenix Framework can be found at
Esbuild for Javascript bundling and minification reduced the build times dramatically. The default generator for Phoenix creates the new application with Milligram as the default CSS framework. However, most people would need atleast SCSS
support for their application. When you want to have an SCSS
based framework or you want to write your design with SCSS, another package
%[github.com/CargoSense/dart_sass]
is used. This package creates a wrapper around the dart_sass
cli and allows us to use scss
inside our phoenix application. However, tailwindcss has been the goto CSS framework for a lot of developers in recent times. If you want to use tailwindcss in your Phoenix application, Tailwind package is provided, which is a wrapper around the tailwindcss-cli
tool. So, in most cases, you can get started with application development in Phoenix without having to install nodejs
ecosystem.
However, tailwindcss-cli
comes with some limitations.
- It is not possible to use stylesheets with
postcss-import
orpostcss-nested
tailwindcss-cli
comes bundled with only official plugins. It is not possible to use any external plugins likedaisyui
ortailwind-scrollbar
etc. which are used frequently by developers.
To meet these requirements invariably, we have to get into some node based build tool. A complete overview of asset management in Phoenix Framework can be found at Phoenix Asset Management. Apart from the regular webpack
new age build tools like vite
and parcel
are used by Phoenix developers for asset management. In this article, we will explore integrating parcel
as the build tool into a Phoenix application.
, calls itself as zero configuration build tool for various types of applications and libraries. parcel
caught developer attention recently for the extremely fast parcel-css
- a CSS parser, transformer and minifier written in Rust. parcel-css
can be our one stop shop for CSS processing. It allows us to get rid of the entire host of postcss
plugins.
Enough of history lessons. Time for some hands-on coding.
Let us create a new phoenix application.
mix phx.new my_app
creates a new phoenix application with esbuild
as the build tool.
Remove Esbuild
Removing esbuild
from the application involves mainly 4 steps.
- Remove the esbuild configuration in config/config.exs and config/dev.exs
- Remove the assets.deploy task defined in mix.exs
- Remove the esbuild dependency from mix.exs
- Unlock the esbuild dependency
If you open config/config.exs
file you would find a code snippet similar to this
# Configure esbuild (the version is required)
config :esbuild,
version: "0.14.29",
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__)}
]
These lines configure the esbuild tool. Remove these lines and save the file.
Then open config/dev.exs
file. You would find in the watchers list a line like this
# Start the esbuild watcher by calling Esbuild.install_and_run(:default, args)
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}
This line downloads the esbuild executable and sets up a watcher for changes in css
and javascript
files. Remove these lines and save the file. These two changes will complete the step 1.
Now, open the mix.exs
file - and at the bottom, in the function list of aliases
, under the "assets.deploy"
task, you will find "esbuild default --minify",
. Remove that part. That completes step 2.
Now, in the same mix.exs
file in the functiond defp deps
you will find an entry for the esbuild
module. The line will be something like {:esbuild, "~> 0.4", runtime: Mix.env() == :dev},
. Remove the line and save the file. This completes step 3. And finally moving on to step 4. In the command line type and execute
mix deps.unlock esbuild
These 4 steps allow you to complete remove esbuild
from the application.
Now, let us move on to integrating parcel
as the build tool for both css and javascript in the phoenix application. We will integrate tailwindcss
also as part of the process.
It is a regular practice for phoenix developers to keep everything related to static assets in the folder assets
. Even the build tool configuration, tailwindcss configuration etc. are also kept in the assets
folder normally. However, the parcel watcher
is not working correctly if we install parcel in the assets
folder. It needs to be configured from the application root folder. However, we can keep all the static assets still in the assets
folder.
From the root folder, execute the command
yarn add -D parcel tailwindcss
We need to make one change in our .gitignore
file - to change assets/node_modules
to node_modules
as the node_modules
directory will be in the application root directory now. Similarly, add the .parcel-cache
directory to .gitignore
file.
Now, we have to add two tasks in the package.json
file for watch
and build
Open your package.json
file and add the following code:
"scripts": {
"watch": "parcel watch assets/js/app.js --dist-dir priv/static/assets",
"build": "parcel build assets/js/app.js --dist-dir priv/static/assets"
},
Here we are adding two tasks - watch
and build
in both cases we are taking assets/js/app.js
as the input file and --dist-dir
is the output directory. parcel
handles both css
and js
also with almost zero configuration. Remember that we have a line
import "../css/app.css"
in the app.js
file. So, both css
and js
files are handled with the single input file app.js
and parcel
generates two output files app.css
and app.js
in the --dist-dir
folder.
Now, we have to add a watcher in config/dev.exs
to watch the files for changes and reload. Open config/dev.exs
and add the following line to empty watchers list ( from where you removed the esbuild
line earlier)
yarn: ["run", "watch", cd: Path.expand("../assets", __DIR__)]
We have another small task to perform to configure parcel build for production. Open mix.exs
file and in the function aliases
, for the task "assets.deploy"
( the same place you removed esbuild default minify
) add the task
"yarn build",
before the phx.digest
task.
Finally, because we have removed the esbuild
the 3 javascript libraries that are required for Phoenix, have to be installed from the local deps using yarn. At your terminal, type the command:
yarn add "./deps/phoenix" "./deps/phoenix_html" "./deps/phoenix_live_view"
It installs these packages from the local deps.
At this stage, if we want to use regular css or scss we are good to go. parcel
true to its claim, with no further configuration will work - handling both css
and js
files.
However, if we want to configure tailwindcss
we have a few more steps to go.
tailwindcss
is considered as a postcss
plugin and processed by parcel-css
. parcel-css
honors any postcss
configuration in the same directory if the file is specified as .postcssrc
. So create a file .postcssrc
in the application root directory and add the following code
{
"plugins": {
"tailwindcss": true,
"postcss-import": true,
}
}
We add two plugins - tailwindcss
and the postcss-import
so that we can write our custom css in different files and import them.
Now, the regular tailwindcss
configuration is all that is pending. We need to import the tailwindcss
css files in our app.css
and create a tailwind.config.js
for tailwind configuration.
Let us create a tailwind.config.js
file in our app root directory and paste the following code into it:
module.exports = {
content: ["./assets/js/**/*.js", "./lib/*_web.ex", "./lib/*_web/**/*.*ex"],
darkMode: "class",
theme: {
},
plugins: [],
};
Pay attention to the relative folder reference. We are not in assets
directory but we are in application root directory, hence the change.
Now, let us import tailwindcss
css files. Open assets/css/app.css
file. You will observe that there is a line @import "./phoenix.css";
which actually imports the milligram
css into the file. Remove that and paste the following:
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
Now, we have tailwindcss
integrated into our application. Let us test it out.
Open the file lib/my_app_web/templates/page/index.html.heex
and go to,
and the first hero section code is available for free. Copy and paste the code into above file. Now, run
mix phx.server
Open the browser and go to localhost:4000
and you will find that tailwindcss is working well. You can make any changes to your code and can observe that even live reload also is working well.
These are the sequence of steps you have to execute to integrate parcel
as the build tool for phoenix framework.
You can find the complete application at,
Hope you find this walk-through useful.