tailwind-to-style 2.8.6 → 2.8.8
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.browser.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/lib/twsx-cli.js +52 -19
- package/package.json +1 -1
- package/plugins/vite-twsx.js +56 -13
- package/plugins/webpack-twsx.js +20 -5
package/dist/index.browser.js
CHANGED
package/dist/index.cjs
CHANGED
package/dist/index.esm.js
CHANGED
package/lib/twsx-cli.js
CHANGED
|
@@ -24,6 +24,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
24
24
|
const generatedCssFiles = [];
|
|
25
25
|
|
|
26
26
|
// Generate CSS from JS files
|
|
27
|
+
let cssWrittenCount = 0;
|
|
27
28
|
for (const filePath of twsxFiles) {
|
|
28
29
|
try {
|
|
29
30
|
const styleModule = await import(
|
|
@@ -32,7 +33,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
32
33
|
const styleObj = styleModule.default || styleModule;
|
|
33
34
|
const css = twsx(styleObj, { inject: false });
|
|
34
35
|
const fileName = path.basename(filePath).replace(/\.js$/, ".css");
|
|
35
|
-
|
|
36
|
+
|
|
36
37
|
let cssFilePath;
|
|
37
38
|
if (preserveStructure) {
|
|
38
39
|
// Generate CSS in the same directory as the JS file
|
|
@@ -41,10 +42,10 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
41
42
|
// Generate CSS in the output directory
|
|
42
43
|
cssFilePath = path.join(outputDir, fileName);
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
fs.writeFileSync(cssFilePath, css);
|
|
46
47
|
generatedCssFiles.push(preserveStructure ? cssFilePath : fileName);
|
|
47
|
-
|
|
48
|
+
cssWrittenCount++;
|
|
48
49
|
} catch (err) {
|
|
49
50
|
console.error(
|
|
50
51
|
`[twsx-cli] Error importing or processing ${filePath}:`,
|
|
@@ -52,6 +53,16 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
52
53
|
);
|
|
53
54
|
}
|
|
54
55
|
}
|
|
56
|
+
if (cssWrittenCount > 0) {
|
|
57
|
+
const green = "\x1b[32m";
|
|
58
|
+
const reset = "\x1b[0m";
|
|
59
|
+
const check = green + "✔" + reset;
|
|
60
|
+
const now = new Date();
|
|
61
|
+
const time = now.toLocaleTimeString();
|
|
62
|
+
console.log(
|
|
63
|
+
`[twsx-cli] ${check} CSS updated in ${cssWrittenCount} file(s) at ${time}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
55
66
|
|
|
56
67
|
// Clean up orphaned CSS files
|
|
57
68
|
if (!preserveStructure && fs.existsSync(outputDir)) {
|
|
@@ -69,12 +80,14 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
69
80
|
} else if (preserveStructure) {
|
|
70
81
|
// Clean up orphaned CSS files in preserve structure mode
|
|
71
82
|
const twsxFiles = findTwsxFiles(inputDir);
|
|
72
|
-
const expectedCssFiles = twsxFiles.map(file =>
|
|
73
|
-
|
|
83
|
+
const expectedCssFiles = twsxFiles.map((file) =>
|
|
84
|
+
file.replace(/\.js$/, ".css")
|
|
85
|
+
);
|
|
86
|
+
|
|
74
87
|
// Find and remove orphaned CSS files
|
|
75
88
|
function cleanupOrphanedCss(dir) {
|
|
76
89
|
if (!fs.existsSync(dir)) return;
|
|
77
|
-
|
|
90
|
+
|
|
78
91
|
const items = fs.readdirSync(dir);
|
|
79
92
|
for (const item of items) {
|
|
80
93
|
const fullPath = path.join(dir, item);
|
|
@@ -89,7 +102,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
89
102
|
}
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
|
-
|
|
105
|
+
|
|
93
106
|
cleanupOrphanedCss(inputDir);
|
|
94
107
|
}
|
|
95
108
|
} catch (err) {
|
|
@@ -101,8 +114,11 @@ const inputDir =
|
|
|
101
114
|
process.env.TWSX_INPUT_DIR || path.resolve(process.cwd(), "src");
|
|
102
115
|
const outputDir =
|
|
103
116
|
process.env.TWSX_OUTPUT_DIR || path.resolve(process.cwd(), "src/styles");
|
|
104
|
-
const watchMode =
|
|
105
|
-
|
|
117
|
+
const watchMode =
|
|
118
|
+
process.argv.includes("--watch") || process.env.TWSX_WATCH === "true";
|
|
119
|
+
const preserveStructure =
|
|
120
|
+
process.argv.includes("--preserve-structure") ||
|
|
121
|
+
process.env.TWSX_PRESERVE_STRUCTURE === "true";
|
|
106
122
|
|
|
107
123
|
if (!preserveStructure && !fs.existsSync(outputDir)) {
|
|
108
124
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
@@ -116,24 +132,41 @@ if (!preserveStructure && !fs.existsSync(outputDir)) {
|
|
|
116
132
|
|
|
117
133
|
if (watchMode) {
|
|
118
134
|
console.log(`[twsx-cli] Watching for changes in ${inputDir}...`);
|
|
119
|
-
|
|
135
|
+
|
|
120
136
|
const watcher = chokidar.watch(`${inputDir}/**/twsx.*.js`, {
|
|
121
137
|
ignored: /node_modules/,
|
|
122
138
|
persistent: true,
|
|
123
139
|
});
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
let changeTimeout = null;
|
|
142
|
+
let pendingChange = false;
|
|
143
|
+
function triggerBatchBuild() {
|
|
144
|
+
if (changeTimeout) clearTimeout(changeTimeout);
|
|
145
|
+
changeTimeout = setTimeout(async () => {
|
|
146
|
+
pendingChange = false;
|
|
147
|
+
const green = "\x1b[32m";
|
|
148
|
+
const reset = "\x1b[0m";
|
|
149
|
+
const check = green + "✔" + reset;
|
|
150
|
+
const now = new Date();
|
|
151
|
+
const time = now.toLocaleTimeString();
|
|
152
|
+
console.log(
|
|
153
|
+
`[twsx-cli] ${check} Detected changes, updating CSS at ${time}`
|
|
154
|
+
);
|
|
128
155
|
await buildTwsx(inputDir, outputDir, preserveStructure);
|
|
156
|
+
}, 100);
|
|
157
|
+
}
|
|
158
|
+
watcher
|
|
159
|
+
.on("change", () => {
|
|
160
|
+
pendingChange = true;
|
|
161
|
+
triggerBatchBuild();
|
|
129
162
|
})
|
|
130
|
-
.on("add",
|
|
131
|
-
|
|
132
|
-
|
|
163
|
+
.on("add", () => {
|
|
164
|
+
pendingChange = true;
|
|
165
|
+
triggerBatchBuild();
|
|
133
166
|
})
|
|
134
|
-
.on("unlink",
|
|
135
|
-
|
|
136
|
-
|
|
167
|
+
.on("unlink", () => {
|
|
168
|
+
pendingChange = true;
|
|
169
|
+
triggerBatchBuild();
|
|
137
170
|
});
|
|
138
171
|
|
|
139
172
|
// Keep the process alive
|
package/package.json
CHANGED
package/plugins/vite-twsx.js
CHANGED
|
@@ -23,6 +23,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
23
23
|
const generatedCssFiles = [];
|
|
24
24
|
|
|
25
25
|
// Generate CSS from JS files
|
|
26
|
+
let cssWrittenCount = 0;
|
|
26
27
|
for (const filePath of twsxFiles) {
|
|
27
28
|
try {
|
|
28
29
|
const styleModule = await import(
|
|
@@ -31,7 +32,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
31
32
|
const styleObj = styleModule.default || styleModule;
|
|
32
33
|
const css = twsx(styleObj, { inject: false });
|
|
33
34
|
const fileName = path.basename(filePath).replace(/\.js$/, ".css");
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
let cssFilePath;
|
|
36
37
|
if (preserveStructure) {
|
|
37
38
|
// Generate CSS file next to the JS file
|
|
@@ -40,15 +41,16 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
40
41
|
// Generate CSS file in the output directory
|
|
41
42
|
cssFilePath = path.join(outputDir, fileName);
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
// Ensure the directory exists
|
|
45
46
|
const cssDir = path.dirname(cssFilePath);
|
|
46
47
|
if (!fs.existsSync(cssDir)) {
|
|
47
48
|
fs.mkdirSync(cssDir, { recursive: true });
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
fs.writeFileSync(cssFilePath, css);
|
|
51
|
-
generatedCssFiles.push(
|
|
52
|
+
generatedCssFiles.push(cssFilePath);
|
|
53
|
+
cssWrittenCount++;
|
|
52
54
|
} catch (err) {
|
|
53
55
|
console.error(
|
|
54
56
|
`[vite-twsx] Error importing or processing ${filePath}:`,
|
|
@@ -56,6 +58,16 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
56
58
|
);
|
|
57
59
|
}
|
|
58
60
|
}
|
|
61
|
+
if (cssWrittenCount > 0) {
|
|
62
|
+
const green = "\x1b[32m";
|
|
63
|
+
const reset = "\x1b[0m";
|
|
64
|
+
const check = green + "✔" + reset;
|
|
65
|
+
const now = new Date();
|
|
66
|
+
const time = now.toLocaleTimeString();
|
|
67
|
+
console.log(
|
|
68
|
+
`[vite-twsx] ${check} CSS updated in ${cssWrittenCount} file(s) at ${time}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
59
71
|
|
|
60
72
|
// Clean up orphaned CSS files
|
|
61
73
|
if (preserveStructure) {
|
|
@@ -75,17 +87,19 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
75
87
|
.filter((file) => file.startsWith("twsx.") && file.endsWith(".css"));
|
|
76
88
|
|
|
77
89
|
for (const cssFile of existingCssFiles) {
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
const cssFilePath = path.join(outputDir, cssFile);
|
|
91
|
+
if (!generatedCssFiles.includes(cssFilePath)) {
|
|
80
92
|
fs.unlinkSync(cssFilePath);
|
|
81
93
|
}
|
|
82
94
|
}
|
|
83
95
|
}
|
|
84
96
|
}
|
|
97
|
+
|
|
98
|
+
return { generatedCssFiles };
|
|
85
99
|
} catch (err) {
|
|
86
100
|
console.error("[vite-twsx] Error scanning for twsx files:", err);
|
|
101
|
+
return { generatedCssFiles: [] };
|
|
87
102
|
}
|
|
88
|
-
return null;
|
|
89
103
|
}
|
|
90
104
|
|
|
91
105
|
export default function twsxPlugin(options = {}) {
|
|
@@ -94,6 +108,9 @@ export default function twsxPlugin(options = {}) {
|
|
|
94
108
|
options.outputDir || path.resolve(process.cwd(), "src/styles");
|
|
95
109
|
const preserveStructure = options.preserveStructure || false;
|
|
96
110
|
|
|
111
|
+
// Keep track of generated files to avoid triggering on our own changes
|
|
112
|
+
const generatedFiles = new Set();
|
|
113
|
+
|
|
97
114
|
if (!preserveStructure && !fs.existsSync(outputDir)) {
|
|
98
115
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
99
116
|
}
|
|
@@ -102,16 +119,42 @@ export default function twsxPlugin(options = {}) {
|
|
|
102
119
|
name: "vite-twsx",
|
|
103
120
|
async buildStart() {
|
|
104
121
|
try {
|
|
105
|
-
await buildTwsx(inputDir, outputDir, preserveStructure);
|
|
122
|
+
const result = await buildTwsx(inputDir, outputDir, preserveStructure);
|
|
123
|
+
// Track generated CSS files
|
|
124
|
+
if (result && result.generatedCssFiles) {
|
|
125
|
+
result.generatedCssFiles.forEach((file) => generatedFiles.add(file));
|
|
126
|
+
}
|
|
106
127
|
} catch (err) {
|
|
107
128
|
console.error("[vite-twsx] Error writing CSS:", err);
|
|
108
129
|
}
|
|
109
130
|
},
|
|
110
|
-
async handleHotUpdate() {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
async handleHotUpdate({ file, server }) {
|
|
132
|
+
// Skip if this is a CSS file we generated
|
|
133
|
+
if (generatedFiles.has(file)) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Only process .js files that start with "twsx."
|
|
138
|
+
if (file.endsWith(".js") && path.basename(file).startsWith("twsx.")) {
|
|
139
|
+
try {
|
|
140
|
+
const result = await buildTwsx(
|
|
141
|
+
inputDir,
|
|
142
|
+
outputDir,
|
|
143
|
+
preserveStructure
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// Update our tracking of generated files
|
|
147
|
+
if (result && result.generatedCssFiles) {
|
|
148
|
+
generatedFiles.clear();
|
|
149
|
+
result.generatedCssFiles.forEach((f) => generatedFiles.add(f));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Return empty array to prevent default HMR handling
|
|
153
|
+
return [];
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error("[vite-twsx] Error updating CSS:", err);
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
115
158
|
}
|
|
116
159
|
},
|
|
117
160
|
};
|
package/plugins/webpack-twsx.js
CHANGED
|
@@ -23,6 +23,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
23
23
|
const generatedCssFiles = [];
|
|
24
24
|
|
|
25
25
|
// Generate CSS from JS files
|
|
26
|
+
let cssWrittenCount = 0;
|
|
26
27
|
for (const filePath of twsxFiles) {
|
|
27
28
|
try {
|
|
28
29
|
const styleModule = await import(
|
|
@@ -31,7 +32,7 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
31
32
|
const styleObj = styleModule.default || styleModule;
|
|
32
33
|
const css = twsx(styleObj, { inject: false });
|
|
33
34
|
const fileName = path.basename(filePath).replace(/\.js$/, ".css");
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
let cssFilePath;
|
|
36
37
|
if (preserveStructure) {
|
|
37
38
|
// Generate CSS file next to the JS file
|
|
@@ -40,15 +41,16 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
40
41
|
// Generate CSS file in the output directory
|
|
41
42
|
cssFilePath = path.join(outputDir, fileName);
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
// Ensure the directory exists
|
|
45
46
|
const cssDir = path.dirname(cssFilePath);
|
|
46
47
|
if (!fs.existsSync(cssDir)) {
|
|
47
48
|
fs.mkdirSync(cssDir, { recursive: true });
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
fs.writeFileSync(cssFilePath, css);
|
|
51
52
|
generatedCssFiles.push(preserveStructure ? cssFilePath : fileName);
|
|
53
|
+
cssWrittenCount++;
|
|
52
54
|
} catch (err) {
|
|
53
55
|
console.error(
|
|
54
56
|
`[webpack-twsx] Error importing or processing ${filePath}:`,
|
|
@@ -56,6 +58,16 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
56
58
|
);
|
|
57
59
|
}
|
|
58
60
|
}
|
|
61
|
+
if (cssWrittenCount > 0) {
|
|
62
|
+
const green = "\x1b[32m";
|
|
63
|
+
const reset = "\x1b[0m";
|
|
64
|
+
const check = green + "✔" + reset;
|
|
65
|
+
const now = new Date();
|
|
66
|
+
const time = now.toLocaleTimeString();
|
|
67
|
+
console.log(
|
|
68
|
+
`[webpack-twsx] ${check} CSS updated in ${cssWrittenCount} file(s) at ${time}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
59
71
|
|
|
60
72
|
// Clean up orphaned CSS files
|
|
61
73
|
if (preserveStructure) {
|
|
@@ -74,7 +86,10 @@ async function buildTwsx(inputDir, outputDir, preserveStructure = false) {
|
|
|
74
86
|
return file.startsWith("twsx.") && file.endsWith(".css");
|
|
75
87
|
});
|
|
76
88
|
|
|
77
|
-
if (
|
|
89
|
+
if (
|
|
90
|
+
Array.isArray(existingCssFiles) &&
|
|
91
|
+
Array.isArray(generatedCssFiles)
|
|
92
|
+
) {
|
|
78
93
|
for (const cssFile of existingCssFiles) {
|
|
79
94
|
if (!generatedCssFiles.includes(cssFile)) {
|
|
80
95
|
const cssFilePath = path.join(outputDir, cssFile);
|
|
@@ -95,7 +110,7 @@ class TwsxPlugin {
|
|
|
95
110
|
this.outputDir =
|
|
96
111
|
options.outputDir || path.resolve(process.cwd(), "src/styles");
|
|
97
112
|
this.preserveStructure = options.preserveStructure || false;
|
|
98
|
-
|
|
113
|
+
|
|
99
114
|
if (!this.preserveStructure && !fs.existsSync(this.outputDir)) {
|
|
100
115
|
fs.mkdirSync(this.outputDir, { recursive: true });
|
|
101
116
|
}
|