cleancss
3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env node
var util = require('util');
var fs = require('fs');
var path = require('path');
var CleanCSS = require('../index');
var commands = require('commander');
var packageConfig = fs.readFileSync(path.join(path.dirname(fs.realpathSync(process.argv[1])), '../package.json'));
var buildVersion = JSON.parse(packageConfig).version;
var isWindows = process.platform == 'win32';
// Specify commander options to parse command line params correctly
commands
.version(buildVersion, '-v, --version')
.usage('[options] <source-file>')
.option('-e, --remove-empty', 'Remove empty declarations, e.g. .a{}')
.option('-b, --keep-line-breaks', 'Keep line breaks')
.option('--s0', 'Remove all special comments, i.e. /*! comment */')
.option('--s1', 'Remove all special comments but the first one')
.option('-r, --root [root-path]', 'Set a root path to which resolve absolute @import rules')
.option('-o, --output [output-file]', 'Use [output-file] as output instead of STDOUT')
.option('-s, --skip-import', 'Disable @import processing')
.option('--skip-rebase', 'Disable URLs rebasing')
.option('-d, --debug', 'Shows debug information (minification time & compression efficiency)');
commands.on('--help', function() {
util.puts(' Examples:\n');
util.puts(' %> cleancss one.css');
util.puts(' %> cleancss -o one-min.css one.css');
if (isWindows) {
util.puts(' %> type one.css two.css three.css | cleancss -o merged-and-minified.css');
} else {
util.puts(' %> cat one.css two.css three.css | cleancss -o merged-and-minified.css');
util.puts(' %> cat one.css two.css three.css | cleancss | gzip -9 -c > merged-minified-and-gzipped.css.gz');
}
util.puts('');
process.exit();
});
commands.parse(process.argv);
var options = {
source: null,
target: null
};
var cleanOptions = {};
var fromStdin = !process.env['__DIRECT__'] && !process.stdin.isTTY;
// If no sensible data passed in just print help and exit
if (!fromStdin && commands.args.length == 0) {
commands.outputHelp();
return 0;
}
// Now coerce commands into CleanCSS configuration...
if (commands.output)
cleanOptions.target = options.target = commands.output;
if (commands.removeEmpty)
cleanOptions.removeEmpty = true;
if (commands.keepLineBreaks)
cleanOptions.keepBreaks = true;
if (commands.s1)
cleanOptions.keepSpecialComments = 1;
if (commands.s0)
cleanOptions.keepSpecialComments = 0;
if (commands.root)
cleanOptions.root = commands.root;
if (commands.skipImport)
cleanOptions.processImport = false;
if (commands.skipRebase)
cleanOptions.noRebase = true;
if (commands.debug)
options.debug = true;
if (commands.args.length > 0) {
var source = commands.args[0];
options.source = source;
cleanOptions.relativeTo = path.dirname(path.resolve(source));
}
// ... and do the magic!
if (options.source) {
fs.readFile(options.source, 'utf8', function(error, data) {
if (error)
throw error;
output(minify(data));
});
} else {
var stdin = process.openStdin();
stdin.setEncoding('utf-8');
var data = '';
stdin.on('data', function(chunk) {
data += chunk;
});
stdin.on('end', function() {
output(minify(data));
});
}
function minify(data) {
var minified;
if (options.debug) {
var start = process.hrtime();
minified = CleanCSS.process(data, cleanOptions);
var taken = process.hrtime(start);
console.error('Minification time: %dms', ~~(taken[0] * 1e3 + taken[1] / 1e6));
console.error('Compression efficiency: %d%', ~~((1 - minified.length / CleanCSS.originalSize) * 100));
} else {
minified = CleanCSS.process(data, cleanOptions);
}
return minified;
}
function output(minified) {
if (options.target)
fs.writeFileSync(options.target, minified, 'utf8');
else
process.stdout.write(minified);
};