-
Notifications
You must be signed in to change notification settings - Fork 748
Expand file tree
/
Copy pathmod.ts
More file actions
154 lines (129 loc) · 4.18 KB
/
mod.ts
File metadata and controls
154 lines (129 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import type { Builder, ResolvedBuildConfig } from "fresh/dev";
import tailwindCss, { type Config } from "tailwindcss";
import postcss from "postcss";
import cssnano from "cssnano";
import autoprefixer from "autoprefixer";
import * as path from "@std/path";
/**
* @deprecated Use the Vite plugin with `@tailwindcss/vite` instead.
*/
export interface AutoprefixerOptions {
/** environment for `Browserslist` */
env?: string;
/** should Autoprefixer use Visual Cascade, if CSS is uncompressed */
cascade?: boolean;
/** should Autoprefixer add prefixes. */
add?: boolean;
/** should Autoprefixer [remove outdated] prefixes */
remove?: boolean;
/** should Autoprefixer add prefixes for @supports parameters. */
supports?: boolean;
/** should Autoprefixer add prefixes for flexbox properties */
flexbox?: boolean | "no-2009";
/** should Autoprefixer add IE 10-11 prefixes for Grid Layout properties */
grid?: boolean | "autoplace" | "no-autoplace";
/** custom usage statistics for > 10% in my stats browsers query */
stats?: {
[browser: string]: {
[version: string]: number;
};
};
/**
* list of queries for target browsers.
* Try to not use it.
* The best practice is to use `.browserslistrc` config or `browserslist` key in `package.json`
* to share target browsers with Babel, ESLint and Stylelint
*/
overrideBrowserslist?: string | string[];
/** do not raise error on unknown browser version in `Browserslist` config. */
ignoreUnknownVersions?: boolean;
}
/**
* @deprecated Use the Vite plugin with `@tailwindcss/vite` instead.
*/
export interface TailwindPluginOptions {
autoprefixer?: AutoprefixerOptions;
}
/**
* @deprecated Use the Vite plugin with `@tailwindcss/vite` instead.
* This plugin is only compatible with the legacy Builder API.
*/
export function tailwind(
builder: Builder,
options: TailwindPluginOptions = {},
): void {
const processor = initTailwind(builder.config, options);
builder.onTransformStaticFile(
{ pluginName: "tailwind", filter: /\.css$/ },
async (args) => {
const instance = await processor;
const res = await instance.process(args.text, {
from: args.path,
});
return {
content: res.content,
map: res.map?.toString(),
};
},
);
}
const CONFIG_EXTENSIONS = ["ts", "js", "mjs"];
async function findTailwindConfigFile(directory: string): Promise<string> {
let dir = directory;
while (true) {
for (let i = 0; i < CONFIG_EXTENSIONS.length; i++) {
const ext = CONFIG_EXTENSIONS[i];
const filePath = path.join(dir, `tailwind.config.${ext}`);
try {
const stat = await Deno.stat(filePath);
if (stat.isFile) {
return filePath;
}
} catch (err) {
if (!(err instanceof Deno.errors.NotFound)) {
throw err;
}
}
}
const parent = path.dirname(dir);
if (parent === dir) {
throw new Error(
`Could not find a tailwind config file in the current directory or any parent directory.`,
);
}
dir = parent;
}
}
async function initTailwind(
config: ResolvedBuildConfig,
options: TailwindPluginOptions,
): Promise<postcss.Processor> {
const root = path.dirname(config.staticDir);
const configPath = await findTailwindConfigFile(root);
const url = path.toFileUrl(configPath).href;
const tailwindConfig = (await import(url)).default as Config;
if (!Array.isArray(tailwindConfig.content)) {
throw new Error(`Expected tailwind "content" option to be an array`);
}
// deno-lint-ignore no-explicit-any
tailwindConfig.content = tailwindConfig.content.map((pattern: any) => {
if (typeof pattern === "string") {
const relative = path.relative(Deno.cwd(), path.dirname(configPath));
if (!relative.startsWith("..")) {
return path.join(relative, pattern);
}
}
return pattern;
});
// PostCSS types cause deep recursion
const plugins = [
// deno-lint-ignore no-explicit-any
tailwindCss(tailwindConfig) as any,
// deno-lint-ignore no-explicit-any
autoprefixer(options.autoprefixer) as any,
];
if (config.mode === "production") {
plugins.push(cssnano());
}
return postcss(plugins);
}