Hey! I am working on a Gradle plugin for bundling ...
# javascript
c
Hey! I am working on a Gradle plugin for bundling with ViteJS/Rollup (instead of Webpack). I am searching for open source projects that may be interested in trying it out early / helping me benchmark this. Please comment under this message or DM me if you are interested πŸ™
a
I am interested
t
Is it open source project? Where I can subscribe? πŸ™‚
c
It's not stable yet, but I'm using it in my own (small) projects already and it works fine. I want to try it on larger projects to measure if it's faster, and to check if there are edge cases that are broken
r
I'm interested
t
@CLOVIS Do you use
commonjs
libraries?
r
Does it support
wasmJs
as well?
c
(I think the latest or previous version is broken though, if Gradle complains about a plugin descriptor, roll back to the previous version πŸ€¦β€β™‚οΈ )
t
FYI - NPM dependencies you can request with
RequiresNpmDependencies
(like here)
c
I do not use
commonjs
libraries myself. I haven't done anything for
wasmJs
but I believe it should just be setting the correct path for it? I'd need a project that uses it to test.
Oh, RequiresNpmDependency sounds like it could simplify some things, I'll look into it thanks
t
MUI showcase can be used as playground
c
It's a sample project, no? I'd also like to have a real large project to measure compilation times and output size.
r
What should I expect after running
viteBuild
? There were no errors but the
vite/dist
directory contains just
index.html
file and not a single
js
file.
c
There should be a
.js
file πŸ˜… have you made the
type="module"
change?
If so, please create an issue, preferably with a reproducer, I'll look into it (though it'll probably take a few days, I'm really busy at the moment)
r
No. The message
1 modules transformed
suggested the plugin did this for me πŸ™‚
c
That's strange… if you don't have the
type=module
, it usually complains about not finding the source code. See https://opensavvy.gitlab.io/automation/kotlin-vite/api-docs/vite-kotlin/index.html
r
I've made the change and now there are errors ...
c
what kind?
r
The webpackTask configuration (bundle name) is not used. Changed the name to the default in the index.html.
It has built something ...
My resources are not processed. How can I support images or other files?
Currently I have some files in
webpack.config.d
to configure different loaders
c
What kind of files are they?
r
jpg
c
Where are your images stored?
This is the resources folder
c
Wait, where is the .html entrypoint?
r
This is the log from the build:
Copy code
vite v5.0.11 building for production...
transforming...
"img/dog.jpg" is imported by "img/dog.jpg?commonjs-external", but could not be resolved – treating it as an external dependency.
"hbs/template1.en.hbs" is imported by "hbs/template1.en.hbs?commonjs-external", but could not be resolved – treating it as an external dependency.
"hbs/template1.pl.hbs" is imported by "hbs/template1.pl.hbs?commonjs-external", but could not be resolved – treating it as an external dependency.
"img/cat.jpg" is imported by "img/cat.jpg?commonjs-external", but could not be resolved – treating it as an external dependency.
"hbs/rest.en.hbs" is imported by "hbs/rest.en.hbs?commonjs-external", but could not be resolved – treating it as an external dependency.
"hbs/rest.pl.hbs" is imported by "hbs/rest.pl.hbs?commonjs-external", but could not be resolved – treating it as an external dependency.
"i18n/messages-pl.json" is imported by "i18n/messages-pl.json?commonjs-external", but could not be resolved – treating it as an external dependency.
"i18n/messages-en.json" is imported by "i18n/messages-en.json?commonjs-external", but could not be resolved – treating it as an external dependency.
c
Ah, it's a working directory issue πŸ˜• Please create a ticket for it, it's going to take some time to track down
r
I'm setting this
config.resolve.modules.push("../../processedResources/js/main");
in my custom webpack config.
c
Vite is completely separate from Webpack, it doesn't read that config
r
I know. But maybe we need to set some similar option for vite?
Or maybe I need to use different (standard) require in my app ...
c
No, the problem here is that I run vite in a subdirectory of the resource folder because of some gradle weirdness, and thus the relative paths are broken, and thus Vite cannot find the resources
I'm sure this is it because the error message clearly mentions that Vite knows you're looking for the file but it couldn't find it πŸ˜•
r
require("./file.jpg")
instead of
require("file.jpg")
c
you can try for now if you want, but my goal is that no code changes are necessary at all
it's probably going to be ../ though, since it's running in a subdirectory
if you run with
--info
, you can see the exact command it runs and the working directory
r
After changing to standard require paths vite seems to resolve my resources correctly.
But it doesn't understand
hbs
files. Webpack uses my custom configuration for
handlebars-loader
. Can I do it somehow for vite as well?
c
What are
hbs
files?
r
c
Looks like there's a plugin for it: https://www.npmjs.com/package/vite-plugin-handlebars
r
Can I use it with your plugin?
r
Let's test the theory πŸ™‚
c
I tested with 2 or 3 plugins and they seem to work, but I don't really know how similar they all are πŸ˜…
r
Unfortunately it doesn't work
😒 1
Copy code
✘ [ERROR] "vite-plugin-handlebars" resolved to an ESM file. ESM file cannot be loaded by `require`. See <https://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only> for more details. [plugin externalize-deps]
😐 1
c
Well, I won't lack stuff to do in the next weeks πŸ˜‡
r
I've removed handlebars part. It works now.
c
Please create issues for all of this πŸ™‚ If you don't want to create a GitLab account, you can create issues by sending an email to contact-project+opensavvy-automation-kotlin-vite-50847490-issue-@incoming.gitlab.com (but that will make your email address public)
r
The applications works, though my jpg is not visible. It's probably imported as some js object and I need to access some property for the url.
c
You may find some info here: https://vitejs.dev/guide/assets
r
after cleaning the project the full production build: webpack: 45s, vite: 25s
πŸ‘€ 1
c
that seems promising
though I'm not sure how trustworthy this is, if you don't have the same result
r
Both runs are with commented out hbs.
So they should be ok to compare.
πŸ™Œ 1
webpack bundle size: 3225600 (css is inside js)
c
In my experience in the projects I've worked on: β€’ development auto-reload is at least an order of magnitude faster with Vite β€’ production compilation is about twice as fast with Vite β€’ bundle size is about ~30% less with Rollup
r
vite bundle size: 2813002 js + 526352 css = 3339354
c
πŸ€”
does that include the images?
r
I'll play a bit more later but it's definitely promising!
No, the images are not bundled.
No idea why it's larger for my project ...
c
When testing on another example we found that by default Rollup keeps comments in the final bundle, but I don't think it should be that much
r
the file contains quite a lot of comments and also some uncompressed html
πŸ‘€ 1
the webpack bundle is definitely better minimized
still gzipping both vite files is 848798 and gzipping webpack file 796307, so the difference is quite large
it's not a major issue, you can always bundle production file the old way ... I'll try to compare dev server performance now ...
a
I am interested to try this with my website done with Kobweb, it would be interesting to see if it works with hot-reloading ! https://github.com/Ayfri/Ayfri.github.io
r
@CLOVIS Unfortunately
viteRun
task doesn't work correctly. It runs without errors but my app doesn't start. I only have an error in the browser console
Uncaught SyntaxError: import not found: default
in the file generated from one of my submodules.
But there is nothing I can do about this in my code.
Unfortunately no solution there.
c
@Ayfri for Kobweb, I have this prototype already: https://github.com/bitspittle/bitspittle.dev/pull/6/files please try the same changes in your project and tell me how it goes πŸ‘€ (it's a bit of an older version of the plugin but it should be similar)
a
Thanks, I'll try when I have the time to ! Maybe this evening
❀️ 1
c
There's a strange workaround for file locations, the goal for the future (when the plugin gets stabilized) is that that code will become part of Kobweb so it works out of the box
a
@David Herman You might be interested by this thread !
thank you color 1
c
he knows already, I have been discussing this with him for months now πŸ˜‡
😎 1
a
Oh, this is neat K
c
(I also have a Discord instance to discuss all of this, if some of you are interested: https://discord.gg/kVfxMZkF)
@Robert Jaros can you create issues on gitlab for the problems you have faced? I will investigate in more depth in the coming weeks
r
I'm playing a bit with my app and I have some more similar issues. I think this is not really a plugin issue. It's more of a webpack vs. vite. There must be some differences in module handling. In general when I use
require("some_module")
in K/JS I get an JS object. But the objects are sometimes different with webpack and different with vite. Unless there is some "webpack compatibility mode" in vite, it will probably never work without fixing the application (or library, which is even bigger problem).
If I had used
@JsModule
instead of
require
it would probably have worked. However, for KVision, a lot of code would need to be rewritten.
What's strange, it's only affects dev mode. The production build is running fine.
c
Well, the dev and prod engines are completely different internally, that's why it can be fast in dev and efficient in prod.
t
Probably
commonjs
plugin fix
require
in production.
require
- Webpack or Node.js function. It's expected, that it won't work in other bundlers, which are ESM oriented from start
Same situation with
process.env...
r
@CLOVIS I'll definitely follow your project. But for now, for small projects it runs fine but the performance gain is not noticeable (the change->reload cycle takes about 4 seconds with webpack and 4 seconds with vite as well). For large projects it doesn't work for me because of dependencies problems. I have filled two issues.
c
Thanks, that's the feedback I was searching for :)
r
I like the idea of configuration by simple strings embedded into
build.gradle.kts
. I wish Kotlin team did the same for webpack configuration instead of
webpack.config.d
πŸ™‚
βž• 1
I couldn't resist and made some more tests πŸ˜‰ I've checked
useEsModules()
option and the dependencies problems are gone. I've successfully run dev server for an application with a dozen of different npm dependencies (with production bundle size ~ 3MB).
But ... the dev cycle takes longer than webpack's! 😞
With webpack it still about 4 seconds but vite plugin takes 5-6 seconds.
πŸ‘€ 1
c
Ohh, that's interesting! File-by-file ES6 modules is the end goal for dev performance in theory, but I want to focus on making the plugin reliable first
r
I test webpack without
useEsModules()
and vite with this option. Unfortunately my app doesn't work with both webpack and useEsmodules().
Maybe that's the cause.
c
Vite originally was created because browsers started to support ES6 modules natively, so all that was left for the bundler was to configure the browser and communicate reload times with it. In the preferred mode, Vite essentially no-ops, that's why it's so fast. Currently, the plugin uses module-wide compilation, so you have to wait for the Kotlin compiler to finish. In the future, I want to enable file-by-file compilation but I haven't tested yet.
a
From what I've seen they optimized more
useEsModules()
in 2.0, maybe you should try in the soon-to-release RC1 ?
r
Yep, I will.
c
I have high hopes for it :)
r
And one more info. In a dual K/JS + K/Wasm project your plugin works with JS target only. No tasks for wasm target are registered.
c
But from what I've heard their implementation doesn't have namespaces through packages so you get naming conflicts?
a
From the pull request, it should release today
c
@Robert Jaros for WasmJS, what do I need to add? Is it just a second working directory?
r
I think tasks should be registered. Just like for we have
jsRun
and
wasmJsRun
,
jsProductionWebpack
and
wasmJsProductionWebpack
.
I would expect
jsViteRun
and
wasmJsViteRun
when both targets are used.
πŸ‘ 1
c
If you have a sample project with WasmJS, please mention it in one of the issues so I can try it :) but currently it requires unstable Node versions and that's very inconvenient for me. Apparently the first stable Node version with WASM in next week though πŸ‘€
I already created an issue for WASMJS
r
As for the performance of the plugin - I think the problem could be the design with two different gradle tasks.
When I make a change in my sources the
viteCompileDev
task is restarted, but it takes "ages" to actually compile something. Every single time it configures all modules of my project (and it's quite large). The log looks like this:
Copy code
new file: /home/rjaros/git/kilua/examples/playground/src/commonMain/kotlin/main.kt~
modified: /home/rjaros/git/kilua/examples/playground/src/commonMain/kotlin/main.kt
Change detected, executing build...


> Configure project :kilua
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:bootstrap-form
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:fullstack-ktor-koin
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:hello-world
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:js-framework-benchmark
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:playground
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:resources
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:ssr-javalin
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:ssr-jooby
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:ssr-ktor
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:ssr-micronaut
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:ssr-spring-boot
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:ssr-vertx
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :examples:todomvc
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-bootstrap
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-bootstrap-icons
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-common-types
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-core-css
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-dom
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-fontawesome
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-i18n
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-imask
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-lazy-layouts
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-rest
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-routing
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-rsup-progress
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-select-remote
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-splitjs
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-ssr
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-tabulator
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-tabulator-remote
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-tempus-dominus
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-testutils
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-toastify
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-tom-select
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-tom-select-remote
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :modules:kilua-trix
New 'wasm' target is Work-in-Progress and is subject to change without notice.

> Configure project :plugins:kilua-gradle-plugin
WARNING: Unsupported Kotlin plugin version.
The `embedded-kotlin` and `kotlin-dsl` plugins rely on features of Kotlin `1.9.22` that might work differently than in the requested version `1.9.23`.

> Task :examples:playground:compileKotlinJs
It's wasting lots of time here.
c
Please enable configuration-on-demand and the configuration-cache, they will help a lot.
This is just the behavior of
--continuous
, I can't do anything about it
r
webpack doesn't do it with the same option
c
yes, the Kotlin plugin does a LOT of very weird stuff to intercept --continuous and do their own stuff on top of it πŸ˜•
r
sorry, it does ;>
But still, when
viteCompileDev
is finished, the reload is not triggered immediately. The main
viteRun
task need to notice the change.
c
Ah, maybe Vite does debouncing πŸ€”
r
No ... I've looked at the tasks more closely and it's not that ...
viteRun reloads at once
but the viteCompile task works differently - sometimes it executes in 2 seconds and sometimes 6 seconds
with the same code change
c
Do you have the build cache enabled?
r
I have
Copy code
org.gradle.parallel=true
org.gradle.caching=true
c
The build cache will do that, if you make the same changes multiple times, it pulls from the cache
r
I've disabled cache. Now the vite plugin reloads in 8 seconds every time. And the webpack plugin reloads in ... 8 seconds every time πŸ˜‰
c
Tbf, I'm convinced this is dominated by the Kotlin compiler
r
Just wanted to say this. It's 8 seconds of
compileKotlinJs
task.
c
In my projects I have seen webpack reload once, then 5 seconds later reload again, it's really inconvenient. It never happens with Vite though
r
Its a Kotlin plugin bug with source maps. I've opened an issue years ago.
I have source maps disabled because of this.