cleancss 3.7 KB

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