@gustcss/vite 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/index.cjs +186 -0
- package/index.mjs +186 -0
- package/package.json +30 -0
package/index.cjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
const { execSync, spawn } = require('child_process')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @gustcss/vite - Vite plugin for CSS Utility Generator
|
|
7
|
+
*
|
|
8
|
+
* Usage in vite.config.ts:
|
|
9
|
+
* import gustcss from '@gustcss/vite'
|
|
10
|
+
* export default defineConfig({
|
|
11
|
+
* plugins: [gustcss({ output: 'src/styles/utility.css' })],
|
|
12
|
+
* })
|
|
13
|
+
*/
|
|
14
|
+
function cssUtility(opts = {}) {
|
|
15
|
+
const output = opts.output || 'src/styles/utility.css'
|
|
16
|
+
const content = opts.content || ['./src/**/*.{js,ts,jsx,tsx,astro,vue}']
|
|
17
|
+
const configPath = opts.config
|
|
18
|
+
let watchProcess = null
|
|
19
|
+
|
|
20
|
+
function findBinary(cwd) {
|
|
21
|
+
const possiblePaths = [
|
|
22
|
+
path.join(cwd, 'node_modules', '.bin', 'gustcss'),
|
|
23
|
+
path.join(cwd, '..', '..', 'bin', 'gustcss'), // For sample projects
|
|
24
|
+
'gustcss', // Global installation
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
for (const p of possiblePaths) {
|
|
28
|
+
if (p === 'gustcss' || fs.existsSync(p)) {
|
|
29
|
+
return p
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
throw new Error('gustcss binary not found')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function findConfigFile(cwd) {
|
|
37
|
+
if (configPath) {
|
|
38
|
+
return configPath
|
|
39
|
+
}
|
|
40
|
+
// Auto-detect config file in current directory
|
|
41
|
+
const defaultConfigPaths = [
|
|
42
|
+
'gustcss.config.json',
|
|
43
|
+
'gustcss.config.js',
|
|
44
|
+
]
|
|
45
|
+
for (const configName of defaultConfigPaths) {
|
|
46
|
+
const fullPath = path.join(cwd, configName)
|
|
47
|
+
if (fs.existsSync(fullPath)) {
|
|
48
|
+
return fullPath
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function buildArgs(cwd, extraArgs = []) {
|
|
55
|
+
const args = ['build', ...extraArgs]
|
|
56
|
+
const resolvedConfigPath = findConfigFile(cwd)
|
|
57
|
+
|
|
58
|
+
if (resolvedConfigPath) {
|
|
59
|
+
// Use existing config file
|
|
60
|
+
args.push('--config', resolvedConfigPath)
|
|
61
|
+
} else {
|
|
62
|
+
// Create temporary config file to avoid glob pattern issues with CLI
|
|
63
|
+
const tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
|
|
64
|
+
const tempConfig = { content, output }
|
|
65
|
+
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
|
|
66
|
+
args.push('--config', tempConfigPath)
|
|
67
|
+
// Note: temp file cleanup happens after build in buildCSS
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return args
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function buildCSS(cwd, binaryPath) {
|
|
74
|
+
const resolvedConfigPath = findConfigFile(cwd)
|
|
75
|
+
const args = ['build', '-o', output]
|
|
76
|
+
|
|
77
|
+
let tempConfigPath = null
|
|
78
|
+
if (resolvedConfigPath) {
|
|
79
|
+
args.push('--config', resolvedConfigPath)
|
|
80
|
+
} else {
|
|
81
|
+
tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
|
|
82
|
+
const tempConfig = { content }
|
|
83
|
+
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
|
|
84
|
+
args.push('--config', tempConfigPath)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
execSync(`"${binaryPath}" ${args.join(' ')}`, {
|
|
89
|
+
cwd,
|
|
90
|
+
encoding: 'utf-8',
|
|
91
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
92
|
+
})
|
|
93
|
+
} catch (error) {
|
|
94
|
+
const stderr = error.stderr ? error.stderr.toString() : error.message
|
|
95
|
+
console.error(`gustcss build failed: ${stderr}`)
|
|
96
|
+
} finally {
|
|
97
|
+
// Clean up temporary config file
|
|
98
|
+
if (tempConfigPath && fs.existsSync(tempConfigPath)) {
|
|
99
|
+
fs.unlinkSync(tempConfigPath)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
name: 'gustcss',
|
|
106
|
+
|
|
107
|
+
configResolved(config) {
|
|
108
|
+
const cwd = config.root || process.cwd()
|
|
109
|
+
const binaryPath = findBinary(cwd)
|
|
110
|
+
|
|
111
|
+
// Always run initial build
|
|
112
|
+
buildCSS(cwd, binaryPath)
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
configureServer(server) {
|
|
116
|
+
const cwd = server.config.root || process.cwd()
|
|
117
|
+
const binaryPath = findBinary(cwd)
|
|
118
|
+
const resolvedConfigPath = findConfigFile(cwd)
|
|
119
|
+
const outputPath = path.resolve(cwd, output)
|
|
120
|
+
|
|
121
|
+
// First, run initial build synchronously before starting watch mode
|
|
122
|
+
buildCSS(cwd, binaryPath)
|
|
123
|
+
|
|
124
|
+
// Start watch mode (without initial build since we just did it)
|
|
125
|
+
const args = ['build', '--watch', '-o', output]
|
|
126
|
+
|
|
127
|
+
let tempConfigPath = null
|
|
128
|
+
if (resolvedConfigPath) {
|
|
129
|
+
args.push('--config', resolvedConfigPath)
|
|
130
|
+
} else {
|
|
131
|
+
tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
|
|
132
|
+
const tempConfig = { content }
|
|
133
|
+
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
|
|
134
|
+
args.push('--config', tempConfigPath)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
watchProcess = spawn(binaryPath, args, {
|
|
138
|
+
cwd,
|
|
139
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
watchProcess.stderr.on('data', (data) => {
|
|
143
|
+
console.error(`gustcss: ${data}`)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// Watch generated CSS file for HMR
|
|
147
|
+
server.watcher.add(outputPath)
|
|
148
|
+
server.watcher.on('change', (changedPath) => {
|
|
149
|
+
if (path.resolve(changedPath) === outputPath) {
|
|
150
|
+
server.ws.send({
|
|
151
|
+
type: 'update',
|
|
152
|
+
updates: [
|
|
153
|
+
{
|
|
154
|
+
type: 'css-update',
|
|
155
|
+
path: '/' + path.relative(cwd, outputPath),
|
|
156
|
+
acceptedPath: '/' + path.relative(cwd, outputPath),
|
|
157
|
+
timestamp: Date.now(),
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
server.httpServer?.on('close', () => {
|
|
165
|
+
if (watchProcess) {
|
|
166
|
+
watchProcess.kill()
|
|
167
|
+
watchProcess = null
|
|
168
|
+
}
|
|
169
|
+
// Clean up temporary config file
|
|
170
|
+
if (tempConfigPath && fs.existsSync(tempConfigPath)) {
|
|
171
|
+
fs.unlinkSync(tempConfigPath)
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
buildEnd() {
|
|
177
|
+
if (watchProcess) {
|
|
178
|
+
watchProcess.kill()
|
|
179
|
+
watchProcess = null
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = { cssUtility }
|
|
186
|
+
module.exports.default = cssUtility
|
package/index.mjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
const { execSync, spawn } = require('child_process')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @gustcss/vite - Vite plugin for CSS Utility Generator
|
|
7
|
+
*
|
|
8
|
+
* Usage in vite.config.ts:
|
|
9
|
+
* import gustcss from '@gustcss/vite'
|
|
10
|
+
* export default defineConfig({
|
|
11
|
+
* plugins: [gustcss({ output: 'src/styles/utility.css' })],
|
|
12
|
+
* })
|
|
13
|
+
*/
|
|
14
|
+
function cssUtility(opts = {}) {
|
|
15
|
+
const output = opts.output || 'src/styles/utility.css'
|
|
16
|
+
const content = opts.content || ['./src/**/*.{js,ts,jsx,tsx,astro,vue}']
|
|
17
|
+
const configPath = opts.config
|
|
18
|
+
let watchProcess = null
|
|
19
|
+
|
|
20
|
+
function findBinary(cwd) {
|
|
21
|
+
const possiblePaths = [
|
|
22
|
+
path.join(cwd, 'node_modules', '.bin', 'gustcss'),
|
|
23
|
+
path.join(cwd, '..', '..', 'bin', 'gustcss'), // For sample projects
|
|
24
|
+
'gustcss', // Global installation
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
for (const p of possiblePaths) {
|
|
28
|
+
if (p === 'gustcss' || fs.existsSync(p)) {
|
|
29
|
+
return p
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
throw new Error('gustcss binary not found')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function findConfigFile(cwd) {
|
|
37
|
+
if (configPath) {
|
|
38
|
+
return configPath
|
|
39
|
+
}
|
|
40
|
+
// Auto-detect config file in current directory
|
|
41
|
+
const defaultConfigPaths = [
|
|
42
|
+
'gustcss.config.json',
|
|
43
|
+
'gustcss.config.js',
|
|
44
|
+
]
|
|
45
|
+
for (const configName of defaultConfigPaths) {
|
|
46
|
+
const fullPath = path.join(cwd, configName)
|
|
47
|
+
if (fs.existsSync(fullPath)) {
|
|
48
|
+
return fullPath
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function buildArgs(cwd, extraArgs = []) {
|
|
55
|
+
const args = ['build', ...extraArgs]
|
|
56
|
+
const resolvedConfigPath = findConfigFile(cwd)
|
|
57
|
+
|
|
58
|
+
if (resolvedConfigPath) {
|
|
59
|
+
// Use existing config file
|
|
60
|
+
args.push('--config', resolvedConfigPath)
|
|
61
|
+
} else {
|
|
62
|
+
// Create temporary config file to avoid glob pattern issues with CLI
|
|
63
|
+
const tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
|
|
64
|
+
const tempConfig = { content, output }
|
|
65
|
+
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
|
|
66
|
+
args.push('--config', tempConfigPath)
|
|
67
|
+
// Note: temp file cleanup happens after build in buildCSS
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return args
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function buildCSS(cwd, binaryPath) {
|
|
74
|
+
const resolvedConfigPath = findConfigFile(cwd)
|
|
75
|
+
const args = ['build', '-o', output]
|
|
76
|
+
|
|
77
|
+
let tempConfigPath = null
|
|
78
|
+
if (resolvedConfigPath) {
|
|
79
|
+
args.push('--config', resolvedConfigPath)
|
|
80
|
+
} else {
|
|
81
|
+
tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
|
|
82
|
+
const tempConfig = { content }
|
|
83
|
+
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
|
|
84
|
+
args.push('--config', tempConfigPath)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
execSync(`"${binaryPath}" ${args.join(' ')}`, {
|
|
89
|
+
cwd,
|
|
90
|
+
encoding: 'utf-8',
|
|
91
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
92
|
+
})
|
|
93
|
+
} catch (error) {
|
|
94
|
+
const stderr = error.stderr ? error.stderr.toString() : error.message
|
|
95
|
+
console.error(`gustcss build failed: ${stderr}`)
|
|
96
|
+
} finally {
|
|
97
|
+
// Clean up temporary config file
|
|
98
|
+
if (tempConfigPath && fs.existsSync(tempConfigPath)) {
|
|
99
|
+
fs.unlinkSync(tempConfigPath)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
name: 'gustcss',
|
|
106
|
+
|
|
107
|
+
configResolved(config) {
|
|
108
|
+
const cwd = config.root || process.cwd()
|
|
109
|
+
const binaryPath = findBinary(cwd)
|
|
110
|
+
|
|
111
|
+
// Always run initial build
|
|
112
|
+
buildCSS(cwd, binaryPath)
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
configureServer(server) {
|
|
116
|
+
const cwd = server.config.root || process.cwd()
|
|
117
|
+
const binaryPath = findBinary(cwd)
|
|
118
|
+
const resolvedConfigPath = findConfigFile(cwd)
|
|
119
|
+
const outputPath = path.resolve(cwd, output)
|
|
120
|
+
|
|
121
|
+
// First, run initial build synchronously before starting watch mode
|
|
122
|
+
buildCSS(cwd, binaryPath)
|
|
123
|
+
|
|
124
|
+
// Start watch mode (without initial build since we just did it)
|
|
125
|
+
const args = ['build', '--watch', '-o', output]
|
|
126
|
+
|
|
127
|
+
let tempConfigPath = null
|
|
128
|
+
if (resolvedConfigPath) {
|
|
129
|
+
args.push('--config', resolvedConfigPath)
|
|
130
|
+
} else {
|
|
131
|
+
tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
|
|
132
|
+
const tempConfig = { content }
|
|
133
|
+
fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
|
|
134
|
+
args.push('--config', tempConfigPath)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
watchProcess = spawn(binaryPath, args, {
|
|
138
|
+
cwd,
|
|
139
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
watchProcess.stderr.on('data', (data) => {
|
|
143
|
+
console.error(`gustcss: ${data}`)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// Watch generated CSS file for HMR
|
|
147
|
+
server.watcher.add(outputPath)
|
|
148
|
+
server.watcher.on('change', (changedPath) => {
|
|
149
|
+
if (path.resolve(changedPath) === outputPath) {
|
|
150
|
+
server.ws.send({
|
|
151
|
+
type: 'update',
|
|
152
|
+
updates: [
|
|
153
|
+
{
|
|
154
|
+
type: 'css-update',
|
|
155
|
+
path: '/' + path.relative(cwd, outputPath),
|
|
156
|
+
acceptedPath: '/' + path.relative(cwd, outputPath),
|
|
157
|
+
timestamp: Date.now(),
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
server.httpServer?.on('close', () => {
|
|
165
|
+
if (watchProcess) {
|
|
166
|
+
watchProcess.kill()
|
|
167
|
+
watchProcess = null
|
|
168
|
+
}
|
|
169
|
+
// Clean up temporary config file
|
|
170
|
+
if (tempConfigPath && fs.existsSync(tempConfigPath)) {
|
|
171
|
+
fs.unlinkSync(tempConfigPath)
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
buildEnd() {
|
|
177
|
+
if (watchProcess) {
|
|
178
|
+
watchProcess.kill()
|
|
179
|
+
watchProcess = null
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = { cssUtility }
|
|
186
|
+
module.exports.default = cssUtility
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gustcss/vite",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vite plugin for Gust CSS Utility Generator",
|
|
5
|
+
"main": "index.mjs",
|
|
6
|
+
"module": "index.mjs",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"index.cjs",
|
|
10
|
+
"index.mjs",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./index.mjs",
|
|
17
|
+
"require": "./index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"keywords": ["vite", "vite-plugin", "gustcss", "gust", "css", "utility"],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"gustcss": "^0.1.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"vite": "^4.0.0 || ^5.0.0 || ^6.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|