DEV Community

Cover image for Using Fission with Elm - Part 1: Using Vite to manage Elm applications
Matt "Verge" Virgin for XetiCode

Posted on • Updated on

Using Fission with Elm - Part 1: Using Vite to manage Elm applications

Prelude

This is a three-part series. In part one (this article), I will show you how to use Vite to manage an Elm application. The second article will show you how to integrate the basics of Fission via the Webnative SDK into the project and the third will walk you through how to refactor the project for Fission authentication and using a Fission Drive.

The Github repository associated with this article can be found here: https://github.com/xeticode/fission-with-elm-demos/tree/Part-1 .


Intro

Hello, hello! In this article, I will walkthrough how to initialize a Vite project and then set up an Elm application within that project. Before I do that, I will quickly introduce you to both Vite and Elm because a lack of character development is almost always an insufficient foundation for any good story. So, without further ado…

Enter Elm…

Elm is not only a typed, pure functional language that transpiles to JavaScript, it is also an architecture for web applications (known as The Elm Architecture or TEA, for short). As a language, Elm offers excellent error messages and is able to avoid runtime errors at compile time because of its strong typing and pure functions. This combination can make refactoring a project a breeze as Elm directs the developer to the exact spot or a specified area where the error is occurring. As an architecture, Elm employs a reactive Model-View-Controller design, or more common within the code: a Model, a view, and an update function. As the user interacts with the UI, messages are sent to the update function which then can alter the data within the Model, which will then update the UI, and the cycle continues on.

To learn more about Elm, check out https://elm-lang.org/ .

Enter Vite…

Vite is a bundling tool that uses browser-native ES modules and tools such as Rollup to build a project. Vite makes it easy to build JS modules along side your Elm code for seamless project deployment. This will not be apparent in this article because we will not be using JS modules. That being said, we will use them in subsequent articles, so setting up Elm with Vite is necessary moving forward. For now, we will have the benefit of using the dev server, build, and build preview functionality offered by this tool.

To learn more about Vite, check out https://vitejs.dev/ .


The Walkthrough

Alright, now that introductions have been made, we can proceed!

Initialize the Vite project

First things first: open an IDE of your choice and open the directory in which you want to store the fission-with-elm application. Once that is done, run the following commands in the terminal from the directory holding the project:

npm init vite
Enter fullscreen mode Exit fullscreen mode

This command will initialize a Vite project.

We will be prompted to enter a name for the Vite project. Normally, this would be your chance to come up with something creative, but since this is a walkthrough, that will have to wait. Name the project fission-with-elm. Anyway, next you will then be prompted to select a web framework. Vite initializes a project differently based on the chosen web framework. As Elm is not one of the core frameworks we will select vanilla for the framework and vanilla as the variant.

Once the Vite project has successfully been initialized, these will be the next commands to run, some of which are displayed at the end of the output from the npm init vite command:

cd fission-with-elm
npm install --save-dev vite-plugin-elm
npm run dev
Enter fullscreen mode Exit fullscreen mode

These commands do the following:

  • cd fission-with-elm : will move the terminal's working directory into the project directory.
  • npm install --save-dev vite-plugin-elm : will install a Vite plugin that bridges the gap between Vite and Elm. Vite supports a handful of web frameworks from the get-go and Elm is not one of them. Thus we install a plugin to make up for that. The --save-dev tag will make this a development dependency, which is a dependency kept for development and building of the project, but is not kept for deployment.
  • npm run dev : will begin the dev server. dev is a script defined in the package.json file.

Before running these commands in the terminal, take a look at the file explorer and browse the files added by npm init vite. You should see:

  • .gitignore
  • favicon.svg
  • index.html
  • main.js
  • package.json
  • style.css

As we change some of the project structure, some of these files will become redundant and can be removed. I will indicate which files those are at the appropriate times. Now run the three commands indicated by the terminal.

After running npm run dev you will see the dev server is running at http://localhost:3000. If you go there you should see this:
Vite Browser

The only thing that remains to finish initializing this Vite project is making it so the project can properly use the Elm plugin. To do this, we will create a file named vite.config.js. This file will be placed within the current directory (which is named after the name you chose for the Vite project). The file needs to contain the following:

import elmPlugin from "vite-plugin-elm"

export default {
  // identify what plugins we want to use
  plugins: [elmPlugin()],
  // configure our build
  build: {
    // file path for the build output directory
    outDir: "build",
    // esbuild target
    target: "es2020"
  }
}
Enter fullscreen mode Exit fullscreen mode

Set up the Elm Application: Installation

elm-tooling

Life and setting up an Elm application have at least one thing in common: there are many ways to do it. As this is a dev article, I will not indicate which way of life you should live, but I will tell you which method to use to set up an Elm application. For this project, we use elm-tooling. It is a command line program for managing Elm tools, namely: elm, elm-format, elm-json, and elm-test-rs (see elm-tooling-cli for more information). First step for setting up an Elm application is to install elm-tooling. Run the following commands in the terminal (double check to make sure you are still in the fission-with-elm directory):

npm install --save-dev elm-tooling
npx elm-tooling init
npx elm-tooling install
Enter fullscreen mode Exit fullscreen mode

These commands do the following:

  • npm install --save-dev elm-tooling : installs the elm-tooling tool to the project.
  • npm elm-tooling init : will initialize elm-tooling within the project. You will notice a new file named elm-tooling.json : appear in the file explorer.
  • npx elm-tooling install : will install the selected tools to ~/.elm/elm-tooling/ and create soft links to these tools in ./node_modules/.bin/ .

You can see what tools elm-tooling has to offer by running the

npx elm-tooling tools
Enter fullscreen mode Exit fullscreen mode

command. This will also let you select the tools you want for the project. Running the command will present you with output like this one:

elm-tooling menu

As you can see, elm, elm-format, and elm-json are selected by default. We will not be using the last tool, elm-test-rs, which is a tool used for testing the application, as writing tests is beyound the scope of these articles.

elm-json

Next, run:

npx elm-json new
Enter fullscreen mode Exit fullscreen mode

This will create a file named elm.json. This file holds information concerning the Elm application such as: dependencies, location of source directories, and which version of Elm is being used for the project. There will be a question about what type of Elm project you want, select “application”.

At this point we have four JSON files: elm.json, elm-tooling.json, package-lock.json, package.json. Here is what is significant about each file:

  • elm.json : this contains Elm specific information such as Elm module dependencies, the version of Elm being used, and the file path(s) to any source directories within the project.
  • elm-tooling.json : this contains a limited selection of Elm tools
  • package-lock.json : the npm package version lock.
  • package.json : this contains information of the project such as the name of the project, command line scripts (i.e., the dev command previously executed in this walkthrough).

Set up the Elm Application: Modifying to the file structure

Ok, now that installation has been complete, let’s add some structure to the project! We will be adding a few directories and files with those directories. As a reminder, everything that will be added will be with the fission-with-elm directory (now referred to as root directory for the remainder of this article).

  1. Add a directory named src. This will be for your Elm source files. Within that directory, add a file named Main.elm. Leave the file empty for now.

  2. Add another directory in the root directory called js. In this new directory, create a file called index.js. Leave the file empty for now.

  3. Create another directory in the root directory called public

    1. Within public, create a directory called assets
    2. Within assets, create a directory called images
    3. The end product here should look like: ./public/assets/images/. For this project, we will be using the Fission logo. You can download this image from the repo associated with this article. To do so, Run the following command in the terminal from the images directory:
      curl -o fission.svg https://raw.githubusercontent.com/xeticode/fission-with-elm-demos/Part-1/public/assets/images/fission.svg
    

Set up the Elm Application: Adding content to the files

We are near the end! We have a few files to change: ./js/index.js, ./src/Main.elm, and ./index.html. First, we will take a look at ./index.html.

index.html

We need to connect the index.js file to the index.html file via a script tag that will be placed within the head tag.

This is the new content of the index.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
    <!-- Here is the new script tag -->
    <script type="module" src="./js/index.js"></script>
  </head>
  <body>
    <!-- This is the old content -->
    <!-- <div id="app"></div> -->
    <!-- <script type="module" src="/main.js"></script> -->
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

These changes make the main.js and styles.css files redundant as we no longer reference them. Both files are used to present the Hello Vite! webpage from the beginning of the walkthrough. Delete these files now.

index.js

Here is all that is needed in the ./js/index.js file:

import { Elm } from "/src/Main.elm"

const app = Elm.Main.init({});
Enter fullscreen mode Exit fullscreen mode

This is the connection point between index.html and our Elm application. Line 1 indicates where to find the application, and line 3 initializes the application.

Main.elm

This article does not focus on the components of Main.elm. Because of this, and the length of the file, we will download the file directly from the Github repository. We will dive into the file in Part 2, but for now, use this command to download the Main.elm file from the repository asociated with this article. We will dive into this file in part 2:

curl -o Main.elm https://raw.githubusercontent.com/xeticode/fission-with-elm-demos/Part-1/src/Main.elm
Enter fullscreen mode Exit fullscreen mode

Set up the Elm Application: Importing Elm modules

Alrighty! Go ahead and run

npm run dev
Enter fullscreen mode Exit fullscreen mode

The compilation should fail. Reason being? There are dependencies we refer to from within Main.elm that have not been installed. Run the following command in the root directory to install the missing dependencies:

npx elm-json install elm/browser elm/url mdgriffith/elm-ui
Enter fullscreen mode Exit fullscreen mode

Here is some information on the packages being installed (for more info on each package, see https://package.elm-lang.org/ and enter the package name in the search bar):

  • elm/browser enables the Elm application to run in the browser.
  • elm/url handles creation and parsing of Urls (required when using Browser.application).
  • mdgriffith/elm-ui handles layout and styling (there are a few options for for layout and styling, and I chose elm-ui for its simplicity, capability, and ease of use).

After running the command, a confirmation prompt will appear regarding the addition of these modules to the elm.json file. There will be some dependencies to be installed to the indirect dependcies because the direct dependencies depend on them. The word "dependency" was used too much in that last sentence... I recommend having the elm.json file open so the changes can be visibly seen.

You can also run the npx elm-json install command once per dependency if desired. Once those dependencies have been installed, the error messages should disappear and you should see this:

Final View


The Ending

Before its over: Witness the live reload of Vite

For this part, make sure you have the dev server running and a browser open to the localhost domain. Vite has live reload functionality. In other words, if you change something in the Main.elm file, it will take note of the changes made and automatically serve the new files. To demonstrate this, go to line 68 in Main.elm. You should see this:

, EBA.color <| E.rgb255 176 192 222
Enter fullscreen mode Exit fullscreen mode

This line dictates the background color of the application. Change any number of the intgers following E.rgb255 to a value between 0 and 255 inclusive and see the background automatically change!

Before its over: Build and Serve the project

Before we can officially wrap this up, I will show you how to build the project and serve the build directory. Run these commands:

npm run build
npm run serve
Enter fullscreen mode Exit fullscreen mode

Both build and serve are scripts defined in package.json. These commands do the following:

  • npm run build will use Vite to build the project. As it builds, a new directory named build will appear in the file structure. The first children of this directory will be the static files from the location indicated by the publicDir tag from the vite.config.js file. The other children will take a moment to appear and will be the files generated from the build process.
  • npm run serve will start a localhost server and serve the files from the build directory. This will be running at http://localhost:5000 .

The result should be the same as what is produced by the npm run dev command.

Adieu

And there you have it! A simple Elm project that is managed by Vite. As a reminder, this only covers the basics of setting up Vite and Elm, if you wish to learn more about what they both have to offer, follow these links:

In the next article, we will alter this project to integrate Webnative, an SDK built and provided by Fission.

Top comments (2)

Collapse
 
verge_729 profile image
Matt "Verge" Virgin

@johncrosby Thank you for noting that. I wonder how accurate the content of this series is now after two years have passed since its publication...

I have not kept up with some of these topics as I have been working on projects with different tech stacks shortly after the series was published 😅

Collapse
 
johncrosby profile image
John Crosby

I needed to use plugins: [elmPlugin.plugin()], rather than plugins: [elmPlugin()], in my vite.config.js file.