vite-plugin-elm
A plugin that enables us to compile an Elm application, document, or element within your Vite project. In development, hot module replacement works to some extent.
import { Elm } from './MyApplication.elm'
Elm.MyApplication.init()
Setup
npm i -D vite-plugin-elm
In vite.config.(js|ts)
:
import { defineConfig } from 'vite'
import elmPlugin from 'vite-plugin-elm'
export default defineConfig({
plugins: [elmPlugin()]
})
Then you can import a .elm
file and run it like:
import { Elm } from './Hello.elm'
// Mount "Hello" Browser.{element,document} on #root
Elm.Hello.init({
node: document.getElementById('root'),
flags: "Initial Message"
})
You can explore the /example
directory to experiment with an actual Vite project. Additionally, this functional website can serve as a helpful resource to learn how to use it effectively.
Options
debug
(Default: process.env.NODE_ENV !== 'production'
)
You can control the debug mode of Elm, which toggles the Elm Debugger, by providing a boolean value.
elmPlugin({ debug: false })
When set to false
, it disables debug mode in both development and production. Conversely, setting it to true
enables debug mode even in production. It’s important to note that when the production build has debug mode enabled, Elm’s compiler optimizations do not take place.
Helper package
We can simplify the tagging process by using the Elm package elm-vite-plugin-helper
:
elm install hmsk/elm-vite-plugin-helper
import VitePluginHelper
Html.img [ Html.Attributes.src <| VitePluginHelper.asset "/assets/logo.png?inline" ] []
Combine multiple main files (Experimental)
By passing importing paths via the with
URL-ish parameter(s), the plugin compiles multiple main files in a single compilation process. This results in a single Elm export that contains multiple properties, each corresponding to a given main file. This feature helps reduce the bundle size when compared to importing each file separately because common modules and Elm core code are not repeated.
// `Elm.App` and `Elm.Another`, both can work as like importing individually.
import { Elm } from './App.elm?with=./Another.elm'
Elm.App.init({
node: document.getElementById('rootForApp'),
})
Elm.Another.init({
node: document.getElementById('rootForAnother'),
})
For 3+ main files:
import { Elm } from './App.elm?with=./Another.elm&with=./YetAnother.elm'
Acknowledgement
- klazuka/elm-hot for a helpful referrence of the HMR implementation
- ChristophP/elm-esm for publishing IIFE -> ESM logic