@ereo/plugin-tailwind 0.1.22 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  * @ereo/plugin-tailwind
3
3
  *
4
4
  * Zero-config Tailwind CSS integration for EreoJS.
5
+ * Compiles Tailwind CSS locally via PostCSS — no CDN dependency.
5
6
  */
6
7
  import type { Plugin } from '@ereo/core';
7
8
  /**
@@ -12,6 +13,8 @@ export interface TailwindPluginOptions {
12
13
  content?: string[];
13
14
  /** Path to tailwind.config.js (auto-detected by default) */
14
15
  config?: string;
16
+ /** Path to CSS entry file (auto-detected: app/styles.css) */
17
+ css?: string;
15
18
  /** Enable dark mode */
16
19
  darkMode?: 'class' | 'media' | false;
17
20
  /** Use EreoJS preset */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACrC,wBAAwB;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAYD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CA+F5E;AAGD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE7D;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAwB1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACrC,wBAAwB;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAgBD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CA6M5E;AAGD,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE7D;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAwB1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC"}
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/index.ts
3
- import { join } from "path";
5
+ import { join, resolve } from "path";
6
+ import { existsSync, readFileSync } from "fs";
4
7
 
5
8
  // src/preset.ts
6
9
  var ereoPreset = {
@@ -104,36 +107,126 @@ function getEreoTailwindConfig(overrides = {}) {
104
107
  }
105
108
  };
106
109
  }
107
-
108
110
  // src/index.ts
109
111
  var defaults = {
110
112
  content: ["./app/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
111
113
  config: "tailwind.config.js",
114
+ css: "",
112
115
  darkMode: "class",
113
116
  usePreset: true
114
117
  };
118
+ var DEFAULT_CSS = `@tailwind base;
119
+ @tailwind components;
120
+ @tailwind utilities;`;
115
121
  function tailwind(options = {}) {
116
122
  const opts = { ...defaults, ...options };
117
- let tailwindCSS = null;
118
- let configLoaded = false;
123
+ let root = process.cwd();
124
+ let processor = null;
125
+ let cssCache = null;
126
+ let cacheTimestamp = 0;
127
+ let tailwindConfig = null;
128
+ function findCSSEntry() {
129
+ if (opts.css) {
130
+ const abs = resolve(root, opts.css);
131
+ if (existsSync(abs))
132
+ return abs;
133
+ }
134
+ const candidates = [
135
+ "app/styles.css",
136
+ "app/globals.css",
137
+ "app/global.css",
138
+ "src/styles.css",
139
+ "src/globals.css",
140
+ "styles/globals.css"
141
+ ];
142
+ for (const c of candidates) {
143
+ const abs = join(root, c);
144
+ if (existsSync(abs))
145
+ return abs;
146
+ }
147
+ return "";
148
+ }
149
+ async function loadTailwindConfig() {
150
+ const configPaths = [
151
+ opts.config ? resolve(root, opts.config) : null,
152
+ join(root, "tailwind.config.js"),
153
+ join(root, "tailwind.config.ts"),
154
+ join(root, "tailwind.config.mjs"),
155
+ join(root, "tailwind.config.cjs")
156
+ ].filter(Boolean);
157
+ for (const configPath of configPaths) {
158
+ try {
159
+ if (existsSync(configPath)) {
160
+ delete __require.cache?.[configPath];
161
+ const imported = await import(configPath);
162
+ return imported.default || imported;
163
+ }
164
+ } catch (e) {
165
+ console.warn(` [Tailwind] Failed to load config: ${configPath}`);
166
+ }
167
+ }
168
+ return null;
169
+ }
170
+ async function ensureProcessor() {
171
+ if (processor)
172
+ return processor;
173
+ const postcss = (await import("postcss")).default;
174
+ const tailwindcss = (await import("tailwindcss")).default;
175
+ let autoprefixer;
176
+ try {
177
+ autoprefixer = (await import("autoprefixer")).default;
178
+ } catch {}
179
+ const userConfig = await loadTailwindConfig();
180
+ tailwindConfig = userConfig ? {
181
+ ...userConfig,
182
+ content: Array.isArray(userConfig.content) ? userConfig.content.map((p) => typeof p === "string" && !p.startsWith("/") ? resolve(root, p) : p) : userConfig.content
183
+ } : {
184
+ content: opts.content.map((p) => resolve(root, p)),
185
+ darkMode: opts.darkMode || "class",
186
+ theme: { extend: {} },
187
+ plugins: []
188
+ };
189
+ const plugins = [tailwindcss(tailwindConfig)];
190
+ if (autoprefixer)
191
+ plugins.push(autoprefixer());
192
+ processor = postcss(plugins);
193
+ return processor;
194
+ }
195
+ async function compileTailwind() {
196
+ const now = Date.now();
197
+ if (cssCache && now - cacheTimestamp < 1000)
198
+ return cssCache;
199
+ const proc = await ensureProcessor();
200
+ const cssEntryPath = findCSSEntry();
201
+ const inputCSS = cssEntryPath ? readFileSync(cssEntryPath, "utf-8") : DEFAULT_CSS;
202
+ const result = await proc.process(inputCSS, {
203
+ from: cssEntryPath || "__tailwind.css"
204
+ });
205
+ cssCache = result.css;
206
+ cacheTimestamp = now;
207
+ return result.css;
208
+ }
119
209
  return {
120
210
  name: "ereo:tailwind",
121
211
  async setup(context) {
122
- const root = context.root;
212
+ root = context.root;
123
213
  const configPath = join(root, opts.config);
124
214
  try {
125
215
  const hasConfig = await Bun.file(configPath).exists();
126
216
  if (hasConfig) {
127
217
  console.log(" Using existing tailwind.config.js");
128
- configLoaded = true;
129
- } else {
130
- if (opts.usePreset) {
131
- console.log(" Using EreoJS Tailwind preset");
132
- }
218
+ } else if (opts.usePreset) {
219
+ console.log(" Using EreoJS Tailwind preset");
133
220
  }
134
- } catch (error) {
221
+ } catch {
135
222
  console.warn(" Warning: Could not check for Tailwind config");
136
223
  }
224
+ try {
225
+ await ensureProcessor();
226
+ console.log(" [Tailwind] PostCSS processor ready");
227
+ } catch (e) {
228
+ console.warn(" [Tailwind] Could not initialize processor:", e.message);
229
+ }
137
230
  },
138
231
  resolveId(id) {
139
232
  if (id === "virtual:tailwind.css" || id === "/__tailwind.css") {
@@ -143,40 +236,47 @@ function tailwind(options = {}) {
143
236
  },
144
237
  async load(id) {
145
238
  if (id === "\x00virtual:tailwind.css") {
146
- if (tailwindCSS) {
147
- return tailwindCSS;
239
+ try {
240
+ return await compileTailwind();
241
+ } catch (e) {
242
+ console.error(" [Tailwind] Compilation error:", e.message);
243
+ return `/* Tailwind CSS Error: ${e.message} */`;
148
244
  }
149
- return `
150
- @tailwind base;
151
- @tailwind components;
152
- @tailwind utilities;
153
- `.trim();
154
245
  }
155
246
  return null;
156
247
  },
157
248
  async transform(code, id) {
158
- if (!id.endsWith(".css")) {
249
+ if (!id.endsWith(".css"))
159
250
  return null;
160
- }
161
- if (!code.includes("@tailwind")) {
251
+ if (!code.includes("@tailwind") && !code.includes("@apply"))
162
252
  return null;
253
+ try {
254
+ const proc = await ensureProcessor();
255
+ const result = await proc.process(code, { from: id });
256
+ return result.css;
257
+ } catch (e) {
258
+ console.error(` [Tailwind] Transform error in ${id}:`, e.message);
259
+ return code;
163
260
  }
164
- return code;
165
261
  },
166
262
  async configureServer(server) {
167
263
  server.middlewares.push(async (request, context, next) => {
168
264
  const url = new URL(request.url);
169
265
  if (url.pathname === "/__tailwind.css") {
170
- const css = `
171
- /* Tailwind CSS - Development Mode */
172
- @import url('https://cdn.tailwindcss.com');
173
- `.trim();
174
- return new Response(css, {
175
- headers: {
176
- "Content-Type": "text/css",
177
- "Cache-Control": "no-cache"
178
- }
179
- });
266
+ try {
267
+ const css = await compileTailwind();
268
+ return new Response(css, {
269
+ headers: {
270
+ "Content-Type": "text/css; charset=utf-8",
271
+ "Cache-Control": "no-cache, no-store, must-revalidate"
272
+ }
273
+ });
274
+ } catch (e) {
275
+ return new Response(`/* Tailwind CSS Error: ${e.message} */`, {
276
+ status: 500,
277
+ headers: { "Content-Type": "text/css" }
278
+ });
279
+ }
180
280
  }
181
281
  return next();
182
282
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ereo/plugin-tailwind",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "license": "MIT",
5
5
  "author": "Ereo Team",
6
6
  "homepage": "https://ereo.dev",
@@ -25,25 +25,30 @@
25
25
  "dist"
26
26
  ],
27
27
  "scripts": {
28
- "build": "bun build ./src/index.ts --outdir ./dist --target bun --external @ereo/core --external tailwindcss && bun run build:types",
28
+ "build": "bun build ./src/index.ts --outdir ./dist --target bun --external @ereo/core --external tailwindcss --external postcss --external autoprefixer && bun run build:types",
29
29
  "build:types": "tsc --emitDeclarationOnly --outDir dist",
30
30
  "dev": "bun build ./src/index.ts --outdir ./dist --target bun --watch",
31
31
  "test": "bun test",
32
32
  "typecheck": "tsc --noEmit"
33
33
  },
34
34
  "dependencies": {
35
- "@ereo/core": "^0.1.22"
35
+ "@ereo/core": "^0.1.23"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/bun": "^1.1.0",
39
39
  "typescript": "^5.4.0"
40
40
  },
41
41
  "peerDependencies": {
42
- "tailwindcss": "^3.4.0"
42
+ "tailwindcss": "^3.4.0",
43
+ "postcss": "^8.4.0",
44
+ "autoprefixer": "^10.4.0"
43
45
  },
44
46
  "peerDependenciesMeta": {
45
47
  "tailwindcss": {
46
48
  "optional": true
49
+ },
50
+ "autoprefixer": {
51
+ "optional": true
47
52
  }
48
53
  }
49
54
  }