totorojs
Version:
895 lines (859 loc) • 24.7 kB
JavaScript
// -*- js -*-
/*
* 名称: totoro
* 描述: totoro是一个前端工程化解决方案 名字源于宫崎骏动画片龙猫
* 日期: 2014.12.29
* 编写: 单骑闯天下
*/
//遍历文件夹,获取所有文件夹里面的文件信息
/*
* @param path 路径
*
*/
var compilerTag=require('./compiler');
var fs=require('fs');
function geFileList(path)
{
var filesList = [];
readFile(path,filesList);
return filesList;
}
//遍历读取文件
function readFile(path,filesList)
{
files = fs.readdirSync(path);//需要用到同步读取
files.forEach(walk);
function walk(file)
{
states = fs.statSync(path+'/'+file);
if(states.isDirectory())
{
readFile(path+'/'+file,filesList);
}
else
{
//创建一个对象保存信息
var obj = new Object();
obj.size = states.size;//文件大小,以字节为单位
obj.name = file;//文件名
obj.path = path+'/'+file; //文件绝对路径
if((/(\w+)\.(js|xhtml)$/).test(obj.path)){
filesList.push(obj);
}else{
//console.log(obj.path)
}
}
}
}
global.FILEDIR='';
var sys = require("sys");
var htmlparser = require("./htmlparser");
function parseXhtml(path,fn){
var call=fn;
// var jsp = require("./parse-js");
// var process = require("./process");
// var findScript=function(obj,fn){
// obj.forEach(function(e,i){
// if(e.type=='script'){
// fn(e.children);
// }else{
// if(e.children){
// findScript(e.children,fn);
// }
// }
// });
// };
//var rawHtml = "<script>var a=2;function(){};</script>";
var handler = new htmlparser.DefaultHandler();
// console.log(handler,1)
var parser = new htmlparser.Parser(handler);
// console.log(parser,1)
function callBack(err,data){
if(err){
console.log("error:"+err);
}else{
parser.ParseComplete(data);
//sys.puts(sys.inspect(handler.dom, false, null));
// var fn=function(data){
// //console.log(data[0].data);
// var ast = jsp.parse(data[0].data);
// //console.log(ast)
// console.log(JSON.stringify(ast));
// };
//findScript(handler.dom,fn);
call(handler.dom);
}
}
fs.readFile(path,"utf-8",callBack);
};
function buildMainFile(path,output){
var callBack=function(arr){
//sys.puts(sys.inspect(arr, false, null));
var html='';
var createHTML=function(arr){
arr.forEach(function(e,i){
if(e.type=='directive'){
html+='<'+e.raw+'>';
}else if(e.type=='text'){
html+=e.raw;
}else if(e.type=='tag'&&e.name!='meta'){
html+='<'+e.raw+'>';
if(e.children){
createHTML(e.children);
}
html+='</'+e.raw+'>';
}
else if(e.type=='tag'&&e.name=='meta'){
html+='<'+e.raw+' />';
}
else if(e.type=='script'&&!e.children){
var src=e.attribs.src;
src.replace(/(\w+\.js)/g,function(e){
html+='<script src="./'+e+'"></script>';
});
}
else if(e.type=='script'&&e.children){
html+='<'+e.raw+'>';
if(e.children){
createHTML(e.children);
}
html+='</script>';
}
});
};
createHTML(arr);
console.log('首页入口文件生成:'+output+'index.html');
fs.writeFileSync(output+'index.html',html);
};
parseXhtml(path,callBack);
}
var totoro=({
BUILD:'totoro.json',// 工程配置文件
ROOTDIR:'',// 工程根目录
FS:null,
PATH:null,
PROCESS:null,
RELEASEARR:[],
PROCESSARR:[],
UGLIFYJS:null,
URL:null,
HTTP:null,
manifest:null,
colors:null,
STYLUS:null,
flieList:[],
build:null,// 工程配置数据
manifestConfig:null,
serverHtml:'',//服务器页面
v:"1.1.2",
tagFileTarget:null,
output:null,
mainFile:'',
config:{
"projects":[{
"server":"index.html",
"target":"test/index.js",
"compiler":["test/index_min.js",'test/a.js'],
"publish":"test/release/index.js",
"include":["test/src/js/"],
"cssCompile":["test/src/css/stylus.styl"],
"template":["test/src/template/"]
}],
"manifest":{
"linkPrefix":"http://cdn.xxx.com/",
"manifestSuffix":"manifest",
"outputRoot":"./output/",
"cache":{
"offline":[
"index.html"
]
},
"network":["*"],
"fallback":[
"/fallback.html"
]
}
},
init:function(process,require){
this.ROOTDIR=process.argv[2]||__dirname;
this.HTTP=require('http');
this.FS=require('fs');
this.PATH=require('path');
this.URL=require('url');
this.colors=require('./colors/safe');
this.STYLUS=require('stylus');
this.colors.setTheme({
silly:'rainbow',
input:'grey',
verbose:'cyan',
prompt:'grey',
info:'green',
data:'grey',
help:'cyan',
warn:'yellow',
debug:'blue',
error:'red'
});
this.BUILD=this.ROOTDIR;
global.FILEDIR=this.ROOTDIR;
this.UGLIFYJS=null;
this.PROCESS=require("child_process");
var msg=this.msg(),
command=this.command(),
merger=this.merger;
msg.hello(this.ROOTDIR);
//console.log(this.readdir('./test',1,'stylus'));
merger.call(this,this.ROOTDIR);
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data',function(chunk){
var cmd=chunk.replace(/\r\n/g,'').replace(/[\r\n]/g,'').replace(/\s+/," ").trim().split(' ');
if(command[cmd[0]]){
command[cmd[0]].apply(this,cmd.slice(1));
}
});
},
msg:function(){
var _this=this;
return {
log:function(msg,type){
var a=type||0,
b=['Ok:','Error:','Warning:','Prompt:','Data:'];
switch(a){
case 0:(console.log(_this.colors.info(b[a]+msg+"\r\n")));break;
case 1:(console.log(_this.colors.error(b[a]+msg+"\r\n")));break;
case 2:(console.log(_this.colors.warn(b[a]+msg+"\r\n")));break;
case 3:(console.log(_this.colors.prompt(b[a]+msg+"\r\n")));break;
case 4:(console.log(_this.colors.data(b[a]+msg+"\r\n")));break;
default:break;
}
},
hello:function(dir){
console.log(_this.colors.info('----------------------------------'));
console.log(_this.colors.info('\0\0\0\0\0\0\0\0Welcome to Totoro'));
console.log(_this.colors.info('\0\0\0\0\0\0前端工程化集成解决方案'));
console.log(_this.colors.info('\0\0\0\0\0\0\0\0\0\0\0\0\0v'+_this.v));
console.log(_this.colors.info('----------------------------------'));
console.log(_this.colors.info('\r\nTotoro初始化完毕开始工程目录监听:'+dir+'/\r\n'));
},
help:function(msg){
console.log(_this.colors.help(msg+"\r\n"));
}
};
},
command:function(){
var _this=this,
msg=this.msg();
return {
init:function(prop){
//
},
reset:function(){
_this.PROCESSARR.forEach(function(tm){
clearInterval(tm);
});
_this.RELEASEARR=[];
msg.log('重启中...');
_this.merger.call(_this,_this.ROOTDIR);
},
gcc:function(level){
level=(level==2)?2:1;
_this.compiler(level);
},
publish:function(){
_this.publish();
},
check:function(){
_this.check();
},
v:function(){
msg.log(' v '+_this.v);
},
server:function(level){
var port=(level)?level:8888;
_this.server(port);
},
manifest:function(){
_this.createManifest();
},
css:function(){
_this.stylus(arguments);
},
help:function(){
msg.help("---------------------------------------");
msg.help(" gcc 压缩目标文件");
msg.help(" reset 重启");
msg.help(" publish 发布目标文件");
msg.help(" check js代码审核");
msg.help(" server -port(端口号)\0启动内置调试服务器");
msg.help(" manifest 执行创建manifest离线配置文件");
msg.help(" css 执行css文件预编译");
msg.help(" v 获取版本号");
msg.help("---------------------------------------");
}
};
},
// 广度优先搜索给定目录的所有文件 支持递归搜索 第二个参数为1开启递归搜索 第三个参数指定搜索给定的后缀文件
readdir:function(){
var fs=this.FS,
path=this.PATH,
_this=this,
result=!0;
;(function(para,args,suffix){
var dir=para?para:'.',
arg=arguments,
dirList=fs.readdirSync(dir);
dirList.forEach(function(e){
if(suffix&&path.extname(e)==('.'+suffix)){
if(_this.isFile(dir+'/'+e)=='file'){
_this.flieList.push(dir+'/'+e);
result=!0
}
}
(!suffix)&&(_this.isFile(dir+'/'+e)=='file')&&(_this.flieList.push(dir+'/'+e),result=!0);
});
(args)&&(
dirList.forEach(function(e){
(_this.isFile(dir+'/'+e)=='dir')&&(
arg.callee(dir+'/'+e,!0,suffix)
)
})
);
}(arguments[0],arguments[1],arguments[2]));
if(result)return(_this.flieList);
},
// 判断是文件还是目录
isFile:function(){
var fs=this.FS,
a=fs.statSync(arguments[0]).isFile(),
b=fs.statSync(arguments[0]).isDirectory(),
is=a?'file':(b?'dir':0);
return is;
},
/*
* 根据指定的目录遍历查找"package.json",如果查找到,建立map进行变更监听
* @param {String} dir 目录地址
*/
merger:function(dir){
var _this=this,
buildFile=dir+'/totoro.json',
fs=_this.FS,
msg=_this.msg();
fs.exists(buildFile,function(exists){
exists?(fs.readFile(buildFile,function(err,data){
_this.map.call(_this,dir,new Function('return '+data)());
})):'';
});
fs.readdir(dir,function(err,files){
files&&files.length&&files.forEach(function(item){
fs.statSync(dir+'/'+item).isDirectory()&&_this.merger.call(_this,dir+'/'+item);
});
});
},
/*
* @class map 根据路径和对应的配置文件,生成监听map
* @param {String} dir 路径
* @param {Object} build 配置
*/
map:function(dir,build){
var that=this,
_this=this,
msg=this.msg(),
fs=this.FS,
path=_this.PATH,
processArr=_this.PROCESSARR;
_this.build=build;
that.manifestConfig=build.manifest;
var _projects=build.projects, //工程配置
_path=dir+'/', //根路径
_mainMap={}, //{合并后的文件名:{include:JS文件数组,template:模版文件数组}}
_fileMap={}, //{合并前的单个文件名:{target:合并后的文件名,time:最后更新时间,type:JS/模版}}
_tmplMap={}; //{合并后的文件名:模版字符串}
var getRealPath = function(p){
return _this.PATH.normalize(/\:|^\//.test(p)?p:_path+'/'+p);
};
//获取文件列表
var getFileList=function(fileList){
var files=[];
fileList && fileList.forEach(function(item){
if(fs.existsSync(getRealPath(item))){
if(fs.statSync(getRealPath(item)).isDirectory()){
var items=fs.readdirSync(getRealPath(item));
items.forEach(function(_item){
if(/^\..+/.test(_item)){
return
}
files.push(item+'/'+_item);
});
}else{
files.push(item);
}
}else{
msg.log(getRealPath(item)+' does not exist',1);
}
});
return files;
};
//当有文件更新时进行合并操作
var merge=function(file,target,type,mtime){
var pool=[];
target.forEach(function(item){
//用于存储当前唯一文件名,防读写冲突
//合并JS
//应F总需求,这里做一个include为空的判断。
//如果include为空,这把当前target的代码作为合并后的代码,来进行模版匹配
//新增代码中模版标识为/*TPL.XX.YY*/somecode/**/的模式匹配
var fileName=getRealPath(item),code;
if(_mainMap[item].include.length){
_mainMap[item].include.forEach(function(item){
if(fs.existsSync(getRealPath(item))){
pool.push(fs.readFileSync(getRealPath(item)));
}else{
msg.log(getRealPath(item)+' does not exist',1);
}
});
codes=pool.join("\r\n");
}else{
codes=fs.readFileSync(fileName)+'';
}
var tmp={},i=0;
for(var p in _tmplMap[item]){
var n = p.replace(/\./g,"\\.");
var r = new RegExp("\\/\\*<"+n+">\\*\\/(.*?)\\/\\*<\\/"+n+">\\*\\/",'g')
codes=codes.replace(r,function(match){
i++;
tmp[i] = "/*<"+p+">*/'"+_tmplMap[item][p]+"'/*</"+p+">*/";
return '<@'+i+'@>';
});
codes=codes.replace(new RegExp(p.replace(/\./g,"\\."),'g'),function(match){
i++;
tmp[i] = "/*<"+p+">*/'"+_tmplMap[item][p]+"'/*</"+p+">*/";
return '<@'+i+'@>';
});
codes=codes.replace(/<@(\d+)@>/g,function(match,i){
return tmp[i];
});
}
fs.writeFileSync(fileName,codes);
msg.log("文件合并完成:"+path.normalize(fileName));
});
};
var fs = require('fs')
//定时监听_fileMap发现文件更新
var listen=function(){
var tm = setInterval(function(){
for(var p in _fileMap){
//先检测文件是否存在
if(fs.existsSync(getRealPath(p))){
var mtime=+fs.statSync(getRealPath(p)).mtime;
mtime!=_fileMap[p].time&&function(){
msg.log('源文件有修改:'+path.normalize(getRealPath(p)),2);
_fileMap[p].time=mtime;
merge(p,_fileMap[p].target,_fileMap[p].type,mtime);
}()
}else{
msg.log(getRealPath(p)+' 文件不存在!',1);
}
}
},1000);
processArr.push(tm);
};
//根据工程配置初始化map
var _init=function(){
if(_this.PATH.normalize(_path+_this.BUILD)){
msg.log('发现工程配置文件:'+_this.PATH.normalize(_path+_this.BUILD));
}
console.log(_projects)
tagFileTarget=_projects.target;
output=_projects.output;
mainFile=_projects.main;
//console.log(geFileList(tagFileTarget))
//遍历工程
// _projects.forEach(function(item){
// _mainMap[item.target]={};
// _mainMap[item.target].include=getFileList(item.include);
// _mainMap[item.target].template=getFileList(item.template);
// //一个文件可能在多个工程中被使用
// _mainMap[item.target].include.forEach(function(_item){
// _fileMap[_item]=_fileMap[_item]||{target:[],time:+_this.FS.statSync(getRealPath(_item)).mtime,type:'js'};
// _fileMap[_item].target.push(item.target);
// });
// _mainMap[item.target].template.forEach(function(_item){
// _fileMap[_item]=_fileMap[_item]||{target:[],time:+_this.FS.statSync(getRealPath(_item)).mtime,type:'tmpl'};
// _fileMap[_item].target.push(item.target);
// });
// _this.RELEASEARR.push({
// compiler:getRealPath(item.compiler || item.target),
// publish:item.publish?getRealPath(item.publish):'',
// src:getRealPath(item.target),
// server:getRealPath(item.server)
// });
// });
//console.log(_mainMap)
//初始化合并
// for(var p in _mainMap){
// //merge(_mainMap[p].include[0],[p],'js',new Date());
// }
//listen();
};
_init();
},
/*
* 压缩选项
* @param {Number} level 压缩级别 1-普通压缩,2-深度压缩
*/
compiler:function(level){
var list=geFileList(this.BUILD+tagFileTarget);
var that=this;
var msg=this.msg();
var fn=function(o){
o.m.log('编译'+o.f.name+'文件成功,output:'+o.o+( (o.f.name).replace('.xhtml','.js') ),0);
}
var that=this;
list.forEach(function(e,i){
var obj={f:e,m:msg,o:(that.BUILD+output)};
//parseXhtml(e.path);
compilerTag.call(obj,e.name,e.path,(that.BUILD+output),fn);
});
buildMainFile(this.BUILD+mainFile,this.BUILD+output);
/*
var _this=this,
path=_this.PATH,
msg=_this.msg(),
fs=_this.FS,
proc=_this.PROCESS,
releaseArr=_this.RELEASEARR,
uglifyjs=this.UGLIFYJS;
console.log(uglifyjs)
var exec=function(sFileName,cFileName,option){
//this.COMPILER
console.log(sFileName,cFileName,option)
msg.log("正在压缩文件:"+path.normalize(sFileName));
try{
var compiler=proc.exec('node uglifyjs '+sFileName+option,function(error,stdout,stderr){
if(error){
msg.log("文件压缩错误"+error,1);
}else{
stdout=_this.method().removeConsole(stdout);
fs.writeFileSync(cFileName,stdout);
//已压缩
msg.log("文件压缩完成:"+path.normalize(cFileName));
}
});
}catch(e){
msg.log("文件压缩错误"+e.message,1);
}
};
var option={1:"--compilation_level WHITESPACE_ONLY",2:' -m'}[level];
console.log(releaseArr)
releaseArr.forEach(function(item){
exec(item.src,item.compiler,option);
});*/
},
check:function(){
var _this=this,
msg=_this.msg(),
fs=_this.FS,
proc=_this.PROCESS,
releaseArr=_this.RELEASEARR;
var exec=function(sFileName){
try{
var compiler=proc.exec('jshint '+sFileName,function(error,stdout){
if(stdout){
msg.log("预编译错误!\n\r"+stdout,1);
}else{
msg.log("恭喜!预编译成功!");
}
});
}catch(e){
msg.log("jshint错误或者命令错误!",1);
}
};
releaseArr.forEach(function(item){
exec(item.src);
});
},
server:function(port){
var _this=this,
msg=_this.msg(),
fs=_this.FS,
proc=_this.PROCESS,
http=_this.HTTP,
url=_this.URL,
path=_this.PATH,
fileName=(_this.RELEASEARR[0]).server;
var exec=function(fileName){
try{
http.createServer(function(request,response){
var pathname=url.parse(request.url).pathname,
realPath=path.join(pathname),
index=path.extname(realPath);
fileName=index?index:fileName;
if(!_this.serverHtml){
_this.serverHtml=fileName;
}
fs.exists(_this.serverHtml,function (exists){
if(!exists){
response.writeHead(404, {
'Content-Type': 'text/plain'
});
response.write('404:文件不存在!');
response.end();
}else{
fs.readFile(_this.serverHtml,'utf8',function(err,file){
if(err){
response.writeHead(500,{
'Content-Type': 'text/html;charset=utf-8'
});
response.end(err);
}else{
var contentType="text/html;charset=utf-8";
response.writeHead(200,{
'Content-Type':contentType
});
response.write(file,"utf8");
response.end();
msg.log('服务器访问中...首页文件路径:'+_this.serverHtml,3);
}
});
}
});
}).listen(port);
msg.log('服务器创建成功,服务器访问地址:127.0.0.1:'+port);
}catch(e){
msg.error("服务器创建错误!");
}
};
exec(fileName);
},
createManifest:function(){
var _this=this,
msg=_this.msg(),
fs=_this.FS,
path=_this.PATH;
var jsonParse=function(jsonStr){
return new Function('return ' + jsonStr)();
};
var mergeArray=function(origin,list){
for(var i=0,item;item=list[i];i++){
if(origin.indexOf(item)===-1){
origin.push(item);
}
}
};
var readConfig=function(config){
var content=fs.readFileSync(config).toString();
config=jsonParse(content);
return config;
};
var pickupJs=function(url){
var content=fs.readFileSync(url).toString();
var reg=/<script\s+.*?src="?([^"]+)"?[^>]+>/gi;
var jss=[];
content.replace(reg,function(m,u1){
jss.push(u1);
});
return jss;
};
var pickupCss=function(url,manifest,config){
var content=fs.readFileSync(url).toString();
var maniReg=/(<html.+manifest="?)[^"]*("?[^>]*>)/i;
if(maniReg.test(content)){
content=content.replace(maniReg,'$1' + manifest + '$2');
}else{
var attr='manifest="' + manifest + '" ';
content=content.replace(/(<html)([^>]*>)/i,'$1' + attr + '$2');
}
var filename=path.join(config.outputRoot,url);
fs.writeFileSync(filename,content);
var reg=/<link\s+.*?href="?([^"]+)"?[^>]+>/gi;
var attReg=/rel="?\bstylesheet\b"?/i;
var csss=[];
content.replace(reg,function(m,u1){
if(attReg.test(m)){
csss.push(u1);
}
});
return csss;
};
var pickupImg=function(url,config){
url=url.split('?')[0];
url=config.linkPrefix?url.replace(config.linkPrefix,''):url;
var content=fs.readFileSync(url).toString();
var styleRoot=path.join(config.linkPrefix,path.dirname(url));
var reg=/url\(["']?([^"')]+)["']?\)/gi;
var imgs=[];
content.replace(reg,function(m,u1){
imgs.push(path.join(styleRoot,u1));
});
return imgs;
};
var writeManifest=function(name,list,config){
//write cache
var record=[];
record.push('CACHE MANIFEST');
record.push('CACHE:');
record=record.concat(list);
//write network
record.push('NETWORK:');
record=record.concat(config.network);
//write fallback
record.push('FALLBACK:');
record=record.concat(config.fallback);
//write timestamp
record.push('#totoro @' + +new Date);
var content=record.join('\n');
var filename=path.join(config.outputRoot,name);
fs.writeFile(filename,content,function(){
msg.log('创建manifest文件成功!');
});
};
var main=function(configFile){
var config=_this.manifestConfig;
var cacheList=config.cache;
var htmls,csss,jss,imgs,list,manifest;
for(var name in cacheList){
list=[];
htmls=cacheList[name];
manifest=name + '.' + config.manifestSuffix;
for(var i=0,html;html=htmls[i];i++){
//收集 html
list.push(html);
//收集 js
jss=pickupJs(html);
mergeArray(list,jss);
//收集 css
csss=pickupCss(html,manifest,config);
mergeArray(list,csss);
//收集 css 里面的图片
for(var j=0,css;css=csss[j];j++){
imgs=pickupImg(css,config);
mergeArray(list,imgs);
}
}
//创建 manifest
//writeManifest(manifest,list,config);
}
console.log(htmls,csss,jss,imgs,list,manifest)
};
main();
},
publish:function(){
var releaseArr=this.RELEASEARR,
msg=this.msg(),
fs=this.FS;
var that=this;
releaseArr.forEach(function(item){
console.log(that.BUILD+item.src)
fs.readFile(that.BUILD+item.src,function(err,data){
if(err){
msg.log("源文件读取失败:"+err.message,1);
}else if(item.publish){
fs.writeFile(item.publish,data+"",function(err){
if(err){
msg.log("文件发布失败:"+err.message,1);
}else{
msg.log("文件发布成功:"+item.publish);
}
});
}
});
});
},
/*
* 如果只有一个参数可以为('目录名或者文件名,如果两者都没找到,则寻找配置文件查找')
* 如果有两个参数,第一个参数为(-0\-1,代表是否压缩),可以为('目录名或者文件名,如果两者都没找到,则寻找配置文件查找')
*/
stylus:function(para){
var _this=this,
fs=this.FS,
configFilePath,// css预编译的工程配置文件
arr=[{compress:false},{compress:true}],
fileData,
fileList;
var fn=function(p,c,s){
var is=_this.isFile(p);
if(is=='file'){
fileData=fs.readFileSync(p,"utf8");
_this.cssCompile(fileData,arr[c],p);
}
if(is=='dir'){
fileList=_this.readdir(p,0,s);
fileList.forEach(function(e){
fileData=fs.readFileSync(e,"utf8");
fileData&&_this.cssCompile(fileData,arr[c],e);
});
}
if(is==0){
if(this.build){// 如果工程配置文件存在
configFilePath=this.build.projects;
}
fileList=_this.readdir('.',1,'stylus');
fileList.forEach(function(e){
fileData=fs.readFileSync(e,"utf8");
_this.cssCompile(fileData,arr[0],e);
});
}
};
if(para[0]&&!para[1]){
fn(para[0],1,'stylus');
}
if(para[0]&¶[1]){
var r=para[0].substr(0,1);
if(r!='-'){
return;
}
r=para[0].substr(1);
fn(para[1],r,'stylus');
}
},
cssCompile:function(file,obj,name){
var stylus=this.STYLUS,
fs=this.FS,
msg=this.msg(),
path=this.PATH,
suffix=path.extname(name),
dir=path.dirname(name);
name=path.basename(name,suffix);
stylus.render(file,obj,function(error,css){
if(error){
msg.log("css编译错误"+error,1);
}else{
fs.writeFileSync(dir+'/'+name+'-min.css',css);
msg.log("css预编译完成:"+dir+'/'+name+'-min.css');
}
});
},
method:function(){
var _this=this,
uglifyjs=this.UGLIFYJS;
return {
removeConsole:function(str){
var nodeArr=[],
string=str,
onde,start_pos,end_pos,replacement,
ast=uglifyjs.parse(str),
spliceString=function(str,begin,end,replacement){
return str.substr(0,begin)+str.substr(end);
};
ast.figure_out_scope();
ast.walk(new uglifyjs.TreeWalker(function(nodeObj){
if(nodeObj instanceof uglifyjs.AST_SimpleStatement){
if(nodeObj.print_to_string({beautify:true}).substr(0,7)=='console'){
nodeArr.push(nodeObj);
}
}
}));
for(var i=nodeArr.length;--i>=0;){
node=nodeArr[i];
start_pos=node.start.pos;
end_pos=node.end.endpos;
replacement=node.print_to_string({beautify:true});
string=spliceString(string,start_pos,end_pos,replacement);
}
return string;
}
}
}
}).init(process,require);