Skip to content

Commit 2269ed6

Browse files
plugin-tailwindcss: tailwind v4
1 parent f49a3f1 commit 2269ed6

File tree

6 files changed

+164
-148
lines changed

6 files changed

+164
-148
lines changed

deno.lock

Lines changed: 145 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin-tailwindcss/README.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,23 @@
22

33
A Tailwind CSS plugin to use in Fresh.
44

5+
> **Note:** This plugin **only** supports Tailwind CSS v4
6+
57
```ts
68
// dev.ts
79

8-
import { tailwind } from "@fresh/plugin-tailwind";
9-
import { FreshDevApp } from "fresh/dev";
10+
import { Builder } from "fresh/dev";
1011
import { app } from "./main.ts";
12+
import { tailwind } from "@fresh/plugin-tailwind";
1113

12-
const devApp = new FreshDevApp();
13-
14+
const builder = new Builder({ target: "safari12" });
1415
// Enable Tailwind CSS
15-
tailwind(devApp);
16-
17-
devApp.mountApp("/", app);
16+
tailwind(builder, app);
1817

1918
if (Deno.args.includes("build")) {
20-
await devApp.build({
21-
target: "safari12",
22-
});
19+
await builder.build(app);
2320
} else {
24-
await devApp.listen();
21+
await builder.listen(app);
2522
}
2623
```
2724

plugin-tailwindcss/deno.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66
".": "./src/mod.ts"
77
},
88
"imports": {
9-
"fresh": "jsr:@fresh/core@^2.0.0-alpha.22",
10-
"@std/path": "jsr:@std/path@1",
11-
"autoprefixer": "npm:autoprefixer@10.4.17",
12-
"cssnano": "npm:cssnano@6.0.3",
13-
"postcss": "npm:postcss@8.4.35",
14-
"tailwindcss": "npm:tailwindcss@^3.4.1"
9+
"@tailwindcss/postcss": "npm:@tailwindcss/postcss@^4.0.8",
10+
"fresh": "jsr:@fresh/core@^2.0.0-alpha.29",
11+
"postcss": "npm:postcss@8.4.35"
1512
}
1613
}

plugin-tailwindcss/src/compiler.ts

Lines changed: 7 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,14 @@
1-
import tailwindCss, { type Config } from "tailwindcss";
1+
import tailwindPoscss from "@tailwindcss/postcss";
22
import postcss from "postcss";
3-
import autoprefixer from "autoprefixer";
4-
import * as path from "@std/path";
5-
import type { TailwindPluginOptions } from "./types.ts";
63
import type { ResolvedFreshConfig } from "fresh";
4+
import type { Processor } from "postcss";
75

8-
const CONFIG_EXTENSIONS = ["ts", "js", "mjs"];
9-
10-
async function findTailwindConfigFile(directory: string): Promise<string> {
11-
let dir = directory;
12-
while (true) {
13-
for (let i = 0; i < CONFIG_EXTENSIONS.length; i++) {
14-
const ext = CONFIG_EXTENSIONS[i];
15-
const filePath = path.join(dir, `tailwind.config.${ext}`);
16-
try {
17-
const stat = await Deno.stat(filePath);
18-
if (stat.isFile) {
19-
return filePath;
20-
}
21-
} catch (err) {
22-
if (!(err instanceof Deno.errors.NotFound)) {
23-
throw err;
24-
}
25-
}
26-
}
27-
28-
const parent = path.dirname(dir);
29-
if (parent === dir) {
30-
throw new Error(
31-
`Could not find a tailwind config file in the current directory or any parent directory.`,
32-
);
33-
}
34-
35-
dir = parent;
36-
}
37-
}
38-
39-
export async function initTailwind(
6+
export function initTailwind(
407
config: ResolvedFreshConfig,
41-
options: TailwindPluginOptions,
42-
): Promise<postcss.Processor> {
43-
const root = path.dirname(config.staticDir);
44-
45-
const configPath = await findTailwindConfigFile(root);
46-
const url = path.toFileUrl(configPath).href;
47-
const tailwindConfig = (await import(url)).default as Config;
48-
49-
if (!Array.isArray(tailwindConfig.content)) {
50-
throw new Error(`Expected tailwind "content" option to be an array`);
51-
}
52-
53-
// deno-lint-ignore no-explicit-any
54-
tailwindConfig.content = tailwindConfig.content.map((pattern: any) => {
55-
if (typeof pattern === "string") {
56-
const relative = path.relative(Deno.cwd(), path.dirname(configPath));
57-
58-
if (!relative.startsWith("..")) {
59-
return path.join(relative, pattern);
60-
}
61-
}
62-
return pattern;
63-
});
64-
65-
// PostCSS types cause deep recursion
66-
const plugins = [
67-
// deno-lint-ignore no-explicit-any
68-
tailwindCss(tailwindConfig) as any,
69-
// deno-lint-ignore no-explicit-any
70-
autoprefixer(options.autoprefixer) as any,
71-
];
72-
73-
if (config.mode === "production") {
74-
const { default: cssnano } = await import("cssnano");
75-
plugins.push(cssnano());
76-
}
8+
): Processor {
9+
const res = postcss(tailwindPoscss({
10+
optimize: config.mode === "production",
11+
}));
7712

78-
const res = postcss(plugins);
7913
return res;
8014
}

plugin-tailwindcss/src/mod.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
import type { TailwindPluginOptions } from "./types.ts";
21
import { initTailwind } from "./compiler.ts";
32
import type { Builder } from "fresh/dev";
43
import type { App } from "fresh";
54

65
export function tailwind<T>(
76
builder: Builder,
87
app: App<T>,
9-
options: TailwindPluginOptions = {},
108
): void {
119
let processor: ReturnType<typeof initTailwind> | null;
1210

1311
builder.onTransformStaticFile(
1412
{ pluginName: "tailwind", filter: /\.css$/ },
1513
async (args) => {
16-
if (!processor) processor = initTailwind(app.config, options);
14+
if (!processor) processor = initTailwind(app.config);
1715
const instance = await processor;
1816
const res = await instance.process(args.text, {
1917
from: args.path,

0 commit comments

Comments
 (0)