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 thepackage.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:
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"
}
}
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
These commands do the following:
-
npm install --save-dev elm-tooling
: installs theelm-tooling
tool to the project. -
npm elm-tooling init
: will initializeelm-tooling
within the project. You will notice a new file namedelm-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:
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).
Add a directory named
src
. This will be for your Elm source files. Within that directory, add a file namedMain.elm
. Leave the file empty for now.Add another directory in the root directory called
js
. In this new directory, create a file calledindex.js
. Leave the file empty for now.-
Create another directory in the root directory called
public
- Within
public
, create a directory calledassets
- Within
assets
, create a directory calledimages
- 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 theimages
directory:
curl -o fission.svg https://raw.githubusercontent.com/xeticode/fission-with-elm-demos/Part-1/public/assets/images/fission.svg
- Within
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>
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({});
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:
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
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 namedbuild
will appear in the file structure. The first children of this directory will be the static files from the location indicated by thepublicDir
tag from thevite.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 alocalhost
server and serve the files from thebuild
directory. This will be running athttp://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)
@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 😅
I needed to use
plugins: [elmPlugin.plugin()],
rather thanplugins: [elmPlugin()],
in my vite.config.js file.