fresh icon indicating copy to clipboard operation
fresh copied to clipboard

Tailwind 4

Open gawhite opened this issue 11 months ago • 25 comments

Any Guidance on updating to / using Tailwind 4 with Fresh?

gawhite avatar Jan 29 '25 19:01 gawhite

Here. https://github.com/rocklau/fresh-daisyuiv5-demo

dev.ts

#!/usr/bin/env -S deno run -A --watch=static/,routes/

import dev from "$fresh/dev.ts";
import config from "./fresh.config.ts";
import autoprefixer from "autoprefixer";

import "$std/dotenv/load.ts";
import postcss from "postcss";
import tailwindcss from "@tailwindcss/postcss";

const css = Deno.readTextFileSync("./static/app.css");
const out = await postcss([tailwindcss, autoprefixer]).process(css, {
  from: "./static/app.css",
});
Deno.writeTextFileSync("./static/styles.css", out.css);

await dev(import.meta.url, "./main.ts", config);
``

rocklau avatar Feb 10 '25 08:02 rocklau

I followed the configuration for your git repo and even cloned it yet I always get this error. Any ideas?

error: Uncaught (in promise) Error: Can't resolve 'tailwindcss' in '/Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/static'
    at finishWithoutResolve (file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/Resolver.js:564:18)
    at file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/Resolver.js:656:15
    at file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/[USERNAME]/Documents/GitHub/TypeScript%20Learning/react-learning/node_modules/.deno/[email protected]/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/[USERNAME]/Documents/GitHub/TypeScript%20Learning/react-learning/node_modules/.deno/[email protected]/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:89:43
    at file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/[USERNAME]/Documents/GitHub/TypeScript%20Learning/react-learning/node_modules/.deno/[email protected]/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at file:///Users/[USERNAME]/Documents/GitHub/TypeScript Learning/react-learning/node_modules/.deno/[email protected]/node_modules/enhanced-resolve/lib/Resolver.js:718:5

Bentheminernz avatar Feb 13 '25 07:02 Bentheminernz

you need to build first

deno task build
deno install --allow-import -e main.ts

rocklau avatar Feb 13 '25 08:02 rocklau

Since tailwind has lightningcss built-in, if you use tailwind, is autoprefixer still needed?

clearfram3 avatar Feb 20 '25 05:02 clearfram3

This is inconvenient, waiting for the official upgrade to V4

shuliangfu avatar Feb 20 '25 07:02 shuliangfu

I made the package for this. Feel free to copy it to your project while you wait for the official implementation https://jsr.io/@pakornv/fresh-plugin-tailwindcss

pakornv avatar Feb 21 '25 17:02 pakornv

you need to build first

deno task build deno install --allow-import -e main.ts

I get the same error when I run deno task build:

error: Uncaught (in promise) Error: Can't resolve 'tailwindcss' in '/Users/maclong/Developer/kylie-wines/static'
    at finishWithoutResolve (file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/enhanced-resolve/5.18.1/lib/Resolver.js:564:18)
    at file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/enhanced-resolve/5.18.1/lib/Resolver.js:656:15
    at file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/enhanced-resolve/5.18.1/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/tapable/2.2.1/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/enhanced-resolve/5.18.1/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/tapable/2.2.1/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
    at file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/enhanced-resolve/5.18.1/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/tapable/2.2.1/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/enhanced-resolve/5.18.1/lib/Resolver.js:718:5
    at eval (eval at create (file:///Users/maclong/Library/Caches/deno/npm/registry.npmjs.org/tapable/2.2.1/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)

@pakornv I also get this error when using your plugin.

maclong9 avatar Mar 21 '25 12:03 maclong9

@maclong9 I think you need to add tailwindcss to your deno.json e.g. deno add npm:tailwindcss my example project: https://github.com/pakornv/fresh-tailwindcss-v4

pakornv avatar Mar 21 '25 16:03 pakornv

@maclong9 I think you need to add tailwindcss to your deno.json e.g. deno add npm:tailwindcss my example project: https://github.com/pakornv/fresh-tailwindcss-v4

I have got tailwindcss in my deno.json and it's producing the same error.

maclong9 avatar Mar 21 '25 16:03 maclong9

@maclong9 I think you need to add tailwindcss to your deno.json e.g. deno add npm:tailwindcss my example project: https://github.com/pakornv/fresh-tailwindcss-v4

I have got tailwindcss in my deno.json and it's producing the same error.

Could you share your example that produce the error?

pakornv avatar Mar 21 '25 16:03 pakornv

@maclong9 I think you need to add tailwindcss to your deno.json e.g. deno add npm:tailwindcss my example project: https://github.com/pakornv/fresh-tailwindcss-v4

I have got tailwindcss in my deno.json and it's producing the same error.

Could you share your example that produce the error?

It's a private repo unfortunately, what files do you need and I can create a minimal repro of the project so you can see

maclong9 avatar Mar 24 '25 17:03 maclong9

@pakornv your project works for me but I can't add the plugin daisy. I don't have any errors but styles are not apply. Any idea ?

hapaxlife avatar Apr 03 '25 06:04 hapaxlife

@pakornv your project works for me but I can't add the plugin daisy. I don't have any errors but styles are not apply. Any idea ?

Sorry for late reply. I just try Daisy UI v5 with my repo and it works. https://github.com/pakornv/fresh-tailwindcss-v4/pull/1

pakornv avatar Apr 20 '25 01:04 pakornv

@maclong9 I just accidentally reproduce the error. I add "nodeModulesDir": "auto" to my deno.json add the error gone.

pakornv avatar Apr 20 '25 01:04 pakornv

hello there, I attempted to make the plugin-tailwind support tailwind version 4 based on #2819, #2829, and https://github.com/pakornv/fresh-plugin-tailwind. It worked properly under the condition of "nodeModulesDir": "auto", and the "/www" functioned normally after the modification. However, when I tried to remove the support for node_modules, I encountered a situation where @tailwindcss/oxide (the new engine of Tailwind v4, written in Rust) didn't provide support. Due to the breaking changes in version 4, the new @tailwindcss/postcss will attempt to call @tailwindcss/oxide, and it currently seems that this issue cannot be easily resolved (it appears so).

SisyphusZheng avatar May 10 '25 16:05 SisyphusZheng

Since tailwind has lightningcss built-in, if you use tailwind, is autoprefixer still needed?

@clearfram3 it's not needed: source

tylersayshi avatar May 12 '25 04:05 tylersayshi

I have this (admittedly bad) setup to get tailwind 4 running with fresh 2:

deno.json:

{
	"tasks": {
		"dev-tailwind": "deno run -A --watch=static/,routes/ --watch-exclude=static/style.css npm:@tailwindcss/cli -i static/style.css -o static/style.compiled.css",
		"dev": "deno run -A --watch=static/,routes/ --watch-exclude=static/style.compiled.css --env dev.js",
		"build": "deno run -A npm:@tailwindcss/cli -i static/style.css -o static/style.compiled.css && deno run -A --env dev.js build"
	},
	"nodeModulesDir": "none",
	"exclude": [
		"**/_fresh/*"
	],
	"imports": {
		"@preact/signals": "npm:@preact/signals@^2.0.4",
		"@tailwindcss/cli": "npm:@tailwindcss/cli@^4.1.6",
		"@typescript-to-lua/language-extensions": "npm:@typescript-to-lua/language-extensions@^1.19.0",
		"fresh": "jsr:@fresh/core@^2.0.0-alpha.34",
		"preact": "npm:preact@^10.26.6",
		"react": "npm:preact@^10.26.6/compat",
		"react-dom": "npm:preact@^10.26.6/compat",
		"tailwindcss": "npm:tailwindcss@^4.1.6"
	}
}

package.json:

{
	"devDependencies": {
		"@tailwindcss/cli": "^4.1.6",
		"tailwindcss": "^4.1.6"
	},
	"type": "module"
}

./static/style.css:

@import "https://rsms.me/inter/inter.css";
@import "tailwindcss";
@source "../components";
@source "../islands";
@source "../routes";

@font-face {
	font-family: Monaspace Neon;
	font-style: normal;
	font-weight: 200 800;
	font-display: swap;
	src: url("/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2") format("woff2");
}

@font-face {
	font-family: m6x11plus;
	font-display: swap;
	src: url("/fonts/m6x11plus.ttf") format("truetype");
}

@theme inline {
	--font-sans: m6x11plus, sans-serif;

	--font-mono: Monaspace Neon, monospace;
	--drop-shadow-dynamic: var(--shadow-x) 4px 0px #00000040;
}

For best IDE experience I also recommend the tailwind extension and this .vscode/settings.json:

{
	"tailwindCSS.files.exclude": [
		"**/.git/**",
		"**/node_modules/**",
		"**/.hg/**",
		"**/.svn/**",
		"**/style.compiled.css"
	]
}

These steps are needed to initialize all of this:

  1. Make sure node_modules, package-lock.json and deno.lock are deleted
  2. Run npm install
  3. Set the environment variable DENO_NO_PACKAGE_JSON to 1
  4. Run deno task dev-tailwind and then deno task dev once (to populate deno.lock

Unix command to do all that (press Ctrl-c two times to stop it):

DENO_NO_PACKAGE_JSON=1 && rm -rf package-lock.json node_modules deno.lock && deno task dev-tailwind && deno task dev

Now you should be able to build with deno task build. Caveat: You need to stop the command with Ctrl-C even after it's finished, as if it is deno task dev, no idea why.

For development, you need to run deno task dev and deno task dev-tailwind in two separate terminals. Someone smarter than me can probably make a parallel single command variant of this.

nnmrts avatar May 22 '25 19:05 nnmrts

@nnmrts you can try my plugin for fresh 2. I just update my example repo https://github.com/pakornv/fresh-tailwindcss-v4

pakornv avatar May 23 '25 06:05 pakornv

@nnmrts you can try my plugin for fresh 2. I just update my example repo https://github.com/pakornv/fresh-tailwindcss-v4

@pakornv I would if it wouldn't require me to set "nodeModulesDir" to "auto". That messes up my eslint (which I also have to run over npm/npx) and sometimes my IDE as well.

nnmrts avatar May 23 '25 15:05 nnmrts

@nnmrts you can try my plugin for fresh 2. I just update my example repo https://github.com/pakornv/fresh-tailwindcss-v4

@pakornv I would if it wouldn't require me to set "nodeModulesDir" to "auto". That messes up my eslint (which I also have to run over npm/npx) and sometimes my IDE as well.

Seems you're using Tailwind CLI to solve this problem, but both the official plugins in fresh repo and the ones mentioned above mainly rely on PostCSS. Therefore, it appears that they can't work without enabling NodeModules.

SisyphusZheng avatar May 23 '25 16:05 SisyphusZheng

@nnmrts you can try my plugin for fresh 2. I just update my example repo https://github.com/pakornv/fresh-tailwindcss-v4

@pakornv I would if it wouldn't require me to set "nodeModulesDir" to "auto". That messes up my eslint (which I also have to run over npm/npx) and sometimes my IDE as well.

Can't you just ignore node_modules I have no idea why you'd want to lint your modules directory anyway.

https://eslint.org/docs/latest/use/configure/ignore

maclong9 avatar May 23 '25 18:05 maclong9

I'm not linting my node_modules... 🙄

The problem is

  1. deno doesn't support eslint cli -> i need npm/npx for that
  2. vscode-eslint also wouldn't support resolving eslint from deno.json -> i need a package.json
  3. running any deno command in a folder with a package.json fucks with my node_modules, because deno resolves stuff differently and sometimes breaks things when trying to install npm packages, either by creating that node_modules/.deno folder or by writing complete nonsense into deno.lock or something else -> i need to disable deno auto detecting node stuff
  4. i obviously still run npm install in this folder -> node_modules folder and package-lock.json gets created

So point 4 leads to this assumption being wrong:

Therefore, it appears that they can't work without enabling NodeModules.

I don't need to "enable" node_modules in my deno.json. The package.json and node_modules folder exist, so

deno run -A npm:@tailwindcss/cli -i static/style.css -o static/style.compiled.css

just works.

Literally just try out setting up a simple repo where you lint with eslint in vscode and from the terminal, while also having a fresh project there. Unless I'm missing something big big, you NEED to do the fuckery I did above instead of going the "recommended" Deno-autodetecting-node-stuff-mysteriously route.

Sorry for the grumpiness but while writing this I just relived several instances of several hours wasted on debugging this exact issue.

nnmrts avatar May 23 '25 23:05 nnmrts

I'm not linting my node_modules... 🙄

The problem is

  1. deno doesn't support eslint cli -> i need npm/npx for that
  2. vscode-eslint also wouldn't support resolving eslint from deno.json -> i need a package.json
  3. running any deno command in a folder with a package.json fucks with my node_modules, because deno resolves stuff differently and sometimes breaks things when trying to install npm packages, either by creating that node_modules/.deno folder or by writing complete nonsense into deno.lock or something else -> i need to disable deno auto detecting node stuff
  4. i obviously still run npm install in this folder -> node_modules folder and package-lock.json gets created

So point 4 leads to this assumption being wrong:

Therefore, it appears that they can't work without enabling NodeModules.

I don't need to "enable" node_modules in my deno.json. The package.json and node_modules folder exist, so

deno run -A npm:@tailwindcss/cli -i static/style.css -o static/style.compiled.css

just works.

Literally just try out setting up a simple repo where you lint with eslint in vscode and from the terminal, while also having a fresh project there. Unless I'm missing something big big, you NEED to do the fuckery I did above instead of going the "recommended" Deno-autodetecting-node-stuff-mysteriously route.

Sorry for the grumpiness but while writing this I just relived several instances of several hours wasted on debugging this exact issue.

Out of curiosity what do you need ESLint for in a Deno Fresh project where deno lint works wonders? Also you really shouldn't use npm and deno in the same project, use just plain Deno and install npm packages using deno install npm:eslint for example...

maclong9 avatar May 23 '25 23:05 maclong9

I think we are a bit off topic at this point, but anyway: https://github.com/pumpncode/eslint-config

I may be somewhat of a perfectionist when it comes to code formatting, but I also think a good set of linting rules can improve the experience of working on something together immensely, which is why I introduced my config at my workplace as well and we're using it successfully there.

Since I've recently heard deno lint supports linter plugins and accepts (roughly?) the same format, I was playing with the idea of migrating all these rules to Deno at some point, but that is obviously a huge undertaking. Not to bash Deno too much (I'm using it for literally everything else), but I also expect it to not support a bunch of my code style choices right now, because the Deno team's style guide is almost diametrically opposite to mine (declarations vs expressions, TS vs TS-in-JSDoc, spaces vs tabs, named exports vs default exports, etc.), and they understandably tend to support their way of doing things first.

nnmrts avatar May 24 '25 15:05 nnmrts

Ah that’s where you and I differ, I only use typescript for work so lint and fmt built in to Deno are enough with the default settings for me

maclong9 avatar May 24 '25 15:05 maclong9

What's the difference between #2829 and #3054 ?

Anutrix avatar Jul 18 '25 00:07 Anutrix

What's the difference between #2829 and #3054 ?

To be honest, there isn't a huge difference. #3054 references and modifies #2829, but both are derived from community plugins. When I checked #2829 last time, I forked the code, but it seemed that the problem wasn't resolved and there were some other issues. This problem should have been fixed in #2903, but there was an issue with the loader at that time, which has now been fixed. So #3054 is a follow-up to #2903, pending the resolution of this problem.

SisyphusZheng avatar Jul 18 '25 01:07 SisyphusZheng