I'm trying to get along with tailwindcss vite plug...
# opensavvy
r
I'm trying to get along with tailwindcss vite plugin and it doesn't want to play nice 🙂 I think it adds
/src/**/*.kt
as files being watched. After every kt file change it reloads the application. And then Vite reloads again when compilation is finished. It is similar to this: https://github.com/tailwindlabs/tailwindcss/issues/16764 . Any idea if we can somehow "de-watch" files in vite?
After thinking about it, I'm afraid it's the only way it can work, because kt files are the only source of input for tailwindcss processing.
c
> After every kt file change… yes, that's the only way it can work. > …it reloads the application. That's weird, Vite should be able to reload CSS files without losing state nor refreshing the page. Maybe it's in the way you import the generated CSS?
r
It reloads because it detect changes in kt file. I don't think it even knows it results in new CSS.
c
🤔
I'm not sure exactly how it's done but React and other frameworks have Vite plugins that reload without losing state, even for code changes, it would be great if we could make it work for KotlinJS
r
I've managed to fix my tailwind problem. This needs to be added to vite.config:
Copy code
server: {
                watch: {
                    ignored: /.*\.kt/
                }
        },
As for HMR (module reload without loosing state) I'm working on it.
Probably this ignore could be added to the configuration by default. I don't think vite should ever reload page just because kotlin sources changed.
👍 1
There is always some processing and mjs files are generated.
c
yep, I agree
I'll need to test if that impacts the source maps Also, since I'll be copying the source files into the working dir, getting Tailwind to work might be easier
r
I've experimented with HMR without loosing state and it works fine with the current vite-kotlin version. For simple HMR (module reload without full application reload) you just need to change
<script>
in the
index.html
file like this:
Copy code
<script type="module">
        import './template.mjs';
        if (import.meta.hot) {
            import.meta.hot.accept('./template.mjs');
        }
    </script>
This alone makes the dev process a lot faster.
To pass application state from one cycle to the next you need some code inside the application.
I already have all the bindings in my framework, which hide all the details behind simple overrides. But if you want to do this manually you just need some Kotlin externals which will do this:
Copy code
if (import.meta.hot != null) {
    if (import.meta.hot.data.appState != null) {
      val restoredState = import.meta.hot.data.appState
      // do something with the state, e.g. populate viewModel
    }
    import.meta.hot.dispose { data ->
        val someState = ... // get application state, e.g. from viewModel
        data.appState = someState
    }
}
The
appState
property can have different name (you can also use multiple properties). With
js
target you can use `Any`/`dynamic` type and store anything you want. In my framework I only use data serialized to String for compatibility with
wasmJs
.
I'll publish an example Kilua app later this weekend (need to release a new version)
Unfortunately, just like with standard webpack, there is no way to use HMR with wasmJs target. Wasm binaries are not JS modules and can't be reloaded 😞
c
That looks very interesting! That may be difficult to apply to a general Compose HTML site since we don't easily have access to the state
r
It works great for apps with some kind of view model or other single source of truth. I'm using this with compose and ballast.
c
Would it be useful if I provided a very small KJS library that exposes these two callbacks, or they're so simple that it's easier to just use them directly?
r
It's not that simple. As far as I know (at least that's what I got from all my attempts in the past) you can't use or provide
import.meta.hot
in a library, because it will be different (specific to the library's module). You have to use it directly in the application module. You can also get the reference in the application and pass it to the library code.
🤔 1
I think it's the same with vite hmr.