@master/css-cli 2.0.0-rc.17 → 2.0.0-rc.19
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 +1 -1
- package/dist/bin/index.mjs +2 -291
- package/dist/commands/extract.mjs +73 -0
- package/dist/commands/render.mjs +66 -0
- package/dist/core.mjs +21 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
<img alt="Follow @mastercorg" src="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
|
|
42
42
|
</picture>
|
|
43
43
|
</a>
|
|
44
|
-
<a aria-label="Github Actions" href="https://github.com/
|
|
44
|
+
<a aria-label="Github Actions" href="https://github.com/master-co/css/actions/workflows/release.yml">
|
|
45
45
|
<picture>
|
|
46
46
|
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=rc&label=%20&message=twitter&color=212022&logo=githubactions&style=for-the-badge">
|
|
47
47
|
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
package/dist/bin/index.mjs
CHANGED
|
@@ -1,293 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { readJSONFileSync } from '@techor/fs';
|
|
5
|
-
import { dirname } from 'path';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
import CSSExtractor from '@master/css-extractor';
|
|
8
|
-
import log from '@techor/log';
|
|
9
|
-
import prettyHartime from 'pretty-hrtime';
|
|
10
|
-
import { explorePathsSync } from '@techor/glob';
|
|
11
|
-
import exploreConfig from 'explore-config';
|
|
12
|
-
import { readFile, writeFileSync } from 'fs';
|
|
13
|
-
import { brotliCompressSync } from 'zlib';
|
|
14
|
-
import { render } from '@master/css-server';
|
|
2
|
+
import runProgram from '../core.mjs';
|
|
15
3
|
|
|
16
|
-
|
|
17
|
-
const { watch, output, verbose, cwd, options: customOptions } = options || {};
|
|
18
|
-
const extractor = new CSSExtractor(customOptions, cwd);
|
|
19
|
-
extractor.on('init', (options)=>{
|
|
20
|
-
if (specifiedSourcePaths?.length) {
|
|
21
|
-
options.include = [];
|
|
22
|
-
options.exclude = [];
|
|
23
|
-
} else {
|
|
24
|
-
if (!options.exclude?.includes('**/node_modules/**')) {
|
|
25
|
-
options.exclude?.push('**/node_modules/**');
|
|
26
|
-
}
|
|
27
|
-
if (!options.exclude?.includes('node_modules')) {
|
|
28
|
-
options.exclude?.push('node_modules');
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
options.output = output;
|
|
32
|
-
options.verbose = verbose ? +verbose : options.verbose;
|
|
33
|
-
});
|
|
34
|
-
extractor.init();
|
|
35
|
-
const insert = async ()=>{
|
|
36
|
-
/**
|
|
37
|
-
* true: Ignore `.include` and `.exclude` when specifying sources explicitly.
|
|
38
|
-
* else: Insert according to the source of `.include` - `.exclude`.
|
|
39
|
-
*/ if (specifiedSourcePaths?.length) {
|
|
40
|
-
await extractor.insertFiles(specifiedSourcePaths);
|
|
41
|
-
} else {
|
|
42
|
-
await extractor.insertFiles(extractor.allowedSourcePaths);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
if (watch) {
|
|
46
|
-
const reset = async ()=>{
|
|
47
|
-
await insert();
|
|
48
|
-
/* If the specified source does not exist, watch the .include - .exclude */ if (!specifiedSourcePaths?.length && extractor.options.include) {
|
|
49
|
-
await extractor.watchSource(extractor.options.include, {
|
|
50
|
-
ignored: extractor.options.exclude
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
extractor.on('watchStart', async ()=>{
|
|
55
|
-
await extractor.prepare();
|
|
56
|
-
await reset();
|
|
57
|
-
log``;
|
|
58
|
-
log.t`Start watching source changes`;
|
|
59
|
-
}).on('reset', async ()=>{
|
|
60
|
-
await reset();
|
|
61
|
-
log``;
|
|
62
|
-
log.t`Restart watching source changes`;
|
|
63
|
-
}).on('change', ()=>{
|
|
64
|
-
if (options?.export) {
|
|
65
|
-
extractor.export();
|
|
66
|
-
} else {
|
|
67
|
-
console.log(extractor.css.text);
|
|
68
|
-
}
|
|
69
|
-
}).on('watchClose', ()=>{
|
|
70
|
-
log``;
|
|
71
|
-
log.t`Stop watching source changes`;
|
|
72
|
-
});
|
|
73
|
-
await extractor.startWatch();
|
|
74
|
-
} else {
|
|
75
|
-
await extractor.prepare();
|
|
76
|
-
await insert();
|
|
77
|
-
if (options?.export) {
|
|
78
|
-
extractor.export();
|
|
79
|
-
} else {
|
|
80
|
-
console.log(extractor.css.text);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}));
|
|
84
|
-
|
|
85
|
-
function getDefaultExportFromCjs (x) {
|
|
86
|
-
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
var bytes$2 = {exports: {}};
|
|
90
|
-
|
|
91
|
-
/*!
|
|
92
|
-
* bytes
|
|
93
|
-
* Copyright(c) 2012-2014 TJ Holowaychuk
|
|
94
|
-
* Copyright(c) 2015 Jed Watson
|
|
95
|
-
* MIT Licensed
|
|
96
|
-
*/
|
|
97
|
-
/**
|
|
98
|
-
* Module exports.
|
|
99
|
-
* @public
|
|
100
|
-
*/ bytes$2.exports = bytes;
|
|
101
|
-
bytes$2.exports.format = format;
|
|
102
|
-
bytes$2.exports.parse = parse;
|
|
103
|
-
/**
|
|
104
|
-
* Module variables.
|
|
105
|
-
* @private
|
|
106
|
-
*/ var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
|
|
107
|
-
var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
|
|
108
|
-
var map = {
|
|
109
|
-
b: 1,
|
|
110
|
-
kb: 1 << 10,
|
|
111
|
-
mb: 1 << 20,
|
|
112
|
-
gb: 1 << 30,
|
|
113
|
-
tb: Math.pow(1024, 4),
|
|
114
|
-
pb: Math.pow(1024, 5)
|
|
115
|
-
};
|
|
116
|
-
var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
|
|
117
|
-
/**
|
|
118
|
-
* Convert the given value in bytes into a string or parse to string to an integer in bytes.
|
|
119
|
-
*
|
|
120
|
-
* @param {string|number} value
|
|
121
|
-
* @param {{
|
|
122
|
-
* case: [string],
|
|
123
|
-
* decimalPlaces: [number]
|
|
124
|
-
* fixedDecimals: [boolean]
|
|
125
|
-
* thousandsSeparator: [string]
|
|
126
|
-
* unitSeparator: [string]
|
|
127
|
-
* }} [options] bytes options.
|
|
128
|
-
*
|
|
129
|
-
* @returns {string|number|null}
|
|
130
|
-
*/ function bytes(value, options) {
|
|
131
|
-
if (typeof value === 'string') {
|
|
132
|
-
return parse(value);
|
|
133
|
-
}
|
|
134
|
-
if (typeof value === 'number') {
|
|
135
|
-
return format(value, options);
|
|
136
|
-
}
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Format the given value in bytes into a string.
|
|
141
|
-
*
|
|
142
|
-
* If the value is negative, it is kept as such. If it is a float,
|
|
143
|
-
* it is rounded.
|
|
144
|
-
*
|
|
145
|
-
* @param {number} value
|
|
146
|
-
* @param {object} [options]
|
|
147
|
-
* @param {number} [options.decimalPlaces=2]
|
|
148
|
-
* @param {number} [options.fixedDecimals=false]
|
|
149
|
-
* @param {string} [options.thousandsSeparator=]
|
|
150
|
-
* @param {string} [options.unit=]
|
|
151
|
-
* @param {string} [options.unitSeparator=]
|
|
152
|
-
*
|
|
153
|
-
* @returns {string|null}
|
|
154
|
-
* @public
|
|
155
|
-
*/ function format(value, options) {
|
|
156
|
-
if (!Number.isFinite(value)) {
|
|
157
|
-
return null;
|
|
158
|
-
}
|
|
159
|
-
var mag = Math.abs(value);
|
|
160
|
-
var thousandsSeparator = options && options.thousandsSeparator || '';
|
|
161
|
-
var unitSeparator = options && options.unitSeparator || '';
|
|
162
|
-
var decimalPlaces = options && options.decimalPlaces !== undefined ? options.decimalPlaces : 2;
|
|
163
|
-
var fixedDecimals = Boolean(options && options.fixedDecimals);
|
|
164
|
-
var unit = options && options.unit || '';
|
|
165
|
-
if (!unit || !map[unit.toLowerCase()]) {
|
|
166
|
-
if (mag >= map.pb) {
|
|
167
|
-
unit = 'PB';
|
|
168
|
-
} else if (mag >= map.tb) {
|
|
169
|
-
unit = 'TB';
|
|
170
|
-
} else if (mag >= map.gb) {
|
|
171
|
-
unit = 'GB';
|
|
172
|
-
} else if (mag >= map.mb) {
|
|
173
|
-
unit = 'MB';
|
|
174
|
-
} else if (mag >= map.kb) {
|
|
175
|
-
unit = 'KB';
|
|
176
|
-
} else {
|
|
177
|
-
unit = 'B';
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
var val = value / map[unit.toLowerCase()];
|
|
181
|
-
var str = val.toFixed(decimalPlaces);
|
|
182
|
-
if (!fixedDecimals) {
|
|
183
|
-
str = str.replace(formatDecimalsRegExp, '$1');
|
|
184
|
-
}
|
|
185
|
-
if (thousandsSeparator) {
|
|
186
|
-
str = str.split('.').map(function(s, i) {
|
|
187
|
-
return i === 0 ? s.replace(formatThousandsRegExp, thousandsSeparator) : s;
|
|
188
|
-
}).join('.');
|
|
189
|
-
}
|
|
190
|
-
return str + unitSeparator + unit;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Parse the string value into an integer in bytes.
|
|
194
|
-
*
|
|
195
|
-
* If no unit is given, it is assumed the value is in bytes.
|
|
196
|
-
*
|
|
197
|
-
* @param {number|string} val
|
|
198
|
-
*
|
|
199
|
-
* @returns {number|null}
|
|
200
|
-
* @public
|
|
201
|
-
*/ function parse(val) {
|
|
202
|
-
if (typeof val === 'number' && !isNaN(val)) {
|
|
203
|
-
return val;
|
|
204
|
-
}
|
|
205
|
-
if (typeof val !== 'string') {
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
// Test if the string passed is valid
|
|
209
|
-
var results = parseRegExp.exec(val);
|
|
210
|
-
var floatValue;
|
|
211
|
-
var unit = 'b';
|
|
212
|
-
if (!results) {
|
|
213
|
-
// Nothing could be extracted from the given string
|
|
214
|
-
floatValue = parseInt(val, 10);
|
|
215
|
-
unit = 'b';
|
|
216
|
-
} else {
|
|
217
|
-
// Retrieve the value and the unit
|
|
218
|
-
floatValue = parseFloat(results[1]);
|
|
219
|
-
unit = results[4].toLowerCase();
|
|
220
|
-
}
|
|
221
|
-
if (isNaN(floatValue)) {
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
return Math.floor(map[unit] * floatValue);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
var bytesExports = bytes$2.exports;
|
|
228
|
-
var bytes$1 = /*@__PURE__*/getDefaultExportFromCjs(bytesExports);
|
|
229
|
-
|
|
230
|
-
var commandRender = ((program)=>program.command('render').description('Scans HTML and injects generated CSS rules').argument('<source paths>', 'The path in glob patterns of the source of the HTML file').option('-c --config <path>', 'The source path of the Master CSS configuration', 'master.css').option('-a --analyze', 'Analyze injected CSS and HTML size ( brotli ) without writing to file').action(async function(filePatterns, options = {
|
|
231
|
-
config: 'master.css'
|
|
232
|
-
}) {
|
|
233
|
-
const sourcePaths = explorePathsSync(filePatterns);
|
|
234
|
-
if (sourcePaths.length) {
|
|
235
|
-
const renderStart = process.hrtime();
|
|
236
|
-
const col1Width = Math.max(sourcePaths.reduce((max, current)=>{
|
|
237
|
-
if (current.length > max.length) {
|
|
238
|
-
return current;
|
|
239
|
-
} else {
|
|
240
|
-
return max;
|
|
241
|
-
}
|
|
242
|
-
}).length + 10, 20);
|
|
243
|
-
const col2Width = 8;
|
|
244
|
-
const config = typeof options.config === 'string' ? exploreConfig(options.config, {
|
|
245
|
-
found: (basename)=>log.i`Loaded **${basename}**`
|
|
246
|
-
}) : undefined;
|
|
247
|
-
log``;
|
|
248
|
-
log`${' Source Files'.padEnd(col1Width)}${'CSS Size'.padStart(col2Width)}`;
|
|
249
|
-
await Promise.all(sourcePaths.map(async (filename)=>new Promise((resolve, reject)=>{
|
|
250
|
-
readFile(filename, {
|
|
251
|
-
encoding: 'utf-8'
|
|
252
|
-
}, (err, content)=>{
|
|
253
|
-
if (err) reject(err);
|
|
254
|
-
const { html, css } = render(content, config);
|
|
255
|
-
const renderedCSSText = css?.text;
|
|
256
|
-
const renderedCSSSize = renderedCSSText ? options.analyze ? brotliCompressSync(renderedCSSText).length : renderedCSSText.length : 0;
|
|
257
|
-
if (!options.analyze) {
|
|
258
|
-
if (content !== html) {
|
|
259
|
-
writeFileSync(filename, html);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
const prettifiedCSSSize = bytes$1(renderedCSSSize, {
|
|
263
|
-
space: false
|
|
264
|
-
});
|
|
265
|
-
log.ok`**${filename}**${' '.repeat(col1Width - filename.length - 2)}${prettifiedCSSSize.padStart(col2Width)}`;
|
|
266
|
-
resolve();
|
|
267
|
-
});
|
|
268
|
-
})));
|
|
269
|
-
const renderTime = process.hrtime(renderStart);
|
|
270
|
-
if (options.analyze) {
|
|
271
|
-
log`${' '.repeat(col1Width)}${'(Brotli)'.padStart(col2Width)}`;
|
|
272
|
-
log``;
|
|
273
|
-
log.success`**${sourcePaths.length}** files analyzed in ${prettyHartime(renderTime).replace(' ', '')}`;
|
|
274
|
-
log``;
|
|
275
|
-
log.i`The CSS output will be smaller because it doesn't yet consider the bytes shared with HTML.`;
|
|
276
|
-
} else {
|
|
277
|
-
log`${' '.repeat(col1Width)}${'(Raw)'.padStart(col2Width)}`;
|
|
278
|
-
log``;
|
|
279
|
-
log.success`**${sourcePaths.length}** files rendered in ${prettyHartime(renderTime).replace(' ', '')}`;
|
|
280
|
-
}
|
|
281
|
-
} else {
|
|
282
|
-
log.i`No **${filePatterns}** files found`;
|
|
283
|
-
}
|
|
284
|
-
}));
|
|
285
|
-
|
|
286
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
287
|
-
const __dirname = dirname(__filename);
|
|
288
|
-
const pkg = readJSONFileSync(resolve(__dirname, '../../package.json'));
|
|
289
|
-
const program = new Command();
|
|
290
|
-
program.name(pkg.name).description(pkg.description).version(pkg.version || '0.0.0');
|
|
291
|
-
commandExtract(program);
|
|
292
|
-
commandRender(program);
|
|
293
|
-
program.parse();
|
|
4
|
+
runProgram();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import log from '@techor/log';
|
|
2
|
+
|
|
3
|
+
var commandExtract = ((program)=>program.command('extract').argument('[source paths]', 'The glob pattern path to extract sources').option('-w, --watch', 'Watch file changed and generate CSS rules.').option('-o, --output <path>', 'Specify your CSS file output path').option('-v, --verbose <level>', 'Verbose logging 0~N', '1').option('--no-export', 'Print only CSS results.').option('--options <path>', 'Specify your extractor options sources', 'master.css-extractor').action(async function(specifiedSourcePaths, options) {
|
|
4
|
+
const { CSSExtractor } = await import('@master/css-extractor');
|
|
5
|
+
const { watch, output, verbose, cwd, options: customOptions } = options || {};
|
|
6
|
+
const extractor = new CSSExtractor(customOptions, cwd);
|
|
7
|
+
extractor.on('init', (options)=>{
|
|
8
|
+
if (specifiedSourcePaths?.length) {
|
|
9
|
+
options.include = [];
|
|
10
|
+
options.exclude = [];
|
|
11
|
+
} else {
|
|
12
|
+
if (!options.exclude?.includes('**/node_modules/**')) {
|
|
13
|
+
options.exclude?.push('**/node_modules/**');
|
|
14
|
+
}
|
|
15
|
+
if (!options.exclude?.includes('node_modules')) {
|
|
16
|
+
options.exclude?.push('node_modules');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
options.output = output;
|
|
20
|
+
options.verbose = verbose ? +verbose : options.verbose;
|
|
21
|
+
});
|
|
22
|
+
extractor.init();
|
|
23
|
+
const insert = async ()=>{
|
|
24
|
+
/**
|
|
25
|
+
* true: Ignore `.include` and `.exclude` when specifying sources explicitly.
|
|
26
|
+
* else: Insert according to the source of `.include` - `.exclude`.
|
|
27
|
+
*/ if (specifiedSourcePaths?.length) {
|
|
28
|
+
await extractor.insertFiles(specifiedSourcePaths);
|
|
29
|
+
} else {
|
|
30
|
+
await extractor.insertFiles(extractor.allowedSourcePaths);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
if (watch) {
|
|
34
|
+
const reset = async ()=>{
|
|
35
|
+
await insert();
|
|
36
|
+
/* If the specified source does not exist, watch the .include - .exclude */ if (!specifiedSourcePaths?.length && extractor.options.include) {
|
|
37
|
+
await extractor.watchSource(extractor.options.include, {
|
|
38
|
+
ignored: extractor.options.exclude
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
extractor.on('watchStart', async ()=>{
|
|
43
|
+
await extractor.prepare();
|
|
44
|
+
await reset();
|
|
45
|
+
log``;
|
|
46
|
+
log.t`Start watching source changes`;
|
|
47
|
+
}).on('reset', async ()=>{
|
|
48
|
+
await reset();
|
|
49
|
+
log``;
|
|
50
|
+
log.t`Restart watching source changes`;
|
|
51
|
+
}).on('change', ()=>{
|
|
52
|
+
if (options?.export) {
|
|
53
|
+
extractor.export();
|
|
54
|
+
} else {
|
|
55
|
+
console.log(extractor.css.text);
|
|
56
|
+
}
|
|
57
|
+
}).on('watchClose', ()=>{
|
|
58
|
+
log``;
|
|
59
|
+
log.t`Stop watching source changes`;
|
|
60
|
+
});
|
|
61
|
+
await extractor.startWatch();
|
|
62
|
+
} else {
|
|
63
|
+
await extractor.prepare();
|
|
64
|
+
await insert();
|
|
65
|
+
if (options?.export) {
|
|
66
|
+
extractor.export();
|
|
67
|
+
} else {
|
|
68
|
+
console.log(extractor.css.text);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}));
|
|
72
|
+
|
|
73
|
+
export { commandExtract as default };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import log from '@techor/log';
|
|
2
|
+
import prettyHartime from 'pretty-hrtime';
|
|
3
|
+
import { explorePathsSync } from '@techor/glob';
|
|
4
|
+
import exploreConfig from 'explore-config';
|
|
5
|
+
import { readFile, writeFileSync } from 'fs';
|
|
6
|
+
import { brotliCompressSync } from 'zlib';
|
|
7
|
+
import bytes from 'bytes';
|
|
8
|
+
|
|
9
|
+
var commandRender = ((program)=>program.command('render').description('Scans HTML and injects generated CSS rules').argument('<source paths>', 'The path in glob patterns of the source of the HTML file').option('-c --config <path>', 'The source path of the Master CSS configuration', 'master.css').option('-a --analyze', 'Analyze injected CSS and HTML size ( brotli ) without writing to file').action(async function(filePatterns, options = {
|
|
10
|
+
config: 'master.css'
|
|
11
|
+
}) {
|
|
12
|
+
const { render } = await import('@master/css-server');
|
|
13
|
+
const sourcePaths = explorePathsSync(filePatterns);
|
|
14
|
+
if (sourcePaths.length) {
|
|
15
|
+
const renderStart = process.hrtime();
|
|
16
|
+
const col1Width = Math.max(sourcePaths.reduce((max, current)=>{
|
|
17
|
+
if (current.length > max.length) {
|
|
18
|
+
return current;
|
|
19
|
+
} else {
|
|
20
|
+
return max;
|
|
21
|
+
}
|
|
22
|
+
}).length + 10, 20);
|
|
23
|
+
const col2Width = 8;
|
|
24
|
+
const config = typeof options.config === 'string' ? exploreConfig(options.config, {
|
|
25
|
+
found: (basename)=>log.i`Loaded **${basename}**`
|
|
26
|
+
}) : undefined;
|
|
27
|
+
log``;
|
|
28
|
+
log`${' Source Files'.padEnd(col1Width)}${'CSS Size'.padStart(col2Width)}`;
|
|
29
|
+
await Promise.all(sourcePaths.map(async (filename)=>new Promise((resolve, reject)=>{
|
|
30
|
+
readFile(filename, {
|
|
31
|
+
encoding: 'utf-8'
|
|
32
|
+
}, (err, content)=>{
|
|
33
|
+
if (err) reject(err);
|
|
34
|
+
const { html, css } = render(content, config);
|
|
35
|
+
const renderedCSSText = css?.text;
|
|
36
|
+
const renderedCSSSize = renderedCSSText ? options.analyze ? brotliCompressSync(renderedCSSText).length : renderedCSSText.length : 0;
|
|
37
|
+
if (!options.analyze) {
|
|
38
|
+
if (content !== html) {
|
|
39
|
+
writeFileSync(filename, html);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const prettifiedCSSSize = bytes(renderedCSSSize, {
|
|
43
|
+
space: false
|
|
44
|
+
});
|
|
45
|
+
log.ok`**${filename}**${' '.repeat(col1Width - filename.length - 2)}${prettifiedCSSSize.padStart(col2Width)}`;
|
|
46
|
+
resolve();
|
|
47
|
+
});
|
|
48
|
+
})));
|
|
49
|
+
const renderTime = process.hrtime(renderStart);
|
|
50
|
+
if (options.analyze) {
|
|
51
|
+
log`${' '.repeat(col1Width)}${'(Brotli)'.padStart(col2Width)}`;
|
|
52
|
+
log``;
|
|
53
|
+
log.success`**${sourcePaths.length}** files analyzed in ${prettyHartime(renderTime).replace(' ', '')}`;
|
|
54
|
+
log``;
|
|
55
|
+
log.i`The CSS output will be smaller because it doesn't yet consider the bytes shared with HTML.`;
|
|
56
|
+
} else {
|
|
57
|
+
log`${' '.repeat(col1Width)}${'(Raw)'.padStart(col2Width)}`;
|
|
58
|
+
log``;
|
|
59
|
+
log.success`**${sourcePaths.length}** files rendered in ${prettyHartime(renderTime).replace(' ', '')}`;
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
log.i`No **${filePatterns}** files found`;
|
|
63
|
+
}
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
export { commandRender as default };
|
package/dist/core.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { readJSONFileSync } from '@techor/fs';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import commandExtract from './commands/extract.mjs';
|
|
7
|
+
import commandRender from './commands/render.mjs';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
const pkg = readJSONFileSync(resolve(__dirname, '../package.json'));
|
|
12
|
+
function runProgram(argv = process.argv) {
|
|
13
|
+
const program = new Command();
|
|
14
|
+
program.name(pkg.name).description(pkg.description).version(pkg.version || '0.0.0');
|
|
15
|
+
commandExtract(program);
|
|
16
|
+
commandRender(program);
|
|
17
|
+
program.parse(argv);
|
|
18
|
+
return program;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { runProgram as default };
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@master/css-cli","scripts":{"build":"techor build","dev":"pnpm build --watch","lint":"eslint ./src","type-check":"tsc --noEmit","test":"jest"},"type":"module","license":"MIT","description":"Master CSS CLI","author":"Aoyue Design LLC.","funding":"https://css.master.co/docs/donate","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/cli"},"keywords":["cli","css","mastercss"],"bin":{"mcss":"./dist/bin/index.mjs","mastercss":"./dist/bin/index.mjs"},"files":["dist"],"publishConfig":{"access":"public"},"dependencies":{"@master/css":"^2.0.0-rc.
|
|
1
|
+
{"name":"@master/css-cli","scripts":{"build":"techor build \"src/**/*.ts\" --formats esm","dev":"pnpm build --watch","lint":"eslint ./src","type-check":"tsc --noEmit","test":"jest"},"type":"module","license":"MIT","description":"Master CSS CLI","author":"Aoyue Design LLC.","funding":"https://css.master.co/docs/donate","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/cli"},"keywords":["cli","css","mastercss"],"bin":{"mcss":"./dist/bin/index.mjs","mastercss":"./dist/bin/index.mjs"},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/css":"^2.0.0-rc.19","@master/css-extractor":"^2.0.0-rc.19","@master/css-server":"^2.0.0-rc.19","@techor/extend":"^3.0.16","@techor/fs":"^3.0.16","@techor/glob":"^3.0.16","@techor/log":"^3.0.16","bytes":"^3.1.2","chokidar":"^3.6.0","commander":"^12.0.0","explore-config":"^3.0.16","minimatch":"^9.0.3","pretty-hrtime":"^1.0.3"},"devDependencies":{"@types/pretty-hrtime":"^1.0.3","fast-glob":"^3.3.2"},"version":"2.0.0-rc.19"}
|