【nodejs】nodejs版seajs圧縮配置ツール


プロジェクトの中でseajsモジュール化の使用は開発の時に来るのは確かに手間が省けますが、seajsのメカニズムによる要請が多すぎて、オンラインに直接配置しにくいです.玉伯にはspm配置のツールがありますが、今のspmプロジェクトの利用性はまだそんなに高くないと分かりました.だから自分でセットの発表の構造をやります.
 
seajsには二つのdefineの形式があります.
 
define(function(require, exports, module){});
  和
 
define("friend-middleware.js",["lib/jquery.js","lib/underscore.js"],function(){});
 
下の一つは上の簡単な書き方です.モジュール定義が多く、モジュール配列に依存する二つのパラメータが選択可能ですが、この二つのパラメータはいくつかの違いがあります.最初は内部クローズドでrequireモジュールを閉じ込める時に、直接指定経路に行くデgetSrcutです.この方法は一つのファイルのモジュールを保証しなければなりません.次の書き方は同じファイルに複数のモジュールを置くことができます.モジュール定義後、他のモジュールが同じファイル呼び出し変更モジュールは、依存リストにモジュールの定義を追加すればいいです.このように、この特性を使ってモジュールに依存して圧縮することができます.また、圧縮するなら、cssを探して、もう一つのcssファイルを圧縮します.
 
発表を便利にするために、nodejsを使って編集して、機会に乗じてnodeを勉強します.js圧縮はnodeバージョンのglifyJsを使いました.この圧縮ツールはgoogleと圧縮したものとあります.jQueryの圧縮もそれを使いました.cssの圧縮はやはりycのcss圧縮ツールのnode版を使いました.
 
 
(function(){
	var fs = require('fs'),
		jsp = require('./lib/uglify-js').parser,
		pro = require('./lib/uglify-js').uglify,
		cssmin = require('./lib/node-css-compressor').cssmin,
		_ = require('./lib/underscore.js');
		
	var	compressCode = '',
		compressCss = '',
		dependCssList = [],
		jsPath = 'D:/Workspace/BB/deploy/htdocs/js/' //   css    path  
		
		pubilcJsFile = [
			//      
		],
		jsFileArray = [
			//       
		];
	
		
	
	var log = function(arg){
		console.log(arg);
	};
	
	var replaceForDepend = function(filename, code){
		var dependenceArray = [];
		var modulename = filename.replace(/^.*\/js\//i,'');
		code.replace(/require\('(.+)'\)/ig, function(){
			var match = arguments[1];
			if(/\.css$/i.test(match)){
				dependCssList.push(jsPath + match);
				return;
			}
			if(!(/\.js$/i.test(match))){
				match += '.js';
			}
			dependenceArray.push('"' + match + '"');
		});
		code = code.replace(/define\(function\(/, 'define(\'' + modulename + '\', [' + dependenceArray.join(',') + '], function(');
		code = code.replace("/require\('(.+\.css)'\)/i", '', code);
		return code;
	};
	
	var compress = function(str ,type){
		if (type === 'javascript') {
			var orig_code = str;
			var ast = jsp.parse(orig_code);
			ast = pro.ast_lift_variables(ast);
			ast = pro.ast_mangle(ast);
			ast = pro.ast_squeeze(ast);
			var finalCode = pro.gen_code(ast);
			return finalCode;
		}else if(type === 'css'){
			return cssmin(str);
		}else{
			return str;
		}
	};
	

	var writeFinalCode = function(file, str){
		fs.writeFile(file, str, 'utf8', function (err) {
		  if (err) throw err;
		  console.log('It\'s saved to ' + file + '!');
		});
	};

	var _init = function(argv0,argv1){
		var minJsFile = argv0 || 'babylon.js';
		var minCssFile = argv1 || 'babylon.css';
		var i, pdata, data, rdata;
		
		log('Javascript analyze start!');
		for(i = 0; i < pubilcJsFile.length ; ++i){
			pdata = fs.readFileSync(pubilcJsFile[i], 'utf8');
			compressCode += pdata;
			log(pubilcJsFile[i] + ' complete!');
		}
		for(i = 0; i < jsFileArray.length; ++i){
			data = fs.readFileSync(jsFileArray[i], 'utf8');
			rdata = replaceForDepend(jsFileArray[i], data);
			compressCode += rdata;
			log(jsFileArray[i]  + ' complete!')
		}
		
		log('Javascript compress start!');
		compressCode = compress(compressCode, 'javascript');

		log('CSS analyze start!');
		dependCssList = _.uniq(dependCssList)
		for (i = 0; i < dependCssList.length; ++i) {
			cdata = fs.readFileSync(dependCssList[i], 'utf8');
			compressCss += cdata;
			log(dependCssList[i] + ' complete!');
		}
		log('Css compress start!');
		compressCss = compress(compressCss, 'css');
		
		writeFinalCode(minJsFile, compressCode);
		
		writeFinalCode(minCssFile, compressCss);
	}

	return _init;
})()(process.argv[2],process.argv[3]);
 
コアとは、コード=code.replace(/define\/、'define(\'+modulename+'''''''、'、'+dependenceAray.join('、')+'')、function(')という文が入れ替わります.また、モジュール内で引用されたcssファイルを取り出して一つのcssモジュールに圧縮し、コードを導入します.
 
でも、書類が多いと、jsListは多くの書類を置くことになります.
以下は第二のバージョンで、自動的にjsファイルを検索する圧縮です.
 
var configure = {
	targetPath : 'D:/Workspace/BB/deploy/htdocs/js',
	publicJs : ['sea.js','jquery.js','underscore.js','underscore.string.js'],
	exceptJs : [	
					//               
					//dir-path
					'seajs',
					//js-file
					'core.js',
				],
	additionalJs : [
					//  js       
				]
};

(function(config){
	var fs = require('fs'),
		path = require('path'),
		jsp = require('./lib/uglify-js').parser,
		pro = require('./lib/uglify-js').uglify,
		cssmin = require('./lib/node-css-compressor').cssmin,
		_ = require('./lib/underscore.js');
		
	var	compressCode = '',
		compressCss = '',
		dependCssList = [],
		jsPath = 'D:/Workspace/BB/deploy/htdocs/js/',
		pubilcJsFile = [],
		jsFileArray = [];
	
		
	
	var log = function(arg){
		console.log(arg);
	};
	
	var replaceForDepend = function(filename, code){
		var dependenceArray = [];
		var modulename = filename.replace(/^.*\/js\//i,'');
		code.replace(/require\('(.+)'\)/ig, function(){
			var match = arguments[1];
			if(/\.css$/i.test(match)){
				dependCssList.push(jsPath + match);
				return;
			}
			if(!(/\.js$/i.test(match))){
				match += '.js';
			}
			dependenceArray.push('"' + match + '"');
		});
		code = code.replace(/define\(function\(/, 'define(\'' + modulename + '\', [' + dependenceArray.join(',') + '], function(');
		code = code.replace("/require\('(.+\.css)'\)/i", '', code);
		return code;
	};
	
	var compress = function(str ,type){
		if (type === 'javascript') {
			var orig_code = str;
			var ast = jsp.parse(orig_code , false);
			ast = pro.ast_lift_variables(ast);
			ast = pro.ast_mangle(ast);
			ast = pro.ast_squeeze(ast);
			var finalCode = pro.gen_code(ast, {quote_keys : true, ascii_only : true});
			return finalCode;
		}else if(type === 'css'){
			return cssmin(str);
		}else{
			return str;
		}
	};
	
	var analyzePath = function(pathname){
		var pathList = fs.readdirSync(pathname);
		for (var index in pathList){
			var filename = pathList[index];
			if ( !_.include(config.exceptJs,filename) && !(/\.svn/.test(filename)) && !(/\.css/.test(filename)) && !(/\.txt/.test(filename)) && !(/\.html/.test(filename)) ){
				var pt = path.join(pathname , filename);
				if(((path.existsSync(pt)) && (fs.lstatSync(pt).isDirectory()))){
					analyzePath(pt);
				}
				if(((path.existsSync(pt)) && (fs.lstatSync(pt).isFile()))){
					if(_.include(config.publicJs,filename)){
						pubilcJsFile.push(pt);
					}else{
						jsFileArray.push(pt);
					}
					
				}
			}
		}
	};
	

	var writeFinalCode = function(file, str){
		fs.writeFile(file, str, 'utf8', function (err) {
		  if (err) throw err;
		  console.log('It\'s saved to ' + file +'!');
		});
	};

	var _init = function(argv0,argv1){
		var minJsFile = argv0 || 'babylon.js';
		var minCssFile = argv1 || 'babylon.css';
		var i, pdata, data, rdata;
		
		analyzePath(config.targetPath);
		
		log('Javascript compress start!');
		for(i = 0; i < pubilcJsFile.length ; ++i){
			pdata = fs.readFileSync(pubilcJsFile[i], 'utf8');
			compressCode += pdata + '


'; log(pubilcJsFile[i] + ' complete!'); } jsFileArray = _.union(config.additionalJs, jsFileArray); for(i = 0; i < jsFileArray.length; ++i){ data = fs.readFileSync(jsFileArray[i], 'utf8'); rdata = replaceForDepend(jsFileArray[i], data); compressCode += rdata; log(jsFileArray[i] + ' complete!'); } compressCode = compress(compressCode, 'javascript'); log('CSS compress start!'); dependCssList = _.uniq(dependCssList) for (i = 0; i < dependCssList.length; ++i) { cdata = fs.readFileSync(dependCssList[i], 'utf8'); compressCss += cdata + '
'; log(dependCssList[i] + ' complete!'); } compressCss = compress(compressCss, 'css'); writeFinalCode(minJsFile, compressCode); writeFinalCode(minCssFile, compressCss); } return _init; })(configure)(process.argv[2],process.argv[3]);
 ただし、上のバージョンはuglifyに対してエラーが発生する場合があります.テストしたら、最初のバージョンのほうが安定しています.使い方は直接cmdに入力します.
 
 
 
node combo [js  ] [css  ]
 
足りないものはみんなでれんがをたたいてください.