We have been using Kotlin for web-development for 2,5 years.
We use Gradle for handling Kotlin build and dependencies. The generated Java-Script is then handled by Webpack, and dependencies in the java-script world is handled by NPM. (We have tasks that chain all this perfectly.)
This works nicely because our NPM and Webpack usage is very complicated, and we don’t want to inhibit it in any way by using a plugin/wrapper of any sort. (Even if in theory there were no downside we would not be migrating any time soon.)
With Kotlin 1.4 it seems JetBrains assume that everybody wants to use NPM and Webpack and that they want to use it through their plugin/wrapper. (I hope I’m wrong.)
When i run the Gradle task ‘mainClasses’ then the unnecessary ‘kotlinNpmInstall’ is part of the chain spewing out NPM-package warnings that confuse people (we have a big build chain that includes ‘mainClasses’ before Webpack is run which gives us our real NPM-package warnings).
For production we use ‘processDceKotlinJs’ instead of ‘mainClasses’ which the documentation didn’t mention. - https://kotlinlang.org/docs/reference/javascript-dce.html only contains examples that assumes we want to use the plugin’s dev-server and Webpack.
Is it possible with the Kotlin Gradle-plugin for Kotlin 1.4 to do a proper build for development and production without any NPM and Webpack being involved?
If not then I feel this is something that should be changed.
The Kotlin/JS plugin went through so many changes. Probably what you have done by hand with the previous model is now integrated/automated by the plugin itself. Sure you do not need to uplift some build logic to the plugin instead of your own?
NPM and JS tools suck badly compared to Gradle (we are very spoiled ), problem is, everybody else really want to use NPM&friends like crazy, like it’s godsend! So yes, if you want to make Kotlin/JS really competitive JB has to make the plugin interact heavily with the already existent ecosystem of libraries and their horrible UX (the JS ones, not the JB plugin, which is great)!
It’s smart of JetBrains to include integration with NPM and Webpack. However, assuming everyone wants to use their integrations is a mistake. - Worsened by the fact that for years people had to make due and hence need that the plugin doesn’t force it now.
Also, there are other packaging solutions than Webpack that people might want to use.
We have a complex common-webpack.js that employs a bunch of webpack-plugins. This file is used by multiple webpack.config.js files (one for each web-project).
We have a bunch of Gradle tasks that makes sure everything is chained together properly; whether for development, production or other needs.
I have my doubt that all this can be migrated without issue and it will definitely be a huge undertaking. Any potential migration wont be done before people have used the integrations for a long time, and we feel confident they satisfy our needs. Even then it would have to be prioritized - We would of course give it a try if we started today, but we started 2,5 years ago. I remember trying it back then, but quickly had to abandon it, because it was severely lacking. I have no doubt it is much better now, but it has to have zero obstructions, and to reiterate even then we wouldn’t migrate right now.
All we are asking is that JetBrains don’t assume people want to use their NPM and Webpack integrations.
That means having development and production (DCE) build tasks that don’t include their integrations.
One should not exclude the other. I.e. having integrations should not exclude the possibility to forgo them.
I’m looking into your suggestion. That is properly what we will end up doing, but I don’t like it. There are more than one integration task, and the number could keep growing.
Also, the build tasks we need are basic, and we hope JetBrains simply forgot them for the initial Kotlin 1.4 release.
EDIT: We have many sub-projects so in order not to write this everywhere I need to make a shared (albeit simple) gradle script.
Gotcha. Hopefully it works out that you can skip those tasks and that downstream tasks don’t depend on their outputs-- I guess that depends on how much the plugin changed.
I’d be remiss if I didn’t mention how great putting your common build logic in buildSrc is. Often those turn into Gradle plugins themselves.
Another option is to add this skip logic to your allprojects { /* disable those tasks */ } in the root project.
and I also wonder why it is triggered. I’m writing a multiplaform 1.4.10 library, which targets browser js and jvm, so any server-side js shouldn’t be needed.