Skip to content

An example Phoenix Project that uses Gleam for Phoenix Hooks

License

Notifications You must be signed in to change notification settings

ElixirCL/gleamphx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Using Gleam in your Phoenix Hooks

Phoenix uses Elixir, but when dealing with LiveView Hooks it requires JavaScript. But how about using another functional language in that area?.

Presenting Gleam

The power of a type system, the expressiveness of functional programming, with a familiar and modern syntax.

Gleam comes with compiler, build tool, formatter, editor integrations, and package manager all built in, so creating a Gleam project is just running gleam new.

In my humble opinion, Gleam is the perfect alternative to Typescript! if you want all the goodies of a functional language and a type system for your Phoenix Hooks.

Installation

Be sure the gleam binary is in your $PATH. You can refer to the Installation Guide for more details.

$ gleam --version
gleam 0.26.1

GleamPhx Project

This will be an small and simple project (Phoenix 1.6) with no ecto. Just a LiveView with a simple hook for demostration.

Creating our Project

First let's start with a project named gleamphx with no database requirement (just to be slim).

$ mix phx.new . --app gleamphx --no-ecto

Creating our Gleam Project

Let's go to assets/ directory and create a new Gleam Project named hooks.

$ cd assets
$ gleam new hooks
$ cd hooks

Now we edit gleam.toml so we can setup the Javascript target.

name = "hooks"
version = "0.1.0"
description = "A Gleam project"
# ...
target = "javascript"

[javascript]
# Generate TypeScript .d.ts files
typescript_declarations = true

# Which JavaScript runtime to use with `gleam run`, `gleam test` etc.
runtime = "node" # or "deno"

JavaScript Code

This will be the main Javascript file that will export all of our hooks. This file will be used in app.js later.

$ touch assets/hooks/index.js
import * as Hello from "./build/dev/javascript/hooks/hello.mjs";

export default { Hello };

Gleam Code

Inside the src/ directory we will create our hooks. Lets create hello.gleam hook.

import gleam/io

pub fn mounted() {
  io.println("Hello from Gleam!")
}

Phoenix Config

Ok we are ready with our hook. Lets configure Phoenix!.

assets/app.js

First lets edit assets/app.js to import our hooks.

// ...
import Hooks from "../hooks"
// ...

let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}})

mix.exs

Let's add a new build step in assets.deploy task.

"gleam.build": [
        "cmd cd assets/hooks && rm -rf build && gleam build"
      ]

This task only builds the gleam code to the target javascript files.

defp aliases do
    [
      "gleam.build": [
        "cmd cd assets/hooks && rm -rf build && gleam build"
      ],
      setup: ["deps.get"],
      "assets.deploy": [
        "gleam.build",
        "esbuild default --minify",
        "phx.digest"]
    ]
  end

We add the task to the assets.deploy pipeline.

lib/gleamphx_web/router.ex

Ok now we just have to test. Let's create a simple live view with a div that is Hooked to the Hello function in Gleam.

First we configure our router

scope "/", GleamphxWeb do
    pipe_through :browser

    live "/", Live.Example, :index
  end

lib/gleamphx_web/live/example.ex

And then create our module

defmodule GleamphxWeb.Live.Example do
  use GleamphxWeb, :live_view

  @impl true
  def render(assigns) do
    ~H"""
      <div id="ExampleGleamHook" phx-hook="Hello">Example Hooked Component</div>
    """
  end
end

If everything went OK then after mix phx.server you will see in the browser console a message similar to this.

GleamPHX

Routes

  • "/": Example Gleam code using console.log
  • "/video": Example Gleam code interacting with the MediaStream api and this.el;

Next Steps?

TODO: Maybe configure autoreload on change of gleam files.

You can check out the example project here https://github.com/ElixirCL/gleamphx