tailwind-scramble 0.1.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/README.md +92 -0
- package/dist/postcss.cjs +35 -0
- package/dist/postcss.d.cts +5 -0
- package/dist/postcss.d.mts +6 -0
- package/dist/postcss.mjs +35 -0
- package/dist/utils-B3ZyiKiX.mjs +19 -0
- package/dist/utils-BHmeg0xb.cjs +71 -0
- package/dist/webpack.cjs +92 -0
- package/dist/webpack.d.cts +3 -0
- package/dist/webpack.d.mts +4 -0
- package/dist/webpack.mjs +92 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# `tailwind-scramble`
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/tailwind-scramble)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
Scramble your Tailwind CSS class names in production builds. Replaces readable class names like `flex items-center` with random short identifiers like `akzmqt xbfplo`, making your markup harder to reverse-engineer.
|
|
8
|
+
|
|
9
|
+
Works with Next.js (Webpack and Turbopack), and supports class utility functions like `cn()`, `clsx()`, `cva()`, and others.
|
|
10
|
+
|
|
11
|
+
## How it works
|
|
12
|
+
|
|
13
|
+
The package has two plugins that work together:
|
|
14
|
+
|
|
15
|
+
1. **Webpack Plugin**: A bundler loader that parses your JSX/TSX, finds class name strings (in `className` attributes and utility function calls), and replaces each class with a unique random identifier. It writes the mapping to a JSON file.
|
|
16
|
+
|
|
17
|
+
2. **PostCSS Plugin**: Reads the class mapping and rewrites the corresponding CSS selectors to match the scrambled names.
|
|
18
|
+
|
|
19
|
+
Both plugins share the mapping file, so the scrambled class names in your HTML and CSS always stay in sync.
|
|
20
|
+
|
|
21
|
+
### Supported class utilities
|
|
22
|
+
|
|
23
|
+
The Webpack plugin detects and rewrites strings inside these functions:
|
|
24
|
+
|
|
25
|
+
- `cn()`
|
|
26
|
+
- `clsx()`
|
|
27
|
+
- `cx()`
|
|
28
|
+
- `cva()`
|
|
29
|
+
- `classnames()`
|
|
30
|
+
- `twMerge()`
|
|
31
|
+
- `twJoin()`
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install tailwind-scramble
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Setup (Next.js)
|
|
40
|
+
|
|
41
|
+
It is recommended to only use this plugin during production builds to make development easier.
|
|
42
|
+
|
|
43
|
+
### Webpack
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// next.config.ts
|
|
47
|
+
import type { NextConfig } from "next";
|
|
48
|
+
|
|
49
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
50
|
+
|
|
51
|
+
const nextConfig: NextConfig = {
|
|
52
|
+
webpack(config) {
|
|
53
|
+
if (isProd) {
|
|
54
|
+
config.module?.rules?.unshift({
|
|
55
|
+
test: /\.(tsx|ts|jsx|js|mjs)$/,
|
|
56
|
+
exclude: /node_modules/,
|
|
57
|
+
enforce: "pre",
|
|
58
|
+
use: [
|
|
59
|
+
{
|
|
60
|
+
loader: require.resolve("tailwind-scramble/webpack"),
|
|
61
|
+
options: {},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return config;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default nextConfig;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### PostCSS
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
// postcss.config.mjs
|
|
78
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
79
|
+
|
|
80
|
+
const config = {
|
|
81
|
+
plugins: {
|
|
82
|
+
"@tailwindcss/postcss": {},
|
|
83
|
+
...(isProd && { "tailwind-scramble/postcss": {} }),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default config;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
package/dist/postcss.cjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const require_utils = require('./utils-BHmeg0xb.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/postcss-plugin.ts
|
|
4
|
+
function toTailwindSelector(className) {
|
|
5
|
+
return className.split("").map((ch) => {
|
|
6
|
+
if (/^[a-zA-Z0-9_-]$/.test(ch)) return ch;
|
|
7
|
+
return "\\" + ch;
|
|
8
|
+
}).join("");
|
|
9
|
+
}
|
|
10
|
+
const postcssPlugin = () => {
|
|
11
|
+
return {
|
|
12
|
+
postcssPlugin: "tailwind-scramble",
|
|
13
|
+
Once(root) {
|
|
14
|
+
console.log("[TailwindScramble] PostCSS Plugin Initialized");
|
|
15
|
+
const map = require_utils.readMap();
|
|
16
|
+
const keys = Object.keys(map);
|
|
17
|
+
if (keys.length === 0) return;
|
|
18
|
+
console.log("[TailwindScramble] Tailwind Keys:", keys.length);
|
|
19
|
+
root.walkRules((rule) => {
|
|
20
|
+
const original = rule.selector;
|
|
21
|
+
let rewritten = original;
|
|
22
|
+
for (const [orig, obf] of Object.entries(map)) {
|
|
23
|
+
const tw = "." + toTailwindSelector(orig);
|
|
24
|
+
const target = "." + obf;
|
|
25
|
+
if (rewritten === tw) rewritten = rewritten.split(tw).join(target);
|
|
26
|
+
}
|
|
27
|
+
if (rewritten !== original) rule.selector = rewritten;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
postcssPlugin.postcss = true;
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
module.exports = postcssPlugin;
|
package/dist/postcss.mjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { n as readMap } from "./utils-B3ZyiKiX.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/postcss-plugin.ts
|
|
4
|
+
function toTailwindSelector(className) {
|
|
5
|
+
return className.split("").map((ch) => {
|
|
6
|
+
if (/^[a-zA-Z0-9_-]$/.test(ch)) return ch;
|
|
7
|
+
return "\\" + ch;
|
|
8
|
+
}).join("");
|
|
9
|
+
}
|
|
10
|
+
const postcssPlugin = () => {
|
|
11
|
+
return {
|
|
12
|
+
postcssPlugin: "tailwind-scramble",
|
|
13
|
+
Once(root) {
|
|
14
|
+
console.log("[TailwindScramble] PostCSS Plugin Initialized");
|
|
15
|
+
const map = readMap();
|
|
16
|
+
const keys = Object.keys(map);
|
|
17
|
+
if (keys.length === 0) return;
|
|
18
|
+
console.log("[TailwindScramble] Tailwind Keys:", keys.length);
|
|
19
|
+
root.walkRules((rule) => {
|
|
20
|
+
const original = rule.selector;
|
|
21
|
+
let rewritten = original;
|
|
22
|
+
for (const [orig, obf] of Object.entries(map)) {
|
|
23
|
+
const tw = "." + toTailwindSelector(orig);
|
|
24
|
+
const target = "." + obf;
|
|
25
|
+
if (rewritten === tw) rewritten = rewritten.split(tw).join(target);
|
|
26
|
+
}
|
|
27
|
+
if (rewritten !== original) rule.selector = rewritten;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
postcssPlugin.postcss = true;
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { postcssPlugin as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { customAlphabet } from "nanoid";
|
|
4
|
+
|
|
5
|
+
//#region src/common/utils.ts
|
|
6
|
+
const nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 6);
|
|
7
|
+
const MAP_FILE = path.join(process.cwd(), ".next/tailwind-scramble-map.json");
|
|
8
|
+
function writeMap(classMap) {
|
|
9
|
+
const obj = Object.fromEntries(classMap);
|
|
10
|
+
fs.mkdirSync(path.dirname(MAP_FILE), { recursive: true });
|
|
11
|
+
fs.writeFileSync(MAP_FILE, JSON.stringify(obj, null, 2));
|
|
12
|
+
}
|
|
13
|
+
function readMap() {
|
|
14
|
+
if (!fs.existsSync(MAP_FILE)) return {};
|
|
15
|
+
return JSON.parse(fs.readFileSync(MAP_FILE, "utf8"));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { readMap as n, writeMap as r, nanoid as t };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
let fs = require("fs");
|
|
29
|
+
fs = __toESM(fs);
|
|
30
|
+
let path = require("path");
|
|
31
|
+
path = __toESM(path);
|
|
32
|
+
let nanoid = require("nanoid");
|
|
33
|
+
|
|
34
|
+
//#region src/common/utils.ts
|
|
35
|
+
const nanoid$1 = (0, nanoid.customAlphabet)("abcdefghijklmnopqrstuvwxyz", 6);
|
|
36
|
+
const MAP_FILE = path.default.join(process.cwd(), ".next/tailwind-scramble-map.json");
|
|
37
|
+
function writeMap(classMap) {
|
|
38
|
+
const obj = Object.fromEntries(classMap);
|
|
39
|
+
fs.default.mkdirSync(path.default.dirname(MAP_FILE), { recursive: true });
|
|
40
|
+
fs.default.writeFileSync(MAP_FILE, JSON.stringify(obj, null, 2));
|
|
41
|
+
}
|
|
42
|
+
function readMap() {
|
|
43
|
+
if (!fs.default.existsSync(MAP_FILE)) return {};
|
|
44
|
+
return JSON.parse(fs.default.readFileSync(MAP_FILE, "utf8"));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
Object.defineProperty(exports, '__toESM', {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return __toESM;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, 'nanoid', {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return nanoid$1;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, 'readMap', {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return readMap;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, 'writeMap', {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return writeMap;
|
|
70
|
+
}
|
|
71
|
+
});
|
package/dist/webpack.cjs
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const require_utils = require('./utils-BHmeg0xb.cjs');
|
|
2
|
+
let _swc_core = require("@swc/core");
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/webpack-plugin.ts
|
|
5
|
+
const classMap = /* @__PURE__ */ new Map();
|
|
6
|
+
const CLASS_FUNCTIONS = new Set([
|
|
7
|
+
"cn",
|
|
8
|
+
"cva",
|
|
9
|
+
"clsx",
|
|
10
|
+
"cx",
|
|
11
|
+
"twMerge",
|
|
12
|
+
"twJoin",
|
|
13
|
+
"classnames"
|
|
14
|
+
]);
|
|
15
|
+
function get(cls) {
|
|
16
|
+
if (!classMap.has(cls)) classMap.set(cls, require_utils.nanoid());
|
|
17
|
+
return classMap.get(cls);
|
|
18
|
+
}
|
|
19
|
+
function rewriteString(value) {
|
|
20
|
+
return value.split(/\s+/).map(get).join(" ");
|
|
21
|
+
}
|
|
22
|
+
function rewriteStringLiteral(node) {
|
|
23
|
+
const newValue = rewriteString(node.value);
|
|
24
|
+
node.value = newValue;
|
|
25
|
+
node.raw = JSON.stringify(newValue);
|
|
26
|
+
}
|
|
27
|
+
function isClassFunction(node) {
|
|
28
|
+
if (node.type !== "CallExpression") return false;
|
|
29
|
+
const callee = node.callee;
|
|
30
|
+
if (callee?.type === "Identifier") return CLASS_FUNCTIONS.has(callee.value);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
function rewriteStringsDeep(node) {
|
|
34
|
+
if (!node || typeof node !== "object") return;
|
|
35
|
+
if (node.type === "StringLiteral") {
|
|
36
|
+
rewriteStringLiteral(node);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (node.type === "TemplateLiteral") {
|
|
40
|
+
for (const quasi of node.quasis ?? []) if (quasi.raw) {
|
|
41
|
+
const rewritten = rewriteString(quasi.raw);
|
|
42
|
+
quasi.raw = rewritten;
|
|
43
|
+
quasi.cooked = rewritten;
|
|
44
|
+
}
|
|
45
|
+
for (const expr of node.expressions ?? []) rewriteStringsDeep(expr);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (node.type === "KeyValueProperty") {
|
|
49
|
+
rewriteStringsDeep(node.value);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(node)) {
|
|
53
|
+
node.forEach(rewriteStringsDeep);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
for (const key in node) {
|
|
57
|
+
const child = node[key];
|
|
58
|
+
if (child && typeof child === "object") rewriteStringsDeep(child);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function bundlerPlugin(source) {
|
|
62
|
+
console.log("[TailwindScramble] Webpack Plugin Initialized");
|
|
63
|
+
const ast = (0, _swc_core.parseSync)(source, {
|
|
64
|
+
syntax: "typescript",
|
|
65
|
+
tsx: true,
|
|
66
|
+
decorators: false
|
|
67
|
+
});
|
|
68
|
+
function walk(node) {
|
|
69
|
+
if (!node || typeof node !== "object") return;
|
|
70
|
+
if (node.type === "JSXAttribute" && node.name?.type === "Identifier" && node.name.value === "className") {
|
|
71
|
+
const v = node.value;
|
|
72
|
+
if (v?.type === "StringLiteral") rewriteStringLiteral(v);
|
|
73
|
+
if (v?.type === "JSXExpressionContainer") walk(v.expression);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (isClassFunction(node)) {
|
|
77
|
+
rewriteStringsDeep(node.arguments);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
for (const key in node) {
|
|
81
|
+
const child = node[key];
|
|
82
|
+
if (Array.isArray(child)) child.forEach(walk);
|
|
83
|
+
else if (child && typeof child === "object") walk(child);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
walk(ast);
|
|
87
|
+
require_utils.writeMap(classMap);
|
|
88
|
+
return (0, _swc_core.printSync)(ast).code;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
module.exports = bundlerPlugin;
|
package/dist/webpack.mjs
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { r as writeMap, t as nanoid } from "./utils-B3ZyiKiX.mjs";
|
|
2
|
+
import { parseSync, printSync } from "@swc/core";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/webpack-plugin.ts
|
|
5
|
+
const classMap = /* @__PURE__ */ new Map();
|
|
6
|
+
const CLASS_FUNCTIONS = new Set([
|
|
7
|
+
"cn",
|
|
8
|
+
"cva",
|
|
9
|
+
"clsx",
|
|
10
|
+
"cx",
|
|
11
|
+
"twMerge",
|
|
12
|
+
"twJoin",
|
|
13
|
+
"classnames"
|
|
14
|
+
]);
|
|
15
|
+
function get(cls) {
|
|
16
|
+
if (!classMap.has(cls)) classMap.set(cls, nanoid());
|
|
17
|
+
return classMap.get(cls);
|
|
18
|
+
}
|
|
19
|
+
function rewriteString(value) {
|
|
20
|
+
return value.split(/\s+/).map(get).join(" ");
|
|
21
|
+
}
|
|
22
|
+
function rewriteStringLiteral(node) {
|
|
23
|
+
const newValue = rewriteString(node.value);
|
|
24
|
+
node.value = newValue;
|
|
25
|
+
node.raw = JSON.stringify(newValue);
|
|
26
|
+
}
|
|
27
|
+
function isClassFunction(node) {
|
|
28
|
+
if (node.type !== "CallExpression") return false;
|
|
29
|
+
const callee = node.callee;
|
|
30
|
+
if (callee?.type === "Identifier") return CLASS_FUNCTIONS.has(callee.value);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
function rewriteStringsDeep(node) {
|
|
34
|
+
if (!node || typeof node !== "object") return;
|
|
35
|
+
if (node.type === "StringLiteral") {
|
|
36
|
+
rewriteStringLiteral(node);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (node.type === "TemplateLiteral") {
|
|
40
|
+
for (const quasi of node.quasis ?? []) if (quasi.raw) {
|
|
41
|
+
const rewritten = rewriteString(quasi.raw);
|
|
42
|
+
quasi.raw = rewritten;
|
|
43
|
+
quasi.cooked = rewritten;
|
|
44
|
+
}
|
|
45
|
+
for (const expr of node.expressions ?? []) rewriteStringsDeep(expr);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (node.type === "KeyValueProperty") {
|
|
49
|
+
rewriteStringsDeep(node.value);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(node)) {
|
|
53
|
+
node.forEach(rewriteStringsDeep);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
for (const key in node) {
|
|
57
|
+
const child = node[key];
|
|
58
|
+
if (child && typeof child === "object") rewriteStringsDeep(child);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function bundlerPlugin(source) {
|
|
62
|
+
console.log("[TailwindScramble] Webpack Plugin Initialized");
|
|
63
|
+
const ast = parseSync(source, {
|
|
64
|
+
syntax: "typescript",
|
|
65
|
+
tsx: true,
|
|
66
|
+
decorators: false
|
|
67
|
+
});
|
|
68
|
+
function walk(node) {
|
|
69
|
+
if (!node || typeof node !== "object") return;
|
|
70
|
+
if (node.type === "JSXAttribute" && node.name?.type === "Identifier" && node.name.value === "className") {
|
|
71
|
+
const v = node.value;
|
|
72
|
+
if (v?.type === "StringLiteral") rewriteStringLiteral(v);
|
|
73
|
+
if (v?.type === "JSXExpressionContainer") walk(v.expression);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (isClassFunction(node)) {
|
|
77
|
+
rewriteStringsDeep(node.arguments);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
for (const key in node) {
|
|
81
|
+
const child = node[key];
|
|
82
|
+
if (Array.isArray(child)) child.forEach(walk);
|
|
83
|
+
else if (child && typeof child === "object") walk(child);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
walk(ast);
|
|
87
|
+
writeMap(classMap);
|
|
88
|
+
return printSync(ast).code;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { bundlerPlugin as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tailwind-scramble",
|
|
3
|
+
"description": "Bundler plugin to scramble Tailwind Classes",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/akshatmittal/tailwind-scramble.git"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./webpack": {
|
|
21
|
+
"import": "./dist/webpack-plugin.mjs",
|
|
22
|
+
"require": "./dist/webpack-plugin.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./postcss": {
|
|
25
|
+
"import": "./dist/postcss-plugin.mjs",
|
|
26
|
+
"require": "./dist/postcss-plugin.cjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
31
|
+
"@changesets/cli": "^2.29.8",
|
|
32
|
+
"@changesets/config": "^3.1.2",
|
|
33
|
+
"@swc/core": "^1.15.17",
|
|
34
|
+
"nanoid": "^5.1.6"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^24.10.15",
|
|
38
|
+
"eslint": "^9.39.3",
|
|
39
|
+
"tsdown": "^0.21.0-beta.2",
|
|
40
|
+
"typescript": "^5.9.2"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"postcss": "^8.5.6"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"tailwindcss",
|
|
50
|
+
"scramble",
|
|
51
|
+
"tailwind",
|
|
52
|
+
"shadcn",
|
|
53
|
+
"bundler"
|
|
54
|
+
],
|
|
55
|
+
"scripts": {
|
|
56
|
+
"lint": "eslint .",
|
|
57
|
+
"build": "tsdown",
|
|
58
|
+
"changeset": "changeset",
|
|
59
|
+
"version": "changeset version",
|
|
60
|
+
"release": "changeset publish"
|
|
61
|
+
}
|
|
62
|
+
}
|