1.nodejs的源码有优势和劣势是什么?
2.nodejsç¼è¯ï¼
3.为什么nodejs运行显示命令?
4.最强 nodejs 下 C++绑定方案介绍
nodejs的优势和劣势是什么?
一个规模稍微大点的系统都不是一种开发语言可以搞定的,往往是源码有几种混杂一起,比如c、源码有c++做服务器端开发,源码有java做业务逻辑,源码有php等做前端展示,源码有php登录签到源码此外还需要消息中间件等等。源码有nodejs可以很快地在服务器端做原型(原来只有c系和java等能做的源码有事情,性能还很高),源码有而且代码量相对会少很多;另一点是源码有它的语法优势,js闭包等。源码有但它不太适合做cpu密集型处理的源码有工作,只能绕着弯去解决,源码有据说这次QCon会有人分享这方面的源码有研究成果,可以关注下。源码有每种语言都有它适合的领域,没必要强求一门语言可以解决所有事情,拥有其它语言的特性,只有不断的tradeoff把系统做出来才是目标。nodejsç¼è¯ï¼
nodejsç¼è¯åjsæ件ååç¼
Node.jsæ¯ä¸ä¸ªåºäºChromeV8å¼æçJavaScriptè¿è¡ç¯å¢ã
Nodeä¸javaScriptçåºå«å¨äºï¼javaScriptç顶å±å¯¹è±¡æ¯window,ènodeæ¯global
//è¿é使ç¨çvar声æçåéä¸æ¯å ¨å±çï¼æ¯å½å模åä¸çï¼ç¨global声æç表示æ¯å ¨å±ç
vars=;
global.s=;
//è¿é访é®å°çsæ¯varçå½ç
console.log(s);//
//è¿é访é®å°çææ¯å ¨å±åé
console.log(global.s);//
模åï¼å¨nodeä¸ï¼æ件å模åæ¯ä¸ä¸å¯¹åºçï¼ä¹å°±æ¯ä¸ä¸ªæ件就æ¯ä¸ä¸ªæ¨¡åï¼æ¯ä¸ªæ¨¡åé½æèªå·±çä½ç¨åï¼æ们éè¿varç³æçåé并éå ¨å±èæ¯è¯¥æ¨¡åä½ç¨åä¸çã
ï¼2ï¼module模å
1ãæ件æ¥æ¾
1ï¼é¦å æç §å è½½ç模åçæ件å称è¿è¡æ¥æ¾ï¼å¦æ没ææ¾å°ï¼åä¼å¸¦ä¸.jsã.jsonæ.nodeæå±åå¨å è½½
2ï¼ä»¥'/'为åç¼ç模åæ¯æ件çç»å¯¹è·¯å¾ãä¾å¦ï¼require('/home/marco/foo.js')ä¼å è½½/home/marco/foo.jsæ件ã
3ï¼ä»¥'./'为åç¼ç模åæ¯ç¸å¯¹äºè°ç¨require()çæ件çãä¹å°±æ¯è¯´ï¼circle.jså¿ é¡»åfoo.jså¨åä¸ç®å½ä¸ä»¥ä¾¿äºrequire('./circle')æ¾å°å®ã
4ï¼å½æ²¡æ以'/'ã'./'æ'../'å¼å¤´æ¥è¡¨ç¤ºæ件æ¶ï¼è¿ä¸ªæ¨¡åå¿ é¡»æ¯ä¸ä¸ªæ ¸å¿æ¨¡åæå è½½èªnode_modulesç®å½ã
5ï¼å¦æç»å®çè·¯å¾ä¸åå¨ï¼årequire()ä¼æåºä¸ä¸ªcodeå±æ§ä¸º'MODULE_NOT_FOUND'çErrorã
2ãmoduleä½ç¨å
å¨ä¸ä¸ªæ¨¡åä¸éè¿varå®ä¹çåéï¼å ¶ä½ç¨åèå´æ¯å½å模åï¼å¤é¨ä¸è½å¤ç´æ¥ç访é®ï¼å¦ææ们æ³ä¸ä¸ªæ¨¡åè½å¤è®¿é®å¦å¤ä¸ä¸ªæ¨¡åä¸å®ä¹çåéï¼å¯ä»¥æä¸ä¸ä¸¤ç§æ¹å¼ï¼
1ï¼æåéä½ä¸ºglobal对象çä¸ä¸ªå±æ§ï¼ä½è¿æ ·çåæ³æ¯ä¸æ¨èç
2ï¼ä½¿ç¨æ¨¡å对象moduleãmoduleä¿åæä¾åå½å模åæå ³çä¸äºä¿¡æ¯ã
å¨è¿ä¸ªmodule对象ä¸æä¸ä¸ªå对象exports对象ï¼æ们å¯ä»¥éè¿è¿ä¸ªå¯¹è±¡æä¸ä¸ªæ¨¡åä¸çå±é¨åé对象è¿è¡æä¾è®¿é®ã
//è¿ä¸ªæ¹æ³çè¿åå¼ï¼å ¶å®å°±æ¯è¢«å 载模åä¸çmodule.exports
require('./.js');
3ã__dirnameï¼å½å模åçç®å½åã
ä¾åï¼å¨/Users/mjrç®å½ä¸è¿è¡nodeexample.jsï¼
console.log(__dirname);
//è¾åº:/Users/mjr
console.log(path.dirname(__filename));
//è¾åº:/Users/mjr
4ã__filenameï¼å½å模åçæ件åï¼å¤çåçç»å¯¹è·¯å¾ï¼ãå½å模åçç®å½åå¯ä»¥ä½¿ç¨__dirnameè·åã
å¨/Users/mjrç®å½ä¸è¿è¡nodeexample.jsï¼
console.log(__filename);
//è¾åº:/Users/mjr/example.js
console.log(__dirname);
//è¾åº:/Users/mjr
ï¼3ï¼processï¼è¿ç¨ï¼
process对象æ¯ä¸ä¸ªå ¨å±åéï¼æä¾Node.jsè¿ç¨çæå ³ä¿¡æ¯ä»¥åæ§å¶è¿ç¨ãå 为æ¯å ¨å±åéï¼æ以æ é使ç¨require()ã
1ãprocess.argv
è¿åè¿ç¨å¯å¨æ¶çå½ä»¤è¡åæ°ã第ä¸ä¸ªå ç´ æ¯process.execPathã第äºä¸ªå ç´ æ¯å½åæ§è¡çJavaScriptæ件çè·¯å¾ãå©ä½çå ç´ é½æ¯é¢å¤çå½ä»¤è¡åæ°ã
console.log(process.argv);
æå°ç»æï¼
2ãprocess.execPathè¿åå¯å¨è¿ç¨çå¯æ§è¡æ件çç»å¯¹è·¯å¾ã
3ãprocess.envè¿åç¨æ·çç¯å¢ä¿¡æ¯ã
å¨process.envä¸å¯ä»¥æ°å¢å±æ§ï¼
process.env.foo='bar';
console.log(process.env.foo);
å¯ä»¥éè¿deleteå é¤å±æ§ï¼
deleteprocess.env.foo;
console.log(process.env);
å¨Windowsä¸ï¼ç¯å¢åéä¸åºå大å°å
4ãprocess.pidå±æ§è¿åè¿ç¨çPIDã
5ãprocess.platformå±æ§è¿åå符串ï¼æ è¯Node.jsè¿ç¨è¿è¡å ¶ä¸çæä½ç³»ç»å¹³å°ã
6ãprocess.titleå±æ§ç¨äºè·åæ设置å½åè¿ç¨å¨pså½ä»¤ä¸æ¾ç¤ºçè¿ç¨åå
7ãprocess.uptime()æ¹æ³è¿åå½åNode.jsè¿ç¨è¿è¡æ¶é´ç§é¿
注æ:该è¿åå¼å å«ç§çåæ°ã使ç¨Math.floor()æ¥å¾å°æ´ç§éã
8ãprocess.versionså±æ§è¿åä¸ä¸ªå¯¹è±¡ï¼æ¤å¯¹è±¡ååºäºNode.jsåå ¶ä¾èµççæ¬ä¿¡æ¯ã
process.versions.modules表æäºå½åABIçæ¬ï¼æ¤çæ¬ä¼éçä¸ä¸ªC++APIååèå¢å ãNode.jsä¼æç»å 载模åï¼å¦æè¿äºæ¨¡å使ç¨ä¸ä¸ªä¸åABIçæ¬ç模åè¿è¡ç¼è¯ã
9ãprocess对象-è¾å ¥è¾åºæµ
vara;
varb;
process.stdout.write('请è¾å ¥açå¼:');
process.stdin.on('data',(chunk)={
if(!a){
a=Number(chunk);
process.stdout.write('请è¾å ¥bçå¼:');
}else{
b=Number(chunk);
process.stdout.write('a+bçå¼:'+(a+b));
process.exit();
}
});
ï¼4ï¼Bufferç¼å²å¨
Bufferç±»ï¼ä¸ä¸ªç¨äºæ´å¥½çæä½äºè¿å¶æ°æ®çç±»ï¼æ们å¨æä½æ件æè ç½ç»æ°æ®çæ¶åï¼å ¶å®æä½çå°±æ¯äºè¿å¶æ°æ®æµï¼Node为æ们æä¾äºä¸ä¸ªæ´å æ¹ä¾¿çå»æä½è¿ç§æ°æ®æµçç±»Buffer,ä»æ¯ä¸ä¸ªå ¨å±çç±»
1ãå¦ä½å建使ç¨buffer
Buffer.from(array)è¿åä¸ä¸ªBufferï¼å å«ä¼ å ¥çåèæ°ç»çæ·è´ã
Buffer.from(arrayBuffer[,byteOffset[,length]])è¿åä¸ä¸ªBufferï¼ä¸ä¼ å ¥çArrayBufferå ±äº«å åã
Buffer.from(buffer)è¿åä¸ä¸ªBufferï¼å å«ä¼ å ¥çBufferçå 容çæ·è´ã
Buffer.from(string[,encoding])è¿åä¸ä¸ªBufferï¼å å«ä¼ å ¥çå符串çæ·è´ã
Buffer.alloc(size[,fill[,encoding]])è¿åä¸ä¸ªæå®å¤§å°ä¸å·²åå§åçBufferã该æ¹æ³æ¯Buffer.allocUnsafe(size)æ ¢ï¼ä½è½ç¡®ä¿æ°å建çBufferä¸ä¼å å«æ§æ°æ®ã
Buffer.allocUnsafe(size)ä¸Buffer.allocUnsafeSlow(size)è¿åä¸ä¸ªæå®å¤§å°ä½æªåå§åçBufferãå 为Bufferæ¯æªåå§åçï¼å¯è½å å«æ§æ°æ®ã
//å建ä¸ä¸ªé¿åº¦ä¸ºãä¸ç¨å¡«å çBufferã
constbuf1=Buffer.alloc(,1);
//å建ä¸ä¸ªé¿åº¦ä¸ºãä¸æªåå§åçBufferã
//è¿ä¸ªæ¹æ³æ¯è°ç¨Buffer.alloc()æ´å¿«ï¼ä½è¿åçBufferå®ä¾å¯è½å å«æ§æ°æ®ï¼å æ¤éè¦ä½¿ç¨fill()æwrite()éåã
constbuf2=Buffer.allocUnsafe();
constbuf3=Buffer.from([1,2,3]);
constbuf4=Buffer.from('tést');
console.log(buf1);//Buffer
console.log(buf2);//Buffer
console.log(buf3);//Buffer
console.log(buf4);//Bufferc3a
2ãBuffer对象æä¾çtoStringãJSONç使ç¨
1ï¼buf.toString(encodingï¼startï¼end)
varbf=Buffer.from('miaov');
console.log(bf.toString('utf-8',1,4));//iaov
console.log(bf.toString('utf-8',0,5));//miaov
console.log(bf.toString('utf-8',0,6));//miaov
2ï¼buf.write(stringï¼offsetï¼lengthï¼encoding)
stringè¦åå ¥bufçå符串ã
offsetå¼å§åå ¥çå移éãé»è®¤0ï¼è¿éæçæ¯buffer对象çèµ·å§è¦åå ¥çä½ç½®ã
lengthè¦åå ¥çåèæ°ãé»è®¤ä¸ºbuf.length-offsetã
encodingstringçå符ç¼ç ãé»è®¤ä¸º'utf8'ã
è¿å:å·²åå ¥çåèæ°ã
varstr="miaovhello";
varbf=Buffer.from(str);
varbf2=Buffer.alloc(8);
//ä»0å¼å§åå ¥5个
bf2.write(str,0,5);
console.log(bf);
console.log(bf2);
3ï¼buf.toJSON()
constbuf=Buffer.from([0x1,0x2,0x3,0x4,0x5]);
constjson=JSON.stringify(buf);
console.log(json);
//è¾åº:{ "type":"Buffer","data":[1,2,3,4,5]}
3ãBufferä¸éææ¹æ³ç使ç¨
1ï¼Buffer.isEncoding(encoding)ï¼å¤ææ¯å¦æ¯Bufferæ¯æçå符ç¼ç ï¼æ¯åè¿åtrueï¼ä¸æ¯åè¿åfalse
console.log(Buffer.isEncoding('utf-8'));//true
2ï¼Buffer.isBuffer(obj)ï¼å¦æobjæ¯ä¸ä¸ªBufferï¼åè¿åtrueï¼å¦åè¿åfalseã
ï¼5ï¼fsï¼æ件系ç»ï¼
该模åæ¯æ ¸å¿æ¨¡åï¼éè¦ä½¿ç¨require('fs')å¯¼å ¥å使ç¨ï¼è¯¥æ¨¡å主è¦ç¨æ¥æä½æ件
1ãfs.open(path,flags,mode,callback)
pathï¼è¦æå¼çæ件çè·¯å¾ï¼
flagsï¼æå¼æ件çæ¹å¼è¯»/åï¼
modeï¼è®¾ç½®æ件ç模å¼è¯»/å/æ§è¡
callback(errï¼fd)ï¼æ件æå¼ä»¥åï¼å¨åè°å½æ°ä¸åç¸åºçå¤ç,åè°å½æ°ç两个åæ°ï¼
errï¼æ件æå¼å¤±è´¥çé误ä¿åå¨erréé¢ï¼å¦ææåerr为null
fdï¼è¢«æå¼æ件çæ è¯
varfs=require('fs');
fs.open('./test.txt','r',function(err,fd){
if(err){
console.log("æ件æå¼å¤±è´¥");
}else{
console.log("æ件æå¼æå");
}
});
2ãfs.openSync(path,flags,mode)ï¼è¿åæ件æ述符ã
varfs=require('fs');
console.log(fs.openSync('./test.txt','r'));//3
3ãfs.read(fd,buffer,offset,length,position,callback)
ä»fdæå®çæ件ä¸è¯»åæ°æ®ï¼
bufferæå®è¦åå ¥æ°æ®çbufferï¼
offsetæå®bufferä¸å¼å§åå ¥çå移éï¼
lengthæå®è¦è¯»åçåèæ°ï¼
positionæå®æ件ä¸å¼å§è¯»åçå移éãå¦æposition为nullï¼åä»æ件çå½åä½ç½®å¼å§è¯»åï¼
callbackæä¸ä¸ªåæ°(err,bytesRead,buffer)
示ä¾ï¼test.txtä¸çå¼ä¸º
fs.open('./test.txt','r',function(err,fd){
if(!err){
varbf=Buffer.alloc(5);
fs.read(fd,bf,0,5,0,function(){
console.log(bf.toString());//
})
}
});
4ãfs.write(fd,buffer,offset,length,position,callback)
å°bufferåå ¥å°fdæå®çæ件ã
offsetæå®bufferä¸è¦å¼å§è¢«åå ¥çå移éï¼lengthæå®è¦åå ¥çåèæ°ã
positionæå®æ件ä¸è¦å¼å§åå ¥çå移éãå¦ætypeofposition!=='number'ï¼åä»å½åä½ç½®å¼å§åå ¥ã
callbackæä¸ä¸ªåæ°(err,bytesWritten,buffer)ï¼å ¶ä¸bytesWrittenæå®bufferä¸å·²åå ¥æ件çåèæ°ã
varfs=require('fs');
fs.open('./test.txt','r+',function(err,fd){
if(!err){
varbf=Buffer.alloc(5);
fs.read(fd,bf,0,5,0,function(){
console.log(bf.toString());//
});
varbf=Buffer.from('testæ°æ®');
fs.write(fd,bf,0,,0);
fs.write(fd,'æµè¯æ°æ®2',,'utf-8');
}
});
fs.write(fd,string,position,encoding,callback)
å°stringåå ¥å°fdæå®çæ件ãå¦æstringä¸æ¯ä¸ä¸ªå符串ï¼åä¼å¼ºå¶è½¬æ¢æå符串ã
positionæå®æ件ä¸è¦å¼å§åå ¥çå移éãå¦ætypeofposition!=='number'ï¼åä»å½åä½ç½®å¼å§åå ¥ã
encodingæå®å符串çç¼ç ã
callbackæä¸ä¸ªåæ°(err,written,string)ï¼å ¶ä¸writtenæå®å符串ä¸å·²åå ¥æ件çåèæ°ãåå ¥çåèæ°ä¸å符串çå符æ°æ¯ä¸åçã
5ãfs.exists(path,callback)æ£æ¥æå®è·¯å¾çæ件æè ç®å½æ¯å¦åå¨
fs.appendFile(path,data,callback)ï¼å°æ°æ®è¿½å å°æ件ï¼å¦ææ件ä¸åå¨åå建æ件ã
//æ£æ¥æ件æ¯å¦åå¨
varfs=require('fs');
varfilename='./test2.txt';
fs.exists(filename,function(isExists){
if(!isExists){
fs.writeFile(filename,'miaov',function(err){
if(err){
console.log("æ件å建失败");
}else{
console.log("æ件å建æå");
}
});
}else{
fs.appendFile(filename,'-leo',function(err){
if(err){
console.log("æ件å 容追å 失败");
}else{
console.log("æ件å 容追å æå");
}
})
}
});
ï¼6ï¼å端项ç®èªå¨åæ建
1ãå建myProject项ç®æ件以å对åºçæ件夹
varprojectData={
'name':'myProject',
'fileData':[
{
'name':'css',
'type':'dir'
},{
'name':'js',
'type':'dir'
},{
'name':'images',
'type':'dir'
},{
'name':'index.html',
'type':'file',
'content':'html\n\thead\n\t\ttitletitle/title\n\t/head\n\tbody\n\t\th1Hello/h1\n\t/body\n/html'
}
]
};
varfs=require('fs');
if(projectData.name){
//å建项ç®æ件夹
fs.mkdirSync(projectData.name);
varfileData=projectData.fileData;
if(fileDatafileData.length){
fileData.forEach(function(file){
//æ件ææ件夹路å¾
file.path='./'+projectData.name+'/'+file.name;
//æ ¹æ®typeç±»åå建æ件ææ件夹
file.content=file.content||'';
switch(file.type){
case'dir':
fs.mkdirSync(file.path);
break;
case'file':
fs.writeFileSync(file.path,file.content);
break;
default:
break;
}
});
}
}
2ãèªå¨æå å¤ä¸ªæ件
varfs=require('fs');
varfiledir='./myProject/dist';
fs.exists(filedir,function(isExists){
if(!isExists){
fs.mkdirSync(filedir);
}
fs.watch(filedir,function(ev,file){
//åªè¦æä¸ä¸ªæ件åçäºååï¼æ们就éè¦å¯¹æ件夹ä¸çæææ件è¿è¡è¯»åãå并
fs.readdir(filedir,function(err,dataList){
vararr=[];
dataList.forEach(function(file){
if(file){
//statSyncæ¥çæ件å±æ§
varinfo=fs.statSync(filedir+'/'+file);
//modeæ件æé
if(info.mode===){
arr.push(filedir+'/'+file);
}
}
});
//读åæ°ç»ä¸çæ件å 容
varcontent='';
arr.forEach(function(file){
varc=fs.readFileSync(file);
content+=c.toString()+'\n';
});
//å并æ件ä¸çå 容
fs.writeFileSync('./myProject/js/index.js',content);
})
});
});
ï¼7ï¼ä½¿ç¨nodeè¿è¡webå¼å
1ãæ建ä¸ä¸ªingMessageçä¸ä¸ªå®ä¾ï¼è·å请æ±çä¸äºä¿¡æ¯ï¼å¦å¤´ä¿¡æ¯ï¼æ°æ®ç
htt
为什么nodejs运行显示命令?
在 Node.js 中,有一个内置的分销代理源码命令行界面(CLI),它允许你通过命令行直接执行 JavaScript 代码,而不需要先创建和运行一个完整的文件或者应用程序。
如果你在 Node.js 中运行的是一个 JavaScript 文件,那么该文件中所有的输出都会被发送到控制台中进行显示。但是,如果你在 Node.js 中直接输入一段代码,那么它通常只会返回一个简短的内容或者一个对象,而不是将整个代码块都打印出来。
为了解决这个问题,你可以使用 Node.js 的搭配网源码 REPL 模式(Read Eval Print Loop),它会在控制台中显示你输入的完整的代码块,并等待你输入下一行代码。要进入 REPL 模式,你只需要在 terminal 中输入 node 命令即可。
例如,在 terminal 中输入以下命令:
node
然后按回车键,就可以进入 Node.js 的 REPL 模式,你可以在其中输入 JavaScript 代码并对其进行交互式调试和测试。当你想退出 REPL 模式时,可以输入 .exit 命令或者按下 Ctrl + C。微窗源码
最强 nodejs 下 C++绑定方案介绍
作者:john 近期,我利用 puerts创建了一个nodejs扩展,方便地结合C++库。让我们通过比较知名的v8pp方案来探讨它们的异同点: 相似之处在于,两者都是为nodejs提供C++库的接入。然而,puerts的创新在于它不仅致力于改进v8/C++绑定,还提出了一套跨语言交互的API,即语言无关的原生扩展标准。这个标准允许无须重新编译,电脑管家源码便能在如UE/Unity游戏引擎、nodejs、lua等环境中无缝使用,你可以通过下载 puerts_addon_demos来体验。而nodejs原生扩展在electron环境下加载,需要借助electron工具进行定制编译,如using-native-node-modules。 在HelloWorld示例中,puerts展示了如何便捷地将C++代码导出给addonjs调用,同样也能应用于lua。puerts提供了生成声明文件的工具,例如:首先安装puerts工具
将生成的声明文件放入typing目录
在ts工程的tsconfig.json中添加typing目录,享受代码提示和检查功能
接下来,我们以HelloWorld为例,了解puerts在nodejs中的初步应用,更多内容请参考文档和示例。文章接下来将深入探讨设计和实现,重点讨论两个主题:跨虚拟机的FFI抽象设计
C还是C++的选择
在FFI抽象设计中,考虑到不同脚本引擎(如Lua、v8等)的交互模式,作者希望创建一个统一的接口,便于在多种环境使用。对于C++接口的选择,作者强调了C的兼容性优势,避免因版本不一致导致的问题。 关于性能,puerts提供模板绑定与pesapi的选择,前者虽然简洁,但性能略逊于直接调用v8 API。通过加入PES_EXTENSION_WITH_V8_API宏,性能可以显著提升,尽管这会增加对v8的依赖。此外,puerts还支持v8的fast api call特性,尽管需要一些调试和优化,但实测性能提升明显。 总之,puerts为nodejs与C++的结合提供了一种高效且灵活的解决方案,通过其独特的设计和性能优化,使得跨语言交互变得更加顺畅和高效。