@tailwind-styled/next 2.0.0
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/astTransform-CDvNOLX5.d.cts +30 -0
- package/dist/astTransform-CDvNOLX5.d.ts +30 -0
- package/dist/chunk-LQ6DVF5A.js +2604 -0
- package/dist/chunk-QYSYW6TK.js +62 -0
- package/dist/index.cjs +288 -0
- package/dist/index.d.cts +45 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +240 -0
- package/dist/turbopackLoader.cjs +2711 -0
- package/dist/turbopackLoader.d.cts +22 -0
- package/dist/turbopackLoader.d.ts +22 -0
- package/dist/turbopackLoader.js +82 -0
- package/dist/webpackLoader.cjs +2692 -0
- package/dist/webpackLoader.d.cts +24 -0
- package/dist/webpackLoader.d.ts +24 -0
- package/dist/webpackLoader.js +63 -0
- package/package.json +35 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
9
|
+
var __typeError = (msg) => {
|
|
10
|
+
throw TypeError(msg);
|
|
11
|
+
};
|
|
12
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
+
var __spreadValues = (a, b) => {
|
|
14
|
+
for (var prop in b || (b = {}))
|
|
15
|
+
if (__hasOwnProp.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
if (__getOwnPropSymbols)
|
|
18
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
+
if (__propIsEnum.call(b, prop))
|
|
20
|
+
__defNormalProp(a, prop, b[prop]);
|
|
21
|
+
}
|
|
22
|
+
return a;
|
|
23
|
+
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
26
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
27
|
+
}) : x)(function(x) {
|
|
28
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
29
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
30
|
+
});
|
|
31
|
+
var __esm = (fn, res) => function __init() {
|
|
32
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
33
|
+
};
|
|
34
|
+
var __export = (target, all) => {
|
|
35
|
+
for (var name in all)
|
|
36
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
37
|
+
};
|
|
38
|
+
var __copyProps = (to, from, except, desc) => {
|
|
39
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
40
|
+
for (let key of __getOwnPropNames(from))
|
|
41
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
42
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
43
|
+
}
|
|
44
|
+
return to;
|
|
45
|
+
};
|
|
46
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
47
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
48
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
49
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
50
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
__spreadValues,
|
|
54
|
+
__spreadProps,
|
|
55
|
+
__require,
|
|
56
|
+
__esm,
|
|
57
|
+
__export,
|
|
58
|
+
__toCommonJS,
|
|
59
|
+
__privateGet,
|
|
60
|
+
__privateAdd,
|
|
61
|
+
__privateSet
|
|
62
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
10
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
+
var __spreadValues = (a, b) => {
|
|
14
|
+
for (var prop in b || (b = {}))
|
|
15
|
+
if (__hasOwnProp.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
if (__getOwnPropSymbols)
|
|
18
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
+
if (__propIsEnum.call(b, prop))
|
|
20
|
+
__defNormalProp(a, prop, b[prop]);
|
|
21
|
+
}
|
|
22
|
+
return a;
|
|
23
|
+
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __export = (target, all) => {
|
|
26
|
+
for (var name in all)
|
|
27
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
28
|
+
};
|
|
29
|
+
var __copyProps = (to, from, except, desc) => {
|
|
30
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
31
|
+
for (let key of __getOwnPropNames(from))
|
|
32
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
33
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
34
|
+
}
|
|
35
|
+
return to;
|
|
36
|
+
};
|
|
37
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
38
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
39
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
40
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
41
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
42
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
43
|
+
mod
|
|
44
|
+
));
|
|
45
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
46
|
+
|
|
47
|
+
// src/index.ts
|
|
48
|
+
var src_exports = {};
|
|
49
|
+
__export(src_exports, {
|
|
50
|
+
withTailwindStyled: () => withTailwindStyled
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(src_exports);
|
|
53
|
+
|
|
54
|
+
// src/withTailwindStyled.ts
|
|
55
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
56
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
57
|
+
var LOADER_PATH = require.resolve("./turbopackLoader");
|
|
58
|
+
var WEBPACK_LOADER_PATH = require.resolve("./webpackLoader");
|
|
59
|
+
function withTailwindStyled(opts = {}) {
|
|
60
|
+
return (nextConfig = {}) => {
|
|
61
|
+
var _a, _b, _c;
|
|
62
|
+
const cwd = process.cwd();
|
|
63
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
64
|
+
const hasReactCompiler = nextConfig.reactCompiler === true || ((_a = nextConfig.experimental) == null ? void 0 : _a.reactCompiler) === true;
|
|
65
|
+
if (hasReactCompiler && isDev) {
|
|
66
|
+
console.log("[tailwind-styled-v4] React Compiler detected \u2192 hoist disabled");
|
|
67
|
+
}
|
|
68
|
+
const {
|
|
69
|
+
scanDirs = ["src"],
|
|
70
|
+
safelistOutput = "src/app/__tw-safelist.css",
|
|
71
|
+
autoClientBoundary = true,
|
|
72
|
+
hoist = !hasReactCompiler,
|
|
73
|
+
atomic = false,
|
|
74
|
+
routeCssDir = import_node_path.default.join(cwd, ".next", "static", "css", "tw"),
|
|
75
|
+
zeroConfig = true,
|
|
76
|
+
plugins = [],
|
|
77
|
+
devtools = isDev,
|
|
78
|
+
staticVariants = !isDev,
|
|
79
|
+
deadStyleElimination = !isDev
|
|
80
|
+
} = opts;
|
|
81
|
+
const routeCss = opts.routeCss !== void 0 ? opts.routeCss : !isDev;
|
|
82
|
+
if (zeroConfig) {
|
|
83
|
+
try {
|
|
84
|
+
const { bootstrapZeroConfig } = require("@tailwind-styled/compiler");
|
|
85
|
+
bootstrapZeroConfig(cwd);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const safelistAbsPath = import_node_path.default.isAbsolute(safelistOutput) ? safelistOutput : import_node_path.default.resolve(cwd, safelistOutput);
|
|
90
|
+
if (!import_node_fs.default.existsSync(safelistAbsPath)) {
|
|
91
|
+
try {
|
|
92
|
+
import_node_fs.default.mkdirSync(import_node_path.default.dirname(safelistAbsPath), { recursive: true });
|
|
93
|
+
import_node_fs.default.writeFileSync(
|
|
94
|
+
safelistAbsPath,
|
|
95
|
+
"/* Auto-generated by tailwind-styled-v4 \u2014 DO NOT EDIT */\n"
|
|
96
|
+
);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (plugins.length > 0) {
|
|
101
|
+
try {
|
|
102
|
+
const { use } = require("@tailwind-styled/plugin");
|
|
103
|
+
for (const plugin of plugins) use(plugin);
|
|
104
|
+
console.log(
|
|
105
|
+
`[tailwind-styled-v4] ${plugins.length} plugin(s): ${plugins.map((p) => p.name).join(", ")}`
|
|
106
|
+
);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
console.warn("[tailwind-styled-v4] Plugin init failed:", e);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const loaderOpts = {
|
|
112
|
+
mode: opts.mode,
|
|
113
|
+
addDataAttr: (_b = opts.addDataAttr) != null ? _b : isDev,
|
|
114
|
+
autoClientBoundary,
|
|
115
|
+
hoist,
|
|
116
|
+
atomic,
|
|
117
|
+
routeCss,
|
|
118
|
+
staticVariants
|
|
119
|
+
};
|
|
120
|
+
return __spreadProps(__spreadValues({}, nextConfig), {
|
|
121
|
+
experimental: __spreadValues({}, nextConfig.experimental),
|
|
122
|
+
// Next.js 16+: turbopack moved to top-level
|
|
123
|
+
// FIX TURBOPACK: pattern "*.{tsx,ts,jsx,js}" terlalu lebar — ikut match
|
|
124
|
+
// node_modules/next/dist/client/*.js.tsx dan trigger "Missing module type".
|
|
125
|
+
// Solusi: scope pattern ke scanDirs saja, jangan catch-all.
|
|
126
|
+
// `as` field dihapus — tidak perlu karena loader output tetap TSX-compatible.
|
|
127
|
+
turbopack: __spreadProps(__spreadValues({}, nextConfig.turbopack), {
|
|
128
|
+
rules: __spreadValues(__spreadValues({}, Object.fromEntries(
|
|
129
|
+
scanDirs.flatMap((dir) => [
|
|
130
|
+
[
|
|
131
|
+
`{./${dir},./src,./app,./pages,./components}/**/*.tsx`,
|
|
132
|
+
{
|
|
133
|
+
loaders: [{ loader: LOADER_PATH, options: loaderOpts }]
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
`{./${dir},./src,./app,./pages,./components}/**/*.ts`,
|
|
138
|
+
{
|
|
139
|
+
loaders: [{ loader: LOADER_PATH, options: loaderOpts }]
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
])
|
|
143
|
+
)), (_c = nextConfig.turbopack) == null ? void 0 : _c.rules)
|
|
144
|
+
}),
|
|
145
|
+
webpack(webpackConfig, webpackOpts) {
|
|
146
|
+
var _a2, _b2, _c2, _d;
|
|
147
|
+
const alreadyRegistered = webpackConfig.module.rules.some(
|
|
148
|
+
(r) => r._tailwindStyledMarker === true
|
|
149
|
+
);
|
|
150
|
+
if (!alreadyRegistered) {
|
|
151
|
+
webpackConfig.module.rules.push({
|
|
152
|
+
_tailwindStyledMarker: true,
|
|
153
|
+
test: /\.(tsx|ts|jsx|js)$/,
|
|
154
|
+
exclude: /node_modules/,
|
|
155
|
+
use: [
|
|
156
|
+
{
|
|
157
|
+
loader: WEBPACK_LOADER_PATH,
|
|
158
|
+
options: __spreadProps(__spreadValues({}, loaderOpts), {
|
|
159
|
+
mode: (_a2 = opts.mode) != null ? _a2 : webpackOpts.dev ? "runtime" : "zero-runtime",
|
|
160
|
+
addDataAttr: (_b2 = opts.addDataAttr) != null ? _b2 : webpackOpts.dev
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (devtools && webpackOpts.dev) {
|
|
167
|
+
webpackConfig.resolve = (_c2 = webpackConfig.resolve) != null ? _c2 : {};
|
|
168
|
+
webpackConfig.resolve.alias = __spreadProps(__spreadValues({}, (_d = webpackConfig.resolve.alias) != null ? _d : {}), {
|
|
169
|
+
"tailwind-styled-v4/devtools": import_node_path.default.resolve(__dirname, "../../devtools/src/index.tsx")
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return typeof nextConfig.webpack === "function" ? nextConfig.webpack(webpackConfig, webpackOpts) : webpackConfig;
|
|
173
|
+
},
|
|
174
|
+
generateBuildId: async () => {
|
|
175
|
+
try {
|
|
176
|
+
const { generateSafelistCss } = require("@tailwind-styled/compiler");
|
|
177
|
+
generateSafelistCss(
|
|
178
|
+
scanDirs.map((d) => import_node_path.default.resolve(cwd, d)),
|
|
179
|
+
import_node_path.default.isAbsolute(safelistOutput) ? safelistOutput : import_node_path.default.resolve(cwd, safelistOutput)
|
|
180
|
+
);
|
|
181
|
+
console.log("[tailwind-styled-v4] \u2713 Safelist CSS generated");
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.warn("[tailwind-styled-v4] Safelist skipped:", e);
|
|
184
|
+
}
|
|
185
|
+
if (plugins.length > 0) {
|
|
186
|
+
try {
|
|
187
|
+
const { getGlobalRegistry, runBuildHooks } = require("@tailwind-styled/plugin");
|
|
188
|
+
await runBuildHooks(getGlobalRegistry());
|
|
189
|
+
console.log("[tailwind-styled-v4] \u2713 Plugin build hooks complete");
|
|
190
|
+
} catch (e) {
|
|
191
|
+
console.warn("[tailwind-styled-v4] Plugin build hooks failed:", e);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (routeCss) {
|
|
195
|
+
try {
|
|
196
|
+
const {
|
|
197
|
+
generateAllRouteCss,
|
|
198
|
+
getCollectorSummary,
|
|
199
|
+
runElimination
|
|
200
|
+
} = require("@tailwind-styled/compiler");
|
|
201
|
+
const results = await generateAllRouteCss({ cwd, outputDir: routeCssDir, minify: true });
|
|
202
|
+
console.log(getCollectorSummary());
|
|
203
|
+
if (deadStyleElimination) {
|
|
204
|
+
let totalSaved = 0;
|
|
205
|
+
for (const result of results) {
|
|
206
|
+
const routeFile = import_node_path.default.join(
|
|
207
|
+
routeCssDir,
|
|
208
|
+
result.route === "/" ? "index.css" : `${result.route.replace(/\//g, "_")}.css`
|
|
209
|
+
);
|
|
210
|
+
if (import_node_fs.default.existsSync(routeFile)) {
|
|
211
|
+
const inputCss = import_node_fs.default.readFileSync(routeFile, "utf-8");
|
|
212
|
+
const { css, report } = runElimination({ dirs: scanDirs, cwd, inputCss });
|
|
213
|
+
import_node_fs.default.writeFileSync(routeFile, css);
|
|
214
|
+
totalSaved += report.bytesSaved;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (totalSaved > 0) {
|
|
218
|
+
console.log(
|
|
219
|
+
`[tailwind-styled-v4] \u2713 Dead styles eliminated: ~${(totalSaved / 1024).toFixed(1)}KB saved`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const totalKb = results.reduce((s, r) => s + r.sizeBytes, 0) / 1024;
|
|
224
|
+
console.log(
|
|
225
|
+
`[tailwind-styled-v4] \u2713 Route CSS: ${results.length} routes, ${totalKb.toFixed(1)}KB`
|
|
226
|
+
);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.warn("[tailwind-styled-v4] Route CSS skipped:", e);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (plugins.length > 0) {
|
|
232
|
+
try {
|
|
233
|
+
const {
|
|
234
|
+
getGlobalRegistry,
|
|
235
|
+
generateTokenCss,
|
|
236
|
+
generateUtilityCss,
|
|
237
|
+
applyCssHooks
|
|
238
|
+
} = require("@tailwind-styled/plugin");
|
|
239
|
+
const registry = getGlobalRegistry();
|
|
240
|
+
let pluginCss = [generateTokenCss(registry), generateUtilityCss(registry)].filter(Boolean).join("\n\n");
|
|
241
|
+
pluginCss = applyCssHooks(pluginCss, registry);
|
|
242
|
+
if (pluginCss.trim()) {
|
|
243
|
+
const outPath = import_node_path.default.join(cwd, "public", "__tw-plugins.css");
|
|
244
|
+
import_node_fs.default.mkdirSync(import_node_path.default.dirname(outPath), { recursive: true });
|
|
245
|
+
import_node_fs.default.writeFileSync(outPath, pluginCss);
|
|
246
|
+
console.log("[tailwind-styled-v4] \u2713 Plugin CSS \u2192 public/__tw-plugins.css");
|
|
247
|
+
}
|
|
248
|
+
} catch (e) {
|
|
249
|
+
console.warn("[tailwind-styled-v4] Plugin CSS skipped:", e);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const { incremental = true, styleBuckets = true, incrementalVerbose = false } = opts;
|
|
253
|
+
if (incremental) {
|
|
254
|
+
try {
|
|
255
|
+
const { getIncrementalEngine, getBucketEngine } = require("@tailwind-styled/compiler");
|
|
256
|
+
const engine = getIncrementalEngine({ verbose: incrementalVerbose });
|
|
257
|
+
engine.buildEndSync();
|
|
258
|
+
const stats = engine.getStats();
|
|
259
|
+
console.log(
|
|
260
|
+
`[tailwind-styled-v4] \u2713 Incremental: ${stats.changedFiles}/${stats.totalFiles} files changed | +${stats.addedRules} -${stats.removedRules} rules | ${stats.buildTimeMs}ms`
|
|
261
|
+
);
|
|
262
|
+
if (styleBuckets) {
|
|
263
|
+
const buckets = getBucketEngine();
|
|
264
|
+
const allNodes = engine.getAllNodes();
|
|
265
|
+
for (const node of allNodes) buckets.add(node);
|
|
266
|
+
const css = buckets.emit();
|
|
267
|
+
const outPath = import_node_path.default.join(cwd, "public", "__tw-atomic.css");
|
|
268
|
+
import_node_fs.default.mkdirSync(import_node_path.default.dirname(outPath), { recursive: true });
|
|
269
|
+
import_node_fs.default.writeFileSync(outPath, css);
|
|
270
|
+
const bStats = buckets.stats();
|
|
271
|
+
console.log(
|
|
272
|
+
`[tailwind-styled-v4] \u2713 Bucket CSS \u2192 public/__tw-atomic.css | ${bStats.totalNodes} rules`
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
} catch (e) {
|
|
276
|
+
console.warn("[tailwind-styled-v4] Incremental engine flush skipped:", e);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (typeof nextConfig.generateBuildId === "function") return nextConfig.generateBuildId();
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
286
|
+
0 && (module.exports = {
|
|
287
|
+
withTailwindStyled
|
|
288
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { TwPlugin } from '@tailwind-styled/plugin';
|
|
2
|
+
import { NextConfig } from 'next';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* tailwind-styled-v4 — withTailwindStyled v3
|
|
6
|
+
*
|
|
7
|
+
* Next.js plugin dengan full v3 integration:
|
|
8
|
+
* - Plugin system
|
|
9
|
+
* - DevTools overlay
|
|
10
|
+
* - Static variant compilation
|
|
11
|
+
* - Dead style elimination
|
|
12
|
+
* - Route CSS bundling
|
|
13
|
+
* - React Compiler compat
|
|
14
|
+
* - Idempotency guard
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface TailwindStyledNextOptions {
|
|
18
|
+
mode?: "zero-runtime" | "runtime";
|
|
19
|
+
addDataAttr?: boolean;
|
|
20
|
+
scanDirs?: string[];
|
|
21
|
+
safelistOutput?: string;
|
|
22
|
+
autoClientBoundary?: boolean;
|
|
23
|
+
hoist?: boolean;
|
|
24
|
+
routeCss?: boolean;
|
|
25
|
+
routeCssDir?: string;
|
|
26
|
+
atomic?: boolean;
|
|
27
|
+
zeroConfig?: boolean;
|
|
28
|
+
/** v3: plugins array */
|
|
29
|
+
plugins?: TwPlugin[];
|
|
30
|
+
/** v3: DevTools overlay. Default: true in dev */
|
|
31
|
+
devtools?: boolean;
|
|
32
|
+
/** v3: pre-compile all variant combos. Default: true in prod */
|
|
33
|
+
staticVariants?: boolean;
|
|
34
|
+
/** v3: remove unused variant CSS at build. Default: true in prod */
|
|
35
|
+
deadStyleElimination?: boolean;
|
|
36
|
+
/** v4: incremental CSS compiler — only recompile changed files. Default: true */
|
|
37
|
+
incremental?: boolean;
|
|
38
|
+
/** v4: style bucket system — deterministic CSS ordering. Default: true */
|
|
39
|
+
styleBuckets?: boolean;
|
|
40
|
+
/** v4: verbose logging untuk incremental engine. Default: false */
|
|
41
|
+
incrementalVerbose?: boolean;
|
|
42
|
+
}
|
|
43
|
+
declare function withTailwindStyled(opts?: TailwindStyledNextOptions): (nextConfig?: NextConfig) => NextConfig;
|
|
44
|
+
|
|
45
|
+
export { type TailwindStyledNextOptions, withTailwindStyled };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { TwPlugin } from '@tailwind-styled/plugin';
|
|
2
|
+
import { NextConfig } from 'next';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* tailwind-styled-v4 — withTailwindStyled v3
|
|
6
|
+
*
|
|
7
|
+
* Next.js plugin dengan full v3 integration:
|
|
8
|
+
* - Plugin system
|
|
9
|
+
* - DevTools overlay
|
|
10
|
+
* - Static variant compilation
|
|
11
|
+
* - Dead style elimination
|
|
12
|
+
* - Route CSS bundling
|
|
13
|
+
* - React Compiler compat
|
|
14
|
+
* - Idempotency guard
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface TailwindStyledNextOptions {
|
|
18
|
+
mode?: "zero-runtime" | "runtime";
|
|
19
|
+
addDataAttr?: boolean;
|
|
20
|
+
scanDirs?: string[];
|
|
21
|
+
safelistOutput?: string;
|
|
22
|
+
autoClientBoundary?: boolean;
|
|
23
|
+
hoist?: boolean;
|
|
24
|
+
routeCss?: boolean;
|
|
25
|
+
routeCssDir?: string;
|
|
26
|
+
atomic?: boolean;
|
|
27
|
+
zeroConfig?: boolean;
|
|
28
|
+
/** v3: plugins array */
|
|
29
|
+
plugins?: TwPlugin[];
|
|
30
|
+
/** v3: DevTools overlay. Default: true in dev */
|
|
31
|
+
devtools?: boolean;
|
|
32
|
+
/** v3: pre-compile all variant combos. Default: true in prod */
|
|
33
|
+
staticVariants?: boolean;
|
|
34
|
+
/** v3: remove unused variant CSS at build. Default: true in prod */
|
|
35
|
+
deadStyleElimination?: boolean;
|
|
36
|
+
/** v4: incremental CSS compiler — only recompile changed files. Default: true */
|
|
37
|
+
incremental?: boolean;
|
|
38
|
+
/** v4: style bucket system — deterministic CSS ordering. Default: true */
|
|
39
|
+
styleBuckets?: boolean;
|
|
40
|
+
/** v4: verbose logging untuk incremental engine. Default: false */
|
|
41
|
+
incrementalVerbose?: boolean;
|
|
42
|
+
}
|
|
43
|
+
declare function withTailwindStyled(opts?: TailwindStyledNextOptions): (nextConfig?: NextConfig) => NextConfig;
|
|
44
|
+
|
|
45
|
+
export { type TailwindStyledNextOptions, withTailwindStyled };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__require,
|
|
3
|
+
__spreadProps,
|
|
4
|
+
__spreadValues
|
|
5
|
+
} from "./chunk-QYSYW6TK.js";
|
|
6
|
+
|
|
7
|
+
// src/withTailwindStyled.ts
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
var LOADER_PATH = __require.resolve("./turbopackLoader");
|
|
11
|
+
var WEBPACK_LOADER_PATH = __require.resolve("./webpackLoader");
|
|
12
|
+
function withTailwindStyled(opts = {}) {
|
|
13
|
+
return (nextConfig = {}) => {
|
|
14
|
+
var _a, _b, _c;
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
17
|
+
const hasReactCompiler = nextConfig.reactCompiler === true || ((_a = nextConfig.experimental) == null ? void 0 : _a.reactCompiler) === true;
|
|
18
|
+
if (hasReactCompiler && isDev) {
|
|
19
|
+
console.log("[tailwind-styled-v4] React Compiler detected \u2192 hoist disabled");
|
|
20
|
+
}
|
|
21
|
+
const {
|
|
22
|
+
scanDirs = ["src"],
|
|
23
|
+
safelistOutput = "src/app/__tw-safelist.css",
|
|
24
|
+
autoClientBoundary = true,
|
|
25
|
+
hoist = !hasReactCompiler,
|
|
26
|
+
atomic = false,
|
|
27
|
+
routeCssDir = path.join(cwd, ".next", "static", "css", "tw"),
|
|
28
|
+
zeroConfig = true,
|
|
29
|
+
plugins = [],
|
|
30
|
+
devtools = isDev,
|
|
31
|
+
staticVariants = !isDev,
|
|
32
|
+
deadStyleElimination = !isDev
|
|
33
|
+
} = opts;
|
|
34
|
+
const routeCss = opts.routeCss !== void 0 ? opts.routeCss : !isDev;
|
|
35
|
+
if (zeroConfig) {
|
|
36
|
+
try {
|
|
37
|
+
const { bootstrapZeroConfig } = __require("@tailwind-styled/compiler");
|
|
38
|
+
bootstrapZeroConfig(cwd);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const safelistAbsPath = path.isAbsolute(safelistOutput) ? safelistOutput : path.resolve(cwd, safelistOutput);
|
|
43
|
+
if (!fs.existsSync(safelistAbsPath)) {
|
|
44
|
+
try {
|
|
45
|
+
fs.mkdirSync(path.dirname(safelistAbsPath), { recursive: true });
|
|
46
|
+
fs.writeFileSync(
|
|
47
|
+
safelistAbsPath,
|
|
48
|
+
"/* Auto-generated by tailwind-styled-v4 \u2014 DO NOT EDIT */\n"
|
|
49
|
+
);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (plugins.length > 0) {
|
|
54
|
+
try {
|
|
55
|
+
const { use } = __require("@tailwind-styled/plugin");
|
|
56
|
+
for (const plugin of plugins) use(plugin);
|
|
57
|
+
console.log(
|
|
58
|
+
`[tailwind-styled-v4] ${plugins.length} plugin(s): ${plugins.map((p) => p.name).join(", ")}`
|
|
59
|
+
);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
console.warn("[tailwind-styled-v4] Plugin init failed:", e);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const loaderOpts = {
|
|
65
|
+
mode: opts.mode,
|
|
66
|
+
addDataAttr: (_b = opts.addDataAttr) != null ? _b : isDev,
|
|
67
|
+
autoClientBoundary,
|
|
68
|
+
hoist,
|
|
69
|
+
atomic,
|
|
70
|
+
routeCss,
|
|
71
|
+
staticVariants
|
|
72
|
+
};
|
|
73
|
+
return __spreadProps(__spreadValues({}, nextConfig), {
|
|
74
|
+
experimental: __spreadValues({}, nextConfig.experimental),
|
|
75
|
+
// Next.js 16+: turbopack moved to top-level
|
|
76
|
+
// FIX TURBOPACK: pattern "*.{tsx,ts,jsx,js}" terlalu lebar — ikut match
|
|
77
|
+
// node_modules/next/dist/client/*.js.tsx dan trigger "Missing module type".
|
|
78
|
+
// Solusi: scope pattern ke scanDirs saja, jangan catch-all.
|
|
79
|
+
// `as` field dihapus — tidak perlu karena loader output tetap TSX-compatible.
|
|
80
|
+
turbopack: __spreadProps(__spreadValues({}, nextConfig.turbopack), {
|
|
81
|
+
rules: __spreadValues(__spreadValues({}, Object.fromEntries(
|
|
82
|
+
scanDirs.flatMap((dir) => [
|
|
83
|
+
[
|
|
84
|
+
`{./${dir},./src,./app,./pages,./components}/**/*.tsx`,
|
|
85
|
+
{
|
|
86
|
+
loaders: [{ loader: LOADER_PATH, options: loaderOpts }]
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
`{./${dir},./src,./app,./pages,./components}/**/*.ts`,
|
|
91
|
+
{
|
|
92
|
+
loaders: [{ loader: LOADER_PATH, options: loaderOpts }]
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
])
|
|
96
|
+
)), (_c = nextConfig.turbopack) == null ? void 0 : _c.rules)
|
|
97
|
+
}),
|
|
98
|
+
webpack(webpackConfig, webpackOpts) {
|
|
99
|
+
var _a2, _b2, _c2, _d;
|
|
100
|
+
const alreadyRegistered = webpackConfig.module.rules.some(
|
|
101
|
+
(r) => r._tailwindStyledMarker === true
|
|
102
|
+
);
|
|
103
|
+
if (!alreadyRegistered) {
|
|
104
|
+
webpackConfig.module.rules.push({
|
|
105
|
+
_tailwindStyledMarker: true,
|
|
106
|
+
test: /\.(tsx|ts|jsx|js)$/,
|
|
107
|
+
exclude: /node_modules/,
|
|
108
|
+
use: [
|
|
109
|
+
{
|
|
110
|
+
loader: WEBPACK_LOADER_PATH,
|
|
111
|
+
options: __spreadProps(__spreadValues({}, loaderOpts), {
|
|
112
|
+
mode: (_a2 = opts.mode) != null ? _a2 : webpackOpts.dev ? "runtime" : "zero-runtime",
|
|
113
|
+
addDataAttr: (_b2 = opts.addDataAttr) != null ? _b2 : webpackOpts.dev
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (devtools && webpackOpts.dev) {
|
|
120
|
+
webpackConfig.resolve = (_c2 = webpackConfig.resolve) != null ? _c2 : {};
|
|
121
|
+
webpackConfig.resolve.alias = __spreadProps(__spreadValues({}, (_d = webpackConfig.resolve.alias) != null ? _d : {}), {
|
|
122
|
+
"tailwind-styled-v4/devtools": path.resolve(__dirname, "../../devtools/src/index.tsx")
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return typeof nextConfig.webpack === "function" ? nextConfig.webpack(webpackConfig, webpackOpts) : webpackConfig;
|
|
126
|
+
},
|
|
127
|
+
generateBuildId: async () => {
|
|
128
|
+
try {
|
|
129
|
+
const { generateSafelistCss } = __require("@tailwind-styled/compiler");
|
|
130
|
+
generateSafelistCss(
|
|
131
|
+
scanDirs.map((d) => path.resolve(cwd, d)),
|
|
132
|
+
path.isAbsolute(safelistOutput) ? safelistOutput : path.resolve(cwd, safelistOutput)
|
|
133
|
+
);
|
|
134
|
+
console.log("[tailwind-styled-v4] \u2713 Safelist CSS generated");
|
|
135
|
+
} catch (e) {
|
|
136
|
+
console.warn("[tailwind-styled-v4] Safelist skipped:", e);
|
|
137
|
+
}
|
|
138
|
+
if (plugins.length > 0) {
|
|
139
|
+
try {
|
|
140
|
+
const { getGlobalRegistry, runBuildHooks } = __require("@tailwind-styled/plugin");
|
|
141
|
+
await runBuildHooks(getGlobalRegistry());
|
|
142
|
+
console.log("[tailwind-styled-v4] \u2713 Plugin build hooks complete");
|
|
143
|
+
} catch (e) {
|
|
144
|
+
console.warn("[tailwind-styled-v4] Plugin build hooks failed:", e);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (routeCss) {
|
|
148
|
+
try {
|
|
149
|
+
const {
|
|
150
|
+
generateAllRouteCss,
|
|
151
|
+
getCollectorSummary,
|
|
152
|
+
runElimination
|
|
153
|
+
} = __require("@tailwind-styled/compiler");
|
|
154
|
+
const results = await generateAllRouteCss({ cwd, outputDir: routeCssDir, minify: true });
|
|
155
|
+
console.log(getCollectorSummary());
|
|
156
|
+
if (deadStyleElimination) {
|
|
157
|
+
let totalSaved = 0;
|
|
158
|
+
for (const result of results) {
|
|
159
|
+
const routeFile = path.join(
|
|
160
|
+
routeCssDir,
|
|
161
|
+
result.route === "/" ? "index.css" : `${result.route.replace(/\//g, "_")}.css`
|
|
162
|
+
);
|
|
163
|
+
if (fs.existsSync(routeFile)) {
|
|
164
|
+
const inputCss = fs.readFileSync(routeFile, "utf-8");
|
|
165
|
+
const { css, report } = runElimination({ dirs: scanDirs, cwd, inputCss });
|
|
166
|
+
fs.writeFileSync(routeFile, css);
|
|
167
|
+
totalSaved += report.bytesSaved;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (totalSaved > 0) {
|
|
171
|
+
console.log(
|
|
172
|
+
`[tailwind-styled-v4] \u2713 Dead styles eliminated: ~${(totalSaved / 1024).toFixed(1)}KB saved`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const totalKb = results.reduce((s, r) => s + r.sizeBytes, 0) / 1024;
|
|
177
|
+
console.log(
|
|
178
|
+
`[tailwind-styled-v4] \u2713 Route CSS: ${results.length} routes, ${totalKb.toFixed(1)}KB`
|
|
179
|
+
);
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.warn("[tailwind-styled-v4] Route CSS skipped:", e);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (plugins.length > 0) {
|
|
185
|
+
try {
|
|
186
|
+
const {
|
|
187
|
+
getGlobalRegistry,
|
|
188
|
+
generateTokenCss,
|
|
189
|
+
generateUtilityCss,
|
|
190
|
+
applyCssHooks
|
|
191
|
+
} = __require("@tailwind-styled/plugin");
|
|
192
|
+
const registry = getGlobalRegistry();
|
|
193
|
+
let pluginCss = [generateTokenCss(registry), generateUtilityCss(registry)].filter(Boolean).join("\n\n");
|
|
194
|
+
pluginCss = applyCssHooks(pluginCss, registry);
|
|
195
|
+
if (pluginCss.trim()) {
|
|
196
|
+
const outPath = path.join(cwd, "public", "__tw-plugins.css");
|
|
197
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
198
|
+
fs.writeFileSync(outPath, pluginCss);
|
|
199
|
+
console.log("[tailwind-styled-v4] \u2713 Plugin CSS \u2192 public/__tw-plugins.css");
|
|
200
|
+
}
|
|
201
|
+
} catch (e) {
|
|
202
|
+
console.warn("[tailwind-styled-v4] Plugin CSS skipped:", e);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const { incremental = true, styleBuckets = true, incrementalVerbose = false } = opts;
|
|
206
|
+
if (incremental) {
|
|
207
|
+
try {
|
|
208
|
+
const { getIncrementalEngine, getBucketEngine } = __require("@tailwind-styled/compiler");
|
|
209
|
+
const engine = getIncrementalEngine({ verbose: incrementalVerbose });
|
|
210
|
+
engine.buildEndSync();
|
|
211
|
+
const stats = engine.getStats();
|
|
212
|
+
console.log(
|
|
213
|
+
`[tailwind-styled-v4] \u2713 Incremental: ${stats.changedFiles}/${stats.totalFiles} files changed | +${stats.addedRules} -${stats.removedRules} rules | ${stats.buildTimeMs}ms`
|
|
214
|
+
);
|
|
215
|
+
if (styleBuckets) {
|
|
216
|
+
const buckets = getBucketEngine();
|
|
217
|
+
const allNodes = engine.getAllNodes();
|
|
218
|
+
for (const node of allNodes) buckets.add(node);
|
|
219
|
+
const css = buckets.emit();
|
|
220
|
+
const outPath = path.join(cwd, "public", "__tw-atomic.css");
|
|
221
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
222
|
+
fs.writeFileSync(outPath, css);
|
|
223
|
+
const bStats = buckets.stats();
|
|
224
|
+
console.log(
|
|
225
|
+
`[tailwind-styled-v4] \u2713 Bucket CSS \u2192 public/__tw-atomic.css | ${bStats.totalNodes} rules`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
} catch (e) {
|
|
229
|
+
console.warn("[tailwind-styled-v4] Incremental engine flush skipped:", e);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (typeof nextConfig.generateBuildId === "function") return nextConfig.generateBuildId();
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
export {
|
|
239
|
+
withTailwindStyled
|
|
240
|
+
};
|