Permalink
Browse files

Initial implementation of a Node.js wrapper for the jar execution

  • Loading branch information...
davglass committed Aug 17, 2012
1 parent 7581fdf commit 01f02942923736add8ff996e80b7b0be53379983
Showing with 225 additions and 15 deletions.
  1. +36 −3 README.md
  2. +3 −10 bin/yuicompressor → nodejs/cli.js
  3. +114 −0 nodejs/index.js
  4. +47 −0 nodejs_tests/tests.js
  5. +25 −2 package.json
View
@@ -20,12 +20,45 @@ Testing
./tests/suite.sh
+
+Node.js Package
+---------------
+
+You can require compressor in a Node.js package and compress files and strings in async.
+_It still uses Java under the hood_
+
+ npm i yuicompressor
+
+```javascript
+
+var compressor = require('yuicompressor');
+
+compressor.compress('/path/to/file or String of JS', {
+ //Compressor Options:
+ charset: 'utf8',
+ type: 'js',
+ nomunge: true,
+ 'line-break': 80
+}, function(err, data, extra) {
+ //err If compressor encounters an error, it's stderr will be here
+ //data The compressed string, you write it out where you want it
+ //extra The stderr (warnings are printed here in case you want to echo them
+});
+
+```
+
+Options:
+* `charset` // defaults to 'utf8'
+* `type` // defaults to 'js'
+* `line-break`
+* `nomunge`
+* `preserve-semi`
+* `disable-optimizations`
+
+
TODO
----
-* Proper Unit Tests
-* Proper Node.js Module
- * Wrapper for use in a Node.js process
* Better Docs
* Help Pages
@@ -7,17 +7,10 @@ for easy CLI use
var spawn = require('child_process').spawn,
fs = require('fs'),
- path = require('path'),
- args = process.argv.slice(2),
- lists = fs.readdirSync(path.join(__dirname, '../build'));
-
-lists.some(function(item) {
- if (path.extname(item) === '.jar') {
- args.unshift(path.join(__dirname, '../build/', item));
- return true;
- }
-});
+ compressor = require('./index'),
+ args = process.argv.slice(2);
+args.unshift(compressor.jar);
args.unshift('-jar');
var cmd = spawn('java', args);
View
@@ -0,0 +1,114 @@
+
+var spawn = require('child_process').spawn,
+ fs = require('fs'),
+ path = require('path'),
+ jar,
+ exists = fs.exists || path.exists,
+ lists = fs.readdirSync(path.join(__dirname, '../build'));
+
+lists.some(function(item) {
+ if (path.extname(item) === '.jar') {
+ jar = path.join(__dirname, '../build/', item);
+ return true;
+ }
+});
+
+exports.jar = jar;
+
+var defaultOptions = {
+ charset: 'utf8',
+ type: 'js'
+};
+
+var validOptions = {
+ charset: 1,
+ type: 1,
+ 'line-break': 1,
+ nomunge: 1,
+ 'preserve-semi': 1,
+ 'disable-optimizations': 1
+};
+
+var getString = function(str, callback, options) {
+ exists(str, function(y) {
+ if (y) {
+ var ext = (path.extname(str)).replace('.', '');
+ fs.readFile(str, 'utf8', function(err, data) {
+ //Set the type from the file name
+ options.type = ext;
+ callback(err, data, options);
+ });
+ } else {
+ callback(null, str, options);
+ }
+ });
+};
+
+
+var filterOptions = function(options) {
+ Object.keys(options).forEach(function(key) {
+ if (!validOptions[key]) {
+ delete options[key];
+ }
+ });
+
+ options.type = options.type || 'js';
+ options.charset = options.charset || 'utf8';
+ return options;
+};
+
+var compressString = function(str, options, callback) {
+ //Now we have a string, spawn and pipe it in.
+
+ options = filterOptions(options);
+
+ var args = [
+ '-jar',
+ jar
+ ], buffer = '', errBuffer = '', child;
+
+ Object.keys(options).forEach(function(key) {
+ args.push('--' + key);
+ if (options[key] && options[key] !== true) {
+ args.push(options[key]);
+ }
+ });
+
+ child = spawn('java', args, {
+ stdio: ['pipe', 'pipe', 'pipe']
+ });
+
+ child.stdin.write(str);
+ child.stdin.end();
+
+ child.stdout.on('data', function(chunk) {
+ buffer += chunk;
+ });
+ child.stderr.on('data', function(chunk) {
+ errBuffer += chunk;
+ });
+
+ child.on('exit', function() {
+ var err = null;
+ if (errBuffer.indexOf('[ERROR]') > -1) {
+ err = errBuffer;
+ }
+ callback(err, buffer, errBuffer);
+ });
+};
+
+var compress = function(str, options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = defaultOptions;
+ }
+
+ getString(str, function(err, str, options) {
+
+ compressString(str, options, callback);
+
+ }, options);
+};
+
+exports.compress = compress;
+exports.compressString = compressString;
View
@@ -0,0 +1,47 @@
+var YUITest = require('yuitest'),
+ Assert = YUITest.Assert,
+ suite = new YUITest.TestSuite('YUICompressor Tests'),
+ path = require('path'),
+ fs = require('fs'),
+ compressor = require('../nodejs/index'),
+ exists = fs.existsSync || path.existsSync;
+
+
+var base = path.join(__dirname, '../tests');
+var files = fs.readdirSync(base);
+var testFiles = [];
+
+files.forEach(function(file) {
+ var ext = path.extname(file);
+ if (ext === '.js' || ext === '.css') {
+ var comp = path.join(base, file + '.min');
+ if (exists(comp)) {
+ testFiles.push({
+ type: ext.replace('.', ''),
+ test: file,
+ result: (fs.readFileSync(path.join(base, file + '.min'), 'utf8')).trim()
+ });
+ }
+ }
+});
+
+testFiles.forEach(function(item) {
+ suite.add(new YUITest.TestCase({
+ name: item.test,
+ 'test: compress': function() {
+ var test = this;
+ compressor.compress(path.join(base, item.test), {
+ type: item.type,
+ charset: 'utf8'
+ }, function(err, out) {
+ test.resume(function() {
+ Assert.areSame(out, item.result, 'Failed to properly compress');
+ });
+ });
+ test.wait();
+ }
+ }));
+
+});
+
+YUITest.TestRunner.add(suite);
View
@@ -1,11 +1,34 @@
{
"name": "yuicompressor",
- "description": "Simple install for YUICompressor CLI",
+ "description": "YUICompressor CLI and Node.js require",
"version": "2.4.8pre",
+ "author": "Dav Glass <davglass@gmail.com>",
+ "bugs": { "url" : "http://yuilibrary.com/projects/yuicompressor/newticket" },
"devDependencies": {
"yuitest": "*"
},
+ "keywords": [
+ "yui", "compressor", "munger", "cssmin", "minify", "minification"
+ ],
+ "main": "./nodejs/index.js",
"bin": {
- "yuicompressor": "./bin/yuicompressor"
+ "yuicompressor": "./nodejs/cli.js"
+ },
+ "files": [
+ "build/*.jar",
+ "nodejs"
+ ],
+ "scripts": {
+ "test": "./node_modules/.bin/yuitest ./nodejs_tests/tests.js"
+ },
+ "licenses":[
+ {
+ "type" : "BSD",
+ "url" : "http://yuilibrary.com/license/"
+ }
+ ],
+ "repository": {
+ "type":"git",
+ "url":"https://github.com/yui/yuicompressor"
}
}

0 comments on commit 01f0294

Please sign in to comment.