Reputation: 53
I am unable to add the tailwindcss library to my KotlinJS project. I tried multiple things.
I have multiple dependencies defined in my build.gradle.kts
implementation(npm("postcss", "latest"))
implementation(npm("postcss-loader", "latest"))
implementation(npm("tailwindcss", "1.8.10"))
I tried creating a tailwindcss.js in my webpack.config.d with this content
config.module.rules.push({
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'tailwindcss'
],
],
},
},
}
]
}
);
But that doesn't do anything. I also tried modifying this with multiple options, but I was never able to get tailwindcss to compile. I also tried disabling and enabling the KotlinJS CSS support in build.gradle.kts
I can't find any info on how to add postcss to KotlinJS project.
Thank you for any help.
Upvotes: 5
Views: 2366
Reputation: 1
An alternative answer is using the gradle-tailwind Gradle plugin. The plugin utilises pre-built executables published by Tailwind (that bundle PostCSS & Autoprefixer), over Tailwind's npm
package.
// build.gradle.kts
plugins {
id "au.id.wale.tailwind" version "0.2.0"
}
tailwind {
version = "3.4.1"
configPath = "src/main/resources"
// replace with the relevant `tailwind.css` input paths
input = "src/main/resources/tailwind/tailwind.css"
output = "src/main/resources/css/example.css"
}
Disclaimer: I am the author of the Gradle plugin.
Upvotes: 0
Reputation: 594
The linked I posted is the answer, the whole repository. It is not just a part of it
If you instead want me to copy/paste the whole repository instead here you're
= Kotlin/JS + Tailwind CSS =
This is a small sample repository to show the idiomatic way of
configuring these two systems together.
== Running it ==
. Run `./gradlew run`.
. Open `http://localhost:8080/` in your browser.
. 🎉 Notice we're using Tailwind CSS classes successfully.
== How To ==
Steps taken to make this work:
=== Dependencies ===
Add the following dependencies to your JS target (`jsMain` dependencies) in your Gradle file:
[source,kotlin]
----
implementation("org.jetbrains:kotlin-extensions:1.0.1-pre.148-kotlin-1.4.21")
implementation(npm("postcss", "8.2.6"))
implementation(npm("postcss-loader", "4.2.0")) // 5.0.0 seems not to work
implementation(npm("autoprefixer", "10.2.4"))
implementation(npm("tailwindcss", "2.0.3"))
----
* `kotlin-extensions` is necessary to get the JavaScript link:https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-extensions/src/main/kotlin/kotlinext/js/CommonJS.kt#L20[`require`] function.
** Make sure the version number matches your version of the Kotlin multiplatform plugin at the top of your Gradle file.
** Kotlin Multiplatform 1.4.30 gave me `No descriptor found for library` errors. Try 1.4.21.
** Find the latest versions link:https://bintray.com/kotlin/kotlin-js-wrappers/kotlin-extensions[here].
* `postcss` and `autoprefixer` are link:https://tailwindcss.com/docs/installation#install-tailwind-via- npm[dependencies] as mentioned in the Tailwind CSS docs.
* `postcss-loader` is required because Kotlin/JS is built on top of Webpack.
** Note that while 5.0.0 is out, using it gave me build errors. The latest 4.x seems to work.
* `tailwindcss` is obviously what we're here for.
=== Add Tailwind as a PostCSS plugin ===
Just do link:https://tailwindcss.com/docs/installation#add-tailwind-as-a-post-css-plugin[this step].
If unsure, create this file in your project root:
[source,javascript]
----
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
----
=== Create your configuration file (optional) ===
link:https://tailwindcss.com/docs/installation#create-your-configuration-file[Official documentation].
Creating the `tailwind.config.js` file is a little tricky because simply `npx` won't work, as we haven't installed any
`node_modules`. Fortunately, Kotlin/JS has already done this for us.
Run the following:
[source,shell]
----
$ ./gradlew kotlinNpmInstall
$ ( cd build/js/ && npx tailwindcss init && mv tailwind.config.js ../../ )
----
This generates `tailwind.config.js` in the `build/js/` directory and then moves it up two directories to the project
root. Kotlin/JS generates the node modules into build/js/node_modules
when the kotlinNpmInstall
task runs.
This assumes your JavaScript module is `js`. If it's not, you'll need to change the `cd build/js/` part. If you're not
sure where your node_modules
directory is, run find . -maxdepth 3 -name node_modules
.
You should now have all your dependencies set up and config files created.
=== Create and Reference a Regular CSS File ===
_If you already have a CSS file that you're loading in your app, you can skip this step._
Create `app.css` in your `jsMain/resources/` directory. Put something obvious in there so you know
when it's loaded:
[source,css]
----
body {
background-color: red;
}
----
This file will get copied into the same folder as your transpiled JavaScript files.
In your JavaScript file (`client.kt` in this package), add:
[source,javascript]
----
kotlinext.js.require("./app.css")
----
to your main
method. You can of course import the require
method if you prefer.
If you run `./gradlew run`, you should be able to see a red page at `http://localhost:8080/`.
We're almost there, but we have two more steps: tell Webpack to use PostCSS and to finally inject Tailwind CSS.
=== Using PostCSS with Webpack ===
We want to "monkeypatch" the Webpack configuration that Kotlin/JS generates for us. This hook is
documented in the link:https://kotlinlang.org/docs/js-project-setup.html#webpack-bundling[webpack bundling] section. Basically, if we create .js files in webpack.config.d/
, they'll be automatically
merged into build/js/packages/projectName/webpack.config.js
, which exists after a build and you can go inspect.
The "problem", if you have `cssSupport.enabled = true` in your Gradle file (which you should!), is that this line
generates a webpack rule matching /\.css$/
. We can't simply create another rule matching the same files...that
won't work.
So, we need to find the original rule and modify it. Create the following file relative to your project root:
[source,javascript]
----
// in webpack.config.d/postcss-loader.config.js
(() => {
const cssRule = config.module.rules.find(r => "test.css".match(r.test));
if (!cssRule) {
throw new Error("Could not resolve webpack rule matching .css files.");
}
cssRule.use.push({
loader: "postcss-loader",
options: {}
});
})();
----
We use an IIFE so that our new variable doesn't potentially interfere with other unseen variables.
Now PostCSS is working!
With PostCSS configured and the `tailwindcss` npm module in our dependencies, all that's left now
is to use it.
=== Importing Tailwind CSS ===
We're basically smooth sailing from here. Follow the link:https://tailwindcss.com/docs/installation#include-tailwind-in-your-css[Include Tailwind in your CSS] directions.
Just stick the following in your `app.css`:
[source,css]
----
@tailwind base;
@tailwind components;
@tailwind utilities;
----
If you start the server again, it should **Just Work**! It's a bit hard to tell, but if you check the devtools,
you should see the tw classes loading and massive js.js file being loaded (9.20mb!) which contains all of Tailwind CSS.
== Areas for Improvement ==
=== Modifications to app.css ===
Changes made to app.css don't get picked up unless you do a full `./gradlew clean` first, which is painful.
Adding the following line to build.gradle.kts seems to fix this:
[source,kotlin]
----
tasks.withType(KotlinWebpack::class.java).forEach { t ->
t.inputs.files(fileTree("src/jsMain/resources"))
}
----
=== Getting --continuous working ===
Even with the above fix, --continuous doesn't seem to work. 🤷
== Future Topics ==
* link:https://tailwindcss.com/docs/installation#building-for-production[Building for Production]
Upvotes: 0
Reputation: 998
The accepted answer seems to not work anymore. Also, using the Node Gradle plugin is sub-optimal (KotlinJS already maintains its own package.json
and yarn
installation).
I managed to get Tailwind to work with KotlinJS thanks for this repository (GitHub) with a few small updates that you can find here (GitLab).
Upvotes: 2
Reputation: 41
A basic integration can be achieved with the node-gradle plugin.
In your build.gradle.kts
:
plugins {
id("com.github.node-gradle.node") version "3.0.0-rc2"
}
Also in build.gradle.kts
define a task called "tailwindcss" that calls the tailwind CLI via npx. For example:
val tailwindCss = tasks.register<com.github.gradle.node.npm.task.NpxTask>("tailwindcss") {
// Output CSS location
val generatedFile = "build/resources/main/static/css/tailwind-generated.css"
// Location of the tailwind config file
val tailwindConfig = "css/tailwind.css"
command.set("tailwind")
args.set(listOf("build", tailwindConfig, "-o", generatedFile))
dependsOn(tasks.npmInstall)
// The location of the source files which Tailwind scans when running ```purgecss```
inputs.dir("src/main/kotlin/path/to/your/presentation/files")
inputs.file(tailwindConfig)
outputs.file(generatedFile)
}
Finally, in build.gradle.kts
bind the task to your processResources step, so that it runs automatically. Note you may want to refine this later, because running tailwind every time the processResources step is invoked will slow down your dev cycle.
tasks.processResources {
dependsOn(tailwindCss)
}
Now we need a minimal package.json
in the root of your project. For example:
{
"name": "MyProject",
"devDependencies": {
"tailwindcss": "^1.7.0"
}
}
Finally, we configure our tailwind config in the location defined by our NpxTask, in the example ```css/tailwind.css"
@tailwind base;
@tailwind components;
@tailwind utilities;
So now after the processResource step is run, gradle will invoke the Tailwind npx task, consume your source and write the CSS to the location you specified.
Upvotes: 2