Using Fission with Elm - Part 1: Using Vite to manage Elm applications
Tags: elm, fission, vite
Published: 2021-10-12 22:34:16

## **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
```
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
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q27yafazd7am7bomhqm1.PNG)

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:
```javascript
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"
  }
}
``` 

---
### **_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](https://elm-tooling.github.io/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
```
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
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/agttu2olm94z777kbzrm.PNG)

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
```
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:
```html
<!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>

```
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:
```javascript
import { Elm } from "/src/Main.elm"

const app = Elm.Main.init({});
```
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
```

### **_Set up the Elm Application: Importing Elm modules_**

Alrighty! Go ahead and run
```
npm run dev
```
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
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwfgad67r37uvx3b4xvm.PNG)

---
## **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:
```elm
, EBA.color <| E.rgb255 176 192 222
```
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
```
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:
- Elm
    - https://package.elm-lang.org/
    - https://elm-lang.org/
- Vite
    - https://vitejs.dev/

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