DEV Community

Theodor Heiselberg
Theodor Heiselberg

Posted on • Edited on

(3)Creating the Pinnacle of Niche Software: Using vite-plugin-elm-watch

About

The problem we are trying to solve here is the usual.

  1. Create a stable development environment
  2. Enable Hot reloading
  3. Simplify the development process and prepare for production

In this article we will go through how to use:

  1. vite-plugin-elm-watch
  2. site-config-loader
  3. Add tailwind css to the project

Key takaways
A working example of this setup running in a devcontaner can be found here - Link! in the branch feature/add-tailwind

host: '0.0.0.0' or host: true is needed in order to run vite from a devcontainer - Documentation - Link!

import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
import elm from 'vite-plugin-elm-watch';
import devMetaTagPlugin from './vite-plugin-dev-meta.mjs';

export default defineConfig(({ command }) => ({
  publicDir: 'public',

  build: {
    outDir: 'wwwroot',
    emptyOutDir: true,
  },

  plugins: [elm(), tailwindcss(), devMetaTagPlugin(command)],

  server: {
    open: true,
    port: 3456,
    host: '0.0.0.0', // Listen on all network interfaces to allow access from the host machine
    allowedHosts: ['host.docker.internal', 'localhost'],
  },
}));

Enter fullscreen mode Exit fullscreen mode

First let's setup vite to handle building Elm

Here is the steps when starting from scratch

  1. elm init
  2. touch src/Main.elm
  3. npm init
  4. npm install vite-plugin-elm-watch --save-dev OR -D
  5. npm install site-config-loader
  6. touch index.html
  7. ! Emmet Abbreviation (To fill index.html)
  8. touch src/main.js
  9. Add to index.html
<body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
</body>
Enter fullscreen mode Exit fullscreen mode
  1. Add to src/index.js
import Main from './Main.elm';
let app = Main.init({
  node: document.getElementById('app')
})
Enter fullscreen mode Exit fullscreen mode
  1. touch vite.config.mjs
import { defineConfig } from "vite";
import elm from 'vite-plugin-elm-watch';

export default defineConfig(({ command }) => ({
  publicDir: "public",

  build: {
    outDir: "wwwroot",
    emptyOutDir: true,
  },

  plugins: [elm()],

  server: {
    open: true,
    port: 3456,
    host: "0.0.0.0", // Listen on all network interfaces to allow access from the host machine
    allowedHosts: ["host.docker.internal", "localhost"],
  },
}));
Enter fullscreen mode Exit fullscreen mode
  1. npm install vite -D
  2. npx vite

Utilize site-config-loader

Add configurations

  1. mkdir -p public/config && touch public/config/environmentVariables.json && touch public/config/environmentVariables.local.json

  2. Add some variables to the two files. Eg.

{
    "API_URL": "https://api.[environment].com",
    "ANOTHER_VARIABLE": "[environment]_value"
}
Enter fullscreen mode Exit fullscreen mode
  1. Run npx vite or npm run dev and explore the Console

Add html rewrite using vite transformIndexHtml

Since we havn't added any meta data to set the environment site-config-loader will default to local based on the url, which is set to localhost.

  1. touch vite-plugin-dev-meta.mjs
  2. Add content
export default function devMetaTagPlugin(command) {
  if (command !== 'serve') return null;

  return {
    name: 'html-transform-dev-only',
    transformIndexHtml(html) {
      return html.replace(
        '</head>',
        '<meta name="environment-name" content="production"></head>'
      );
    }
  };
}
Enter fullscreen mode Exit fullscreen mode
  1. Add usage of the plugin to vite.config.mjs
  import devMetaTagPlugin from './vite-plugin-dev-meta.mjs';
  ...
  plugins: [
    elm(),
    devMetaTagPlugin(command)
  ],
Enter fullscreen mode Exit fullscreen mode
  1. Run npx vite or npm run dev and explore the Console

Adding tailwind

  1. npm install -D @tailwindcss/cli @tailwindcss/vite tailwindcss
  2. touch src/site.css
  3. Add content to site.css
@import "tailwindcss";

body {
  @apply bg-pink-50 text-red-900 font-sans;
}
Enter fullscreen mode Exit fullscreen mode
  1. Add usage of tailwind to vite.config.mjs
import tailwindcss from '@tailwindcss/vite';
...
  plugins: [
    elm(),
    devMetaTagPlugin(command),
    tailwindcss()
  ],
Enter fullscreen mode Exit fullscreen mode
  1. Add the css to main.js
import './site.css';
Enter fullscreen mode Exit fullscreen mode
  1. Restart the vite server

Conclusion

There are quit a few moving parts need to get this up and going.

A Complete example can be found here: Link! in the branch feature/add-tailwind

Next up we will abandon using localhost entirely and use a custom domain name for development. This will also require adding quite a few moving parts, like a reverse proxy to our .devcontainer/docker-compose.yml.

I wrote about it previously here: Link!

Top comments (0)