strata-css 1.0.2 → 1.0.3
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 +730 -730
- package/bin/strata.js +276 -177
- package/package.json +68 -68
- package/src/index.js +171 -171
package/bin/strata.js
CHANGED
|
@@ -1,177 +1,276 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
'use strict'
|
|
4
|
-
|
|
5
|
-
const fs = require('fs')
|
|
6
|
-
const path = require('path')
|
|
7
|
-
const chokidar = require('chokidar')
|
|
8
|
-
const strata = require('../src/index')
|
|
9
|
-
const { getWatchFiles } = require('../src/scanner/scanner')
|
|
10
|
-
|
|
11
|
-
const args = process.argv.slice(2)
|
|
12
|
-
const cwd = process.cwd()
|
|
13
|
-
|
|
14
|
-
function loadConfig(cwd) {
|
|
15
|
-
const configPath = path.resolve(cwd, 'strata.config.js')
|
|
16
|
-
const configPathCjs = path.resolve(cwd, 'strata.config.cjs')
|
|
17
|
-
|
|
18
|
-
if (fs.existsSync(configPathCjs)) {
|
|
19
|
-
try { return require(configPathCjs) } catch {}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (fs.existsSync(configPath)) {
|
|
23
|
-
try { return require(configPath) } catch {}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ─── JS minifier ──────────────────────────────────────────────────────
|
|
30
|
-
// Strips block comments (preserving /*! banners), line comments,
|
|
31
|
-
// and collapses unnecessary whitespace — no external dependency needed.
|
|
32
|
-
|
|
33
|
-
function minifyJS(src) {
|
|
34
|
-
return src
|
|
35
|
-
// preserve /*! banner */ comments, strip all other /* ... */ blocks
|
|
36
|
-
.replace(/\/\*(?!!)([\s\S]*?)\*\//g, '')
|
|
37
|
-
// strip // line comments (not inside strings — conservative: only at line start or after whitespace)
|
|
38
|
-
.replace(/(?:^|\s)\/\/[^\n]*/gm, '')
|
|
39
|
-
// collapse runs of whitespace/newlines to a single space
|
|
40
|
-
.replace(/[ \t]+/g, ' ')
|
|
41
|
-
.replace(/\n\s*\n+/g, '\n')
|
|
42
|
-
.trim()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ─── Build ────────────────────────────────────────────────────────────
|
|
46
|
-
// --watch → unminified CSS, unminified JS (fast rebuilds for dev)
|
|
47
|
-
// --build → unminified CSS, minified JS (production-ready JS)
|
|
48
|
-
// --minify → minified CSS + minified JS (smallest possible output)
|
|
49
|
-
|
|
50
|
-
async function build(cssMinify = false, jsMinify = true) {
|
|
51
|
-
const config = loadConfig(cwd)
|
|
52
|
-
const inputFile = config.input || path.join(cwd, 'strata.css')
|
|
53
|
-
const outputFile = config.output || path.join(cwd, 'dist', 'strata.output.css')
|
|
54
|
-
|
|
55
|
-
const start = process.hrtime.bigint()
|
|
56
|
-
const css = await strata.build(inputFile, outputFile, { cwd, sourceMap: !cssMinify })
|
|
57
|
-
|
|
58
|
-
// CSS minification
|
|
59
|
-
if (cssMinify) {
|
|
60
|
-
const cssnano = require('cssnano')
|
|
61
|
-
const postcss = require('postcss')
|
|
62
|
-
const result = await postcss([cssnano({ preset: 'default' })]).process(css, { from: outputFile })
|
|
63
|
-
fs.writeFileSync(outputFile, result.css)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Bundle + optionally minify JS components
|
|
67
|
-
const componentsDir = path.join(__dirname, '..', 'src', 'components', 'modules')
|
|
68
|
-
const jsDest = path.join(path.dirname(outputFile), 'strata.components.js')
|
|
69
|
-
if (fs.existsSync(componentsDir)) {
|
|
70
|
-
const files = fs.readdirSync(componentsDir).filter(f => f.endsWith('.js')).sort()
|
|
71
|
-
const banner = `/*! Strata Components — built ${new Date().toISOString().slice(0,10)} */\n`
|
|
72
|
-
const raw = files.map(f => fs.readFileSync(path.join(componentsDir, f), 'utf8')).join('\n')
|
|
73
|
-
const output = jsMinify ? banner + minifyJS(raw) : banner + raw
|
|
74
|
-
fs.mkdirSync(path.dirname(jsDest), { recursive: true })
|
|
75
|
-
fs.writeFileSync(jsDest, output)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const ms = (Number(process.hrtime.bigint() - start) / 1_000_000).toFixed(2)
|
|
79
|
-
const cssSize = (Buffer.byteLength(fs.readFileSync(outputFile)) / 1024).toFixed(2)
|
|
80
|
-
const jsSize = fs.existsSync(jsDest)
|
|
81
|
-
? (Buffer.byteLength(fs.readFileSync(jsDest)) / 1024).toFixed(2)
|
|
82
|
-
: '0'
|
|
83
|
-
console.log(`[Strata] ✓ Built → ${outputFile} (CSS ${cssSize} KB, JS ${jsSize} KB) in ${ms}ms`)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ─── Watch ────────────────────────────────────────────────────────────
|
|
87
|
-
async function watch() {
|
|
88
|
-
console.log('[Strata] Starting in watch mode...')
|
|
89
|
-
await build(false, false) // unminified for dev
|
|
90
|
-
|
|
91
|
-
const config = loadConfig(cwd)
|
|
92
|
-
const contentGlobs = config.content || ['./src/**/*.{html,jsx,tsx,vue,astro,svelte,js,ts}']
|
|
93
|
-
const inputFile = config.input || path.join(cwd, 'strata.css')
|
|
94
|
-
const watchFiles = [inputFile, ...getWatchFiles(contentGlobs)]
|
|
95
|
-
|
|
96
|
-
const watcher = chokidar.watch(watchFiles, { ignoreInitial: true, persistent: true })
|
|
97
|
-
|
|
98
|
-
watcher.on('change', async (filePath) => {
|
|
99
|
-
console.log(`[Strata] Changed: ${path.relative(cwd, filePath)}`)
|
|
100
|
-
strata.invalidate(filePath)
|
|
101
|
-
await build(false, false)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
watcher.on('add', async (filePath) => {
|
|
105
|
-
console.log(`[Strata] Added: ${path.relative(cwd, filePath)}`)
|
|
106
|
-
strata.invalidate(filePath)
|
|
107
|
-
await build(false, false)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
console.log('[Strata] Watching for changes...')
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// ─── ESM / framework helpers ──────────────────────────────────────────
|
|
114
|
-
function isESMProject(cwd) {
|
|
115
|
-
try {
|
|
116
|
-
const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf8'))
|
|
117
|
-
return pkg.type === 'module'
|
|
118
|
-
} catch {
|
|
119
|
-
return false
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function detectOutputPath(cwd) {
|
|
124
|
-
try {
|
|
125
|
-
const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf8'))
|
|
126
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
127
|
-
if (deps['astro']) return './public/strata.output.css'
|
|
128
|
-
if (deps['laravel-vite-plugin']) return './public/strata.output.css'
|
|
129
|
-
if (deps['next']) return './public/strata.output.css'
|
|
130
|
-
if (deps['react']) return './public/strata.output.css'
|
|
131
|
-
if (deps['vue']) return './public/strata.output.css'
|
|
132
|
-
if (deps['@sveltejs/kit']) return './public/strata.output.css'
|
|
133
|
-
} catch {}
|
|
134
|
-
return './dist/strata.output.css'
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// ───
|
|
138
|
-
function
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict'
|
|
4
|
+
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
const path = require('path')
|
|
7
|
+
const chokidar = require('chokidar')
|
|
8
|
+
const strata = require('../src/index')
|
|
9
|
+
const { getWatchFiles } = require('../src/scanner/scanner')
|
|
10
|
+
|
|
11
|
+
const args = process.argv.slice(2)
|
|
12
|
+
const cwd = process.cwd()
|
|
13
|
+
|
|
14
|
+
function loadConfig(cwd) {
|
|
15
|
+
const configPath = path.resolve(cwd, 'strata.config.js')
|
|
16
|
+
const configPathCjs = path.resolve(cwd, 'strata.config.cjs')
|
|
17
|
+
|
|
18
|
+
if (fs.existsSync(configPathCjs)) {
|
|
19
|
+
try { return require(configPathCjs) } catch {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(configPath)) {
|
|
23
|
+
try { return require(configPath) } catch {}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ─── JS minifier ──────────────────────────────────────────────────────
|
|
30
|
+
// Strips block comments (preserving /*! banners), line comments,
|
|
31
|
+
// and collapses unnecessary whitespace — no external dependency needed.
|
|
32
|
+
|
|
33
|
+
function minifyJS(src) {
|
|
34
|
+
return src
|
|
35
|
+
// preserve /*! banner */ comments, strip all other /* ... */ blocks
|
|
36
|
+
.replace(/\/\*(?!!)([\s\S]*?)\*\//g, '')
|
|
37
|
+
// strip // line comments (not inside strings — conservative: only at line start or after whitespace)
|
|
38
|
+
.replace(/(?:^|\s)\/\/[^\n]*/gm, '')
|
|
39
|
+
// collapse runs of whitespace/newlines to a single space
|
|
40
|
+
.replace(/[ \t]+/g, ' ')
|
|
41
|
+
.replace(/\n\s*\n+/g, '\n')
|
|
42
|
+
.trim()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ─── Build ────────────────────────────────────────────────────────────
|
|
46
|
+
// --watch → unminified CSS, unminified JS (fast rebuilds for dev)
|
|
47
|
+
// --build → unminified CSS, minified JS (production-ready JS)
|
|
48
|
+
// --minify → minified CSS + minified JS (smallest possible output)
|
|
49
|
+
|
|
50
|
+
async function build(cssMinify = false, jsMinify = true) {
|
|
51
|
+
const config = loadConfig(cwd)
|
|
52
|
+
const inputFile = config.input || path.join(cwd, 'strata.css')
|
|
53
|
+
const outputFile = config.output || path.join(cwd, 'dist', 'strata.output.css')
|
|
54
|
+
|
|
55
|
+
const start = process.hrtime.bigint()
|
|
56
|
+
const css = await strata.build(inputFile, outputFile, { cwd, sourceMap: !cssMinify })
|
|
57
|
+
|
|
58
|
+
// CSS minification
|
|
59
|
+
if (cssMinify) {
|
|
60
|
+
const cssnano = require('cssnano')
|
|
61
|
+
const postcss = require('postcss')
|
|
62
|
+
const result = await postcss([cssnano({ preset: 'default' })]).process(css, { from: outputFile })
|
|
63
|
+
fs.writeFileSync(outputFile, result.css)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Bundle + optionally minify JS components
|
|
67
|
+
const componentsDir = path.join(__dirname, '..', 'src', 'components', 'modules')
|
|
68
|
+
const jsDest = path.join(path.dirname(outputFile), 'strata.components.js')
|
|
69
|
+
if (fs.existsSync(componentsDir)) {
|
|
70
|
+
const files = fs.readdirSync(componentsDir).filter(f => f.endsWith('.js')).sort()
|
|
71
|
+
const banner = `/*! Strata Components — built ${new Date().toISOString().slice(0,10)} */\n`
|
|
72
|
+
const raw = files.map(f => fs.readFileSync(path.join(componentsDir, f), 'utf8')).join('\n')
|
|
73
|
+
const output = jsMinify ? banner + minifyJS(raw) : banner + raw
|
|
74
|
+
fs.mkdirSync(path.dirname(jsDest), { recursive: true })
|
|
75
|
+
fs.writeFileSync(jsDest, output)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const ms = (Number(process.hrtime.bigint() - start) / 1_000_000).toFixed(2)
|
|
79
|
+
const cssSize = (Buffer.byteLength(fs.readFileSync(outputFile)) / 1024).toFixed(2)
|
|
80
|
+
const jsSize = fs.existsSync(jsDest)
|
|
81
|
+
? (Buffer.byteLength(fs.readFileSync(jsDest)) / 1024).toFixed(2)
|
|
82
|
+
: '0'
|
|
83
|
+
console.log(`[Strata] ✓ Built → ${outputFile} (CSS ${cssSize} KB, JS ${jsSize} KB) in ${ms}ms`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ─── Watch ────────────────────────────────────────────────────────────
|
|
87
|
+
async function watch() {
|
|
88
|
+
console.log('[Strata] Starting in watch mode...')
|
|
89
|
+
await build(false, false) // unminified for dev
|
|
90
|
+
|
|
91
|
+
const config = loadConfig(cwd)
|
|
92
|
+
const contentGlobs = config.content || ['./src/**/*.{html,jsx,tsx,vue,astro,svelte,js,ts}']
|
|
93
|
+
const inputFile = config.input || path.join(cwd, 'strata.css')
|
|
94
|
+
const watchFiles = [inputFile, ...getWatchFiles(contentGlobs)]
|
|
95
|
+
|
|
96
|
+
const watcher = chokidar.watch(watchFiles, { ignoreInitial: true, persistent: true })
|
|
97
|
+
|
|
98
|
+
watcher.on('change', async (filePath) => {
|
|
99
|
+
console.log(`[Strata] Changed: ${path.relative(cwd, filePath)}`)
|
|
100
|
+
strata.invalidate(filePath)
|
|
101
|
+
await build(false, false)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
watcher.on('add', async (filePath) => {
|
|
105
|
+
console.log(`[Strata] Added: ${path.relative(cwd, filePath)}`)
|
|
106
|
+
strata.invalidate(filePath)
|
|
107
|
+
await build(false, false)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
console.log('[Strata] Watching for changes...')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ─── ESM / framework helpers ──────────────────────────────────────────
|
|
114
|
+
function isESMProject(cwd) {
|
|
115
|
+
try {
|
|
116
|
+
const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf8'))
|
|
117
|
+
return pkg.type === 'module'
|
|
118
|
+
} catch {
|
|
119
|
+
return false
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function detectOutputPath(cwd) {
|
|
124
|
+
try {
|
|
125
|
+
const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf8'))
|
|
126
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
127
|
+
if (deps['astro']) return './public/strata.output.css'
|
|
128
|
+
if (deps['laravel-vite-plugin']) return './public/strata.output.css'
|
|
129
|
+
if (deps['next']) return './public/strata.output.css'
|
|
130
|
+
if (deps['react']) return './public/strata.output.css'
|
|
131
|
+
if (deps['vue']) return './public/strata.output.css'
|
|
132
|
+
if (deps['@sveltejs/kit']) return './public/strata.output.css'
|
|
133
|
+
} catch {}
|
|
134
|
+
return './dist/strata.output.css'
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ─── Framework detection ──────────────────────────────────────────────
|
|
138
|
+
function detectFramework(cwd) {
|
|
139
|
+
try {
|
|
140
|
+
const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf8'))
|
|
141
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
142
|
+
|
|
143
|
+
if (deps['astro']) return 'astro'
|
|
144
|
+
if (deps['laravel-vite-plugin']) return 'laravel'
|
|
145
|
+
if (deps['next']) return 'next'
|
|
146
|
+
if (deps['@sveltejs/kit']) return 'sveltekit'
|
|
147
|
+
if (deps['nuxt']) return 'nuxt'
|
|
148
|
+
if (deps['react'] && deps['vite']) return 'react-vite'
|
|
149
|
+
if (deps['vue'] && deps['vite']) return 'vue-vite'
|
|
150
|
+
} catch {}
|
|
151
|
+
return 'generic'
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ─── Script injection ─────────────────────────────────────────────────
|
|
155
|
+
function injectScripts(cwd, framework) {
|
|
156
|
+
const pkgPath = path.resolve(cwd, 'package.json')
|
|
157
|
+
const strataWatch = 'node node_modules/strata-css/bin/strata.js --watch'
|
|
158
|
+
const strataBuild = 'node node_modules/strata-css/bin/strata.js --build'
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
|
|
162
|
+
if (!pkg.scripts) pkg.scripts = {}
|
|
163
|
+
|
|
164
|
+
const frameworkDev = {
|
|
165
|
+
'astro': 'astro dev',
|
|
166
|
+
'laravel': 'vite',
|
|
167
|
+
'next': 'next dev',
|
|
168
|
+
'sveltekit': 'vite dev',
|
|
169
|
+
'nuxt': 'nuxt dev',
|
|
170
|
+
'react-vite': 'vite',
|
|
171
|
+
'vue-vite': 'vite',
|
|
172
|
+
'generic': pkg.scripts.dev || 'npm start'
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const frameworkBuild = {
|
|
176
|
+
'astro': 'astro build',
|
|
177
|
+
'laravel': 'vite build',
|
|
178
|
+
'next': 'next build',
|
|
179
|
+
'sveltekit': 'vite build',
|
|
180
|
+
'nuxt': 'nuxt build',
|
|
181
|
+
'react-vite': 'vite build',
|
|
182
|
+
'vue-vite': 'vite build',
|
|
183
|
+
'generic': pkg.scripts.build || 'npm run build'
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const devCmd = frameworkDev[framework]
|
|
187
|
+
const buildCmd = frameworkBuild[framework]
|
|
188
|
+
|
|
189
|
+
const hasConcurrently = pkg.dependencies?.['concurrently'] ||
|
|
190
|
+
pkg.devDependencies?.['concurrently']
|
|
191
|
+
|
|
192
|
+
if (hasConcurrently) {
|
|
193
|
+
pkg.scripts.dev = `concurrently "${devCmd}" "${strataWatch}"`
|
|
194
|
+
} else {
|
|
195
|
+
pkg.scripts.dev = `${strataWatch} & ${devCmd}`
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
pkg.scripts.build = `${strataBuild} && ${buildCmd}`
|
|
199
|
+
pkg.scripts['strata:watch'] = strataWatch
|
|
200
|
+
pkg.scripts['strata:build'] = strataBuild
|
|
201
|
+
|
|
202
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2))
|
|
203
|
+
return true
|
|
204
|
+
} catch (e) {
|
|
205
|
+
return false
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ─── Init ─────────────────────────────────────────────────────────────
|
|
210
|
+
function init() {
|
|
211
|
+
const isESM = isESMProject(cwd)
|
|
212
|
+
const output = detectOutputPath(cwd)
|
|
213
|
+
const framework = detectFramework(cwd)
|
|
214
|
+
|
|
215
|
+
console.log('[Strata] Initializing project...')
|
|
216
|
+
console.log(`[Strata] Detected: ${isESM ? 'ESM' : 'CommonJS'} project`)
|
|
217
|
+
console.log(`[Strata] Framework: ${framework}`)
|
|
218
|
+
|
|
219
|
+
const configFile = isESM ? 'strata.config.cjs' : 'strata.config.js'
|
|
220
|
+
const postcssFile = isESM ? 'postcss.config.cjs' : 'postcss.config.js'
|
|
221
|
+
|
|
222
|
+
const configContent = `module.exports = {\n content: ["./src/**/*.{html,jsx,tsx,vue,astro,svelte,js,ts}"],\n input: "./strata.css",\n output: "${output}"\n}\n`
|
|
223
|
+
const postcssContent = `module.exports = {\n plugins: [\n require('strata-css'),\n require('autoprefixer')\n ]\n}\n`
|
|
224
|
+
const strataCssContent = `@strata base;\n@strata components;\n@strata utilities;\n`
|
|
225
|
+
|
|
226
|
+
fs.writeFileSync(path.resolve(cwd, configFile), configContent)
|
|
227
|
+
fs.writeFileSync(path.resolve(cwd, postcssFile), postcssContent)
|
|
228
|
+
fs.writeFileSync(path.resolve(cwd, 'strata.css'), strataCssContent)
|
|
229
|
+
|
|
230
|
+
console.log(`[Strata] Created: ${configFile}`)
|
|
231
|
+
console.log(`[Strata] Created: strata.css`)
|
|
232
|
+
console.log(`[Strata] Created: ${postcssFile}`)
|
|
233
|
+
|
|
234
|
+
const injected = injectScripts(cwd, framework)
|
|
235
|
+
|
|
236
|
+
if (injected) {
|
|
237
|
+
let hasConcurrently = false
|
|
238
|
+
try {
|
|
239
|
+
const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf8'))
|
|
240
|
+
hasConcurrently = !!(pkg.dependencies?.['concurrently'] || pkg.devDependencies?.['concurrently'])
|
|
241
|
+
} catch {}
|
|
242
|
+
|
|
243
|
+
console.log(`[Strata] Updated package.json scripts:`)
|
|
244
|
+
console.log(`[Strata] dev → runs Strata watcher + framework dev server`)
|
|
245
|
+
console.log(`[Strata] build → runs Strata build then framework build`)
|
|
246
|
+
console.log(`[Strata] strata:watch → node node_modules/strata-css/bin/strata.js --watch`)
|
|
247
|
+
console.log(`[Strata] strata:build → node node_modules/strata-css/bin/strata.js --build`)
|
|
248
|
+
|
|
249
|
+
if (!hasConcurrently) {
|
|
250
|
+
console.log(`[Strata]`)
|
|
251
|
+
console.log(`[Strata] Tip: install concurrently for cleaner parallel dev:`)
|
|
252
|
+
console.log(`[Strata] npm install --save-dev concurrently`)
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
console.log(`[Strata] Warning: could not update package.json scripts — update manually.`)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
console.log(`[Strata] Done! Next steps:`)
|
|
259
|
+
console.log(`[Strata] 1. Add <link rel="stylesheet" href="/strata.output.css"> to your HTML`)
|
|
260
|
+
console.log(`[Strata] 2. Add data-st-theme="light" to your <html> tag`)
|
|
261
|
+
console.log(`[Strata] 3. Run: npm run dev`)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ─── Run ──────────────────────────────────────────────────────────────
|
|
265
|
+
if (args[0] === 'init') init()
|
|
266
|
+
else if (args.includes('--watch')) watch()
|
|
267
|
+
else if (args.includes('--minify')) build(true, true)
|
|
268
|
+
else if (args.includes('--build')) build(false, true)
|
|
269
|
+
else console.log(`
|
|
270
|
+
Strata CSS
|
|
271
|
+
|
|
272
|
+
strata-css init scaffold a new project
|
|
273
|
+
strata-css --watch development mode (unminified, fast rebuild)
|
|
274
|
+
strata-css --build production build (minified JS, readable CSS)
|
|
275
|
+
strata-css --minify production build (minified CSS + JS, smallest output)
|
|
276
|
+
`)
|
package/package.json
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "strata-css",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"_versioningNote": "Stable: 1.0.0 / 1.1.0 / 2.0.0 | Beta: 1.1.0-beta.1 / 1.1.0-beta.2",
|
|
5
|
-
"description": "A modern CSS framework combining Bootstrap components with Tailwind JIT processing",
|
|
6
|
-
"main": "src/index.js",
|
|
7
|
-
"types": "index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": "./src/index.js",
|
|
10
|
-
"./package.json": "./package.json"
|
|
11
|
-
},
|
|
12
|
-
"bin": {
|
|
13
|
-
"strata-css": "bin/strata.js"
|
|
14
|
-
},
|
|
15
|
-
"files": [
|
|
16
|
-
"src/",
|
|
17
|
-
"bin/",
|
|
18
|
-
"strata.css",
|
|
19
|
-
"index.d.ts",
|
|
20
|
-
"README.md",
|
|
21
|
-
"LICENSE",
|
|
22
|
-
"CHANGELOG.md"
|
|
23
|
-
],
|
|
24
|
-
"scripts": {
|
|
25
|
-
"dev": "node bin/strata.js --watch",
|
|
26
|
-
"build": "node bin/strata.js --build",
|
|
27
|
-
"minify": "node bin/strata.js --minify",
|
|
28
|
-
"benchmark": "node --expose-gc benchmark/run.js",
|
|
29
|
-
"publish:stable": "npm publish --tag latest",
|
|
30
|
-
"publish:beta": "npm publish --tag beta"
|
|
31
|
-
},
|
|
32
|
-
"keywords": [
|
|
33
|
-
"css",
|
|
34
|
-
"framework",
|
|
35
|
-
"postcss",
|
|
36
|
-
"postcss-plugin",
|
|
37
|
-
"jit",
|
|
38
|
-
"tailwind",
|
|
39
|
-
"tailwindcss",
|
|
40
|
-
"bootstrap",
|
|
41
|
-
"component-library",
|
|
42
|
-
"utility-first",
|
|
43
|
-
"theming",
|
|
44
|
-
"dark-mode",
|
|
45
|
-
"css-framework"
|
|
46
|
-
],
|
|
47
|
-
"author": "Aftab Ibrahim Kazi",
|
|
48
|
-
"license": "MIT",
|
|
49
|
-
"homepage": "https://aftabibrahimkazi.github.io/strata",
|
|
50
|
-
"repository": {
|
|
51
|
-
"type": "git",
|
|
52
|
-
"url": "git+https://github.com/AftabIbrahimKazi/strata.git"
|
|
53
|
-
},
|
|
54
|
-
"bugs": {
|
|
55
|
-
"url": "https://github.com/AftabIbrahimKazi/strata/issues"
|
|
56
|
-
},
|
|
57
|
-
"type": "commonjs",
|
|
58
|
-
"engines": {
|
|
59
|
-
"node": ">=18.0.0"
|
|
60
|
-
},
|
|
61
|
-
"dependencies": {
|
|
62
|
-
"autoprefixer": "^10.5.0",
|
|
63
|
-
"chokidar": "^5.0.0",
|
|
64
|
-
"cssnano": "^8.0.1",
|
|
65
|
-
"glob": "^13.0.6",
|
|
66
|
-
"postcss": "^8.5.14"
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "strata-css",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"_versioningNote": "Stable: 1.0.0 / 1.1.0 / 2.0.0 | Beta: 1.1.0-beta.1 / 1.1.0-beta.2",
|
|
5
|
+
"description": "A modern CSS framework combining Bootstrap components with Tailwind JIT processing",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"strata-css": "bin/strata.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src/",
|
|
17
|
+
"bin/",
|
|
18
|
+
"strata.css",
|
|
19
|
+
"index.d.ts",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"CHANGELOG.md"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"dev": "node bin/strata.js --watch",
|
|
26
|
+
"build": "node bin/strata.js --build",
|
|
27
|
+
"minify": "node bin/strata.js --minify",
|
|
28
|
+
"benchmark": "node --expose-gc benchmark/run.js",
|
|
29
|
+
"publish:stable": "npm publish --tag latest",
|
|
30
|
+
"publish:beta": "npm publish --tag beta"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"css",
|
|
34
|
+
"framework",
|
|
35
|
+
"postcss",
|
|
36
|
+
"postcss-plugin",
|
|
37
|
+
"jit",
|
|
38
|
+
"tailwind",
|
|
39
|
+
"tailwindcss",
|
|
40
|
+
"bootstrap",
|
|
41
|
+
"component-library",
|
|
42
|
+
"utility-first",
|
|
43
|
+
"theming",
|
|
44
|
+
"dark-mode",
|
|
45
|
+
"css-framework"
|
|
46
|
+
],
|
|
47
|
+
"author": "Aftab Ibrahim Kazi",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"homepage": "https://aftabibrahimkazi.github.io/strata",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/AftabIbrahimKazi/strata.git"
|
|
53
|
+
},
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/AftabIbrahimKazi/strata/issues"
|
|
56
|
+
},
|
|
57
|
+
"type": "commonjs",
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"autoprefixer": "^10.5.0",
|
|
63
|
+
"chokidar": "^5.0.0",
|
|
64
|
+
"cssnano": "^8.0.1",
|
|
65
|
+
"glob": "^13.0.6",
|
|
66
|
+
"postcss": "^8.5.14"
|
|
67
|
+
}
|
|
68
|
+
}
|