About
The problem we are trying to solve here is the usual.
- Create a stable development environment
- Enable Hot reloading
- Simplify the development process and prepare for production
In this article we will go through how to use:
- vite-plugin-elm-watch
- site-config-loader
- 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'],
},
}));
First let's setup vite to handle building Elm
Here is the steps when starting from scratch
elm inittouch src/Main.elmnpm init-
npm install vite-plugin-elm-watch --save-devOR -D npm install site-config-loadertouch index.html- ! Emmet Abbreviation (To fill index.html)
touch src/main.js- Add to index.html
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
- Add to src/index.js
import Main from './Main.elm';
let app = Main.init({
node: document.getElementById('app')
})
-
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"],
},
}));
npm install vite -Dnpx vite
Utilize site-config-loader
Add configurations
mkdir -p public/config && touch public/config/environmentVariables.json && touch public/config/environmentVariables.local.jsonAdd some variables to the two files. Eg.
{
"API_URL": "https://api.[environment].com",
"ANOTHER_VARIABLE": "[environment]_value"
}
- Run
npx viteornpm run devand 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.
touch vite-plugin-dev-meta.mjs- 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>'
);
}
};
}
- Add usage of the plugin to
vite.config.mjs
import devMetaTagPlugin from './vite-plugin-dev-meta.mjs';
...
plugins: [
elm(),
devMetaTagPlugin(command)
],
- Run
npx viteornpm run devand explore the Console
Adding tailwind
npm install -D @tailwindcss/cli @tailwindcss/vite tailwindcsstouch src/site.css- Add content to site.css
@import "tailwindcss";
body {
@apply bg-pink-50 text-red-900 font-sans;
}
- Add usage of tailwind to
vite.config.mjs
import tailwindcss from '@tailwindcss/vite';
...
plugins: [
elm(),
devMetaTagPlugin(command),
tailwindcss()
],
- Add the css to
main.js
import './site.css';
- 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)