大家好,很高兴又见面了,我是web前端分享,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1。理解Node发版规律1。1什么Semver? Semver,Sem是Semantic(语义的)之意,ver是Version(版本)之意。整体表示一种版本命名的方式,要体现一定的版本变更内容的含义。目前的Semver一般指由Semver。org组织制定的版本规范。其基本要求如下:版本号的基本形式为MAJOR。MINOR。PATCH3部分组成,每个部分的含义如下:MAJOR:软件的API改变MINOR:修改或添加功能,但保持向后兼容(API未变)PATCH:补丁,主要是错误修复 Semver的含义1。2LTS(LongTermSupport)与Current含义? 关于Node。js的发布流程,有以下几个要点:每6个月发布一个主要版本(即Major版本),作为Current版本。注意:它可能是奇数版本也可能是偶数版本。但是,因为其是最新的,所以包含Node。js平台的最新特性4月发布偶数版本,10月发布奇数版本每12个月将一个版本转入LTS版本,LTS代表了一个被不断修正与改进的版本。LTS版本要经历两个阶段:活跃期(Active)与维护期(Maintenance)活跃期共18个月,即在不改变兼容性的情况下,周期性修改Bug并合并其他版本的重要修改(1)每个时刻Current版本只有一个,LTS版本可能有3个,LTSActive版本可能有2个。在Node。js官网中给出的LTS版本总是处于LTS的最新版本 (2)该版本处于活跃期(Ative)时,可以看到其MINOR版本在不断升级维护期共12个月,只负责修改本版本的Bug以及特别紧急问题的修复,如安全性问题 下面是Node官网的最新信息,即最新Current版本V19。2。0、而LTS版本为V18。12。1版。 Node19最新版本发布2。Nodev19带来那些特性?2。1HTTP(S)1。1KeepAlive默认为true Node。jsv19将keepAlive的默认值设置为true,这意味着所有HTTP(s)连接将默认启动HTTP1。1的keepAlive,默认时间为5S。consthttprequire(node:http);http链接console。log(http。globalAgent);consthttpsrequire(node:https);https链接console。log(https。globalAgent); 我们可以对比下v16和v19的节点服务器Agent配置差异,首先切换到V16版本:nvmuse16nowusingnodev16。0。0(npmv7。10。0)nodeserver 输入信息如下:agent{events:〔Object:nullprototype〕{free:〔function(anonymous)〕,newListener:〔Function:maybeEnableKeylog〕},eventsCount:2,maxListeners:undefined,defaultPort:80,protocol:http:,options:〔Object:nullprototype〕{path:null},requests:〔Object:nullprototype〕{},sockets:〔Object:nullprototype〕{},freeSockets:〔Object:nullprototype〕{},keepAliveMsecs:1000,keepAlive:false,maxSockets:Infinity,maxFreeSockets:256,schedule:lifo,maxTotalSockets:Infinity,totalSocketCount:0,〔Symbol(kCapture)〕:false}agent{events:〔Object:nullprototype〕{free:〔function(anonymous)〕,newListener:〔Function:maybeEnableKeylog〕},eventsCount:2,maxListeners:undefined,defaultPort:443,protocol:https:,options:〔Object:nullprototype〕{path:null},requests:〔Object:nullprototype〕{},sockets:〔Object:nullprototype〕{},freeSockets:〔Object:nullprototype〕{},keepAliveMsecs:1000,keepAlive:false,maxSockets:Infinity,maxFreeSockets:256,schedule:lifo,maxTotalSockets:Infinity,totalSocketCount:0,maxCachedSessions:100,sessionCache:{map:{},list:〔〕},〔Symbol(kCapture)〕:false} 第5、37行,keepAlive默认值设置为false。接着请看下面的V19输出,首先切换到19版本:nvmuse19nowusingnodev19。0。0(npmv8。19。2)nodeserver 输出信息如下:agent{events:〔Object:nullprototype〕{free:〔function(anonymous)〕,newListener:〔Function:maybeEnableKeylog〕},eventsCount:2,maxListeners:undefined,defaultPort:80,protocol:http:,options:〔Object:nullprototype〕{keepAlive:true,schedule:lifo,timeout:5000,noDelay:true,path:null},requests:〔Object:nullprototype〕{},sockets:〔Object:nullprototype〕{},freeSockets:〔Object:nullprototype〕{},keepAliveMsecs:1000,keepAlive:true,这里是truemaxSockets:Infinity,maxFreeSockets:256,schedule:lifo,maxTotalSockets:Infinity,totalSocketCount:0,〔Symbol(kCapture)〕:false}agent{events:〔Object:nullprototype〕{free:〔function(anonymous)〕,newListener:〔Function:maybeEnableKeylog〕},eventsCount:2,maxListeners:undefined,defaultPort:443,protocol:https:,options:〔Object:nullprototype〕{keepAlive:true,schedule:lifo,timeout:5000,noDelay:true,path:null},requests:〔Object:nullprototype〕{},sockets:〔Object:nullprototype〕{},freeSockets:〔Object:nullprototype〕{},keepAliveMsecs:1000,keepAlive:true,这里是truemaxSockets:Infinity,maxFreeSockets:256,schedule:lifo,maxTotalSockets:Infinity,totalSocketCount:0,maxCachedSessions:100,sessionCache:{map:{},list:〔〕},〔Symbol(kCapture)〕:false} 第21、50将keepAlive设置为true,启用keepAlive可实现连接重用并提高网络吞吐量。此外,服务端会调用close()自动断开空闲客户端,内部依赖于http(s)。Server。closeAPI实现,这些修改将进一步优化Node体验和性能。这个改动有以下几个注意点:http。globalAgent和https。globalAgent默认都使用keepaliveAgent代理会解析、应用从server处获取到的KeepAlive头部(如果其值小于Agent的超时时间)http(s)。Server。close现在在内部调用closeIdleConnections方法2。2稳定的WebCryptoAPI WebCryptoAPI是使用密码学构建的系统接口,在node。jsv19(Ed25519、Ed448、X25519、X448除外)中趋于稳定。可以通过调用globalThis。crypto或者require(node:crypto)。webcrypto来访问,比如下面的代码;const{subtle}globalThis。或者require(node:crypto)。webcrypto(asyncfunction(){constkeyawaitsubtle。generateKey({name:HMAC,hash:SHA256,length:256,},true,〔sign,verify〕);console。log(key,key);constencnewTextEncoder();constmessageenc。encode(Ilovecupcakes);console。log(message,message);constdigestawaitsubtle。sign({name:HMAC,},key,message);console。log(digest,digest);})(); 我们对上面的代码做一个简单的说明,一共包括三个步骤:首先生成HMAC密钥,可同时用于验证消息数据的完整性和真实性;然后,加密字符串Ilovecupcakes最后创建消息摘要,这是一个加密哈希函数; 执行如下命令:nodeserver 此时控制台显示key、message、digest等信息:执行命令keyCryptoKey{type:secret,extractable:true,algorithm:{name:HMAC,length:256,hash:〔Object〕},usages:〔sign,verify〕}messageUint8Array(15)〔73,32,108,111,118,101,32,99,117,112,99,97,107,101,115〕digestArrayBuffer{〔Uint8Contents〕:30017a5cd9e282556b55904f1dde36d789ddfbfb1a9ea0cc5dd84913382fd1bc,byteLength:32}2。3自定义ESM解析调整 Node。js已删除experimentalspecifierresolution能力,其功能现在可通过自定义加载器使用(可以在文末参考文献链接中尝试)。gitclonehttps:github。comnodejsloaderstest。gitcdloaderstestcommonjsextensionresolutionloaderyarninstall 例如loaderstestcommonjsextensionresolutionloadertestbasicfixturesindex。js文档:import{version}import{valueInFile}from。import{valueInFolderIndex}from。console。log(valueInFile);console。log(valueInFolderIndex); 。file如果没有自定义加载器,则不会搜索文件的扩展名,比如。file。js或者。file。mjs。而通过设置自定义加载器后,可以解决以上问题:import{isBuiltin}fromnode:import{dirname}fromnode:import{cwd}fromnode:import{fileURLToPath,pathToFileURL}fromnode:import{promisify}fromnode:importresolveCallbackfromresolveasync。constresolveAsyncpromisify(resolveCallback);constbaseURLpathToFileURL(cwd())。exportasyncfunctionresolve(specifier,context,next){const{parentURLbaseURL}if(isBuiltin(specifier)){returnnext(specifier,context);}resolveAsyncworkswithpaths,notURLsif(specifier。startsWith(file:)){specifierfileURLToPath(specifier);}constparentPathfileURLToPath(parentURL);try{constresolutionawaitresolveAsync(specifier,{basedir:dirname(parentPath),Forwhateverreason,experimentalspecifierresolutionnodedoesntsearchfor。mjsextensionsbutitdoessearchforindex。mjsfileswithindirectoriesextensions:〔。js,。json,。node,。mjs〕,});urlpathToFileURL(resolution)。}catch(error){if(error。codeMODULENOTFOUND){MatchNodeserrorcodeerror。codeERRMODULENOTFOUND;}}returnnext(url,context);} 测试命令如下:nodeloader。loader。jstestbasicfixturesindex(node:56149)ExperimentalWarning:CustomESMLoadersisanexperimentalfeature。Thisfeaturecouldchangeatanytime(Usenodetracewarnings。。。toshowwherethewarningwascreated)hellofromfile。js 此时程序不会再报错,能正常运行。2。4。移除对DTraceSystemTapETW的支持 在Node。jsv19中,移除了对DTraceSystemTapETW的支持,主要是因为资源优先级的问题。数据显示,很少有人使用DTrace、SystemTap或ETW,因此维护它们没有多大意义(如果有问题,可以在文末提供的链接中提交issue)。2。5升级V8JavaScript引擎到V10。7 Node。jsv19将V8JavaScript引擎更新为V810。7(这也是Chromium107默认的JavaScript引擎),其中包括一个用于格式化敏感数字的新函数Intl。NumberFormat。Intl。NumberFormat(locales,options); 对于不同的语言,传入不同的语言环境:constnumber123456。789;console。log(newIntl。NumberFormat(deDE,{style:currency,currency:EUR})。format(number));console。log(newIntl。NumberFormat(jaJP,{style:currency,currency:JPY})。format(number));console。log(newIntl。NumberFormat(arSA,{style:currency,currency:EGP})。format(number));console。log(newIntl。NumberFormat(zhCN,{style:currency,currency:CNY})。format(number));Intl。NumberFormatv3API是一个新的TC39ECMA402stage3提案,扩展了预先存在的Intl。NumberFormat。 除了对NumberFormat的扩展,NodeV19还包括了如下变更:Node。js19附带了llhttp8。1。0Node。js19更新了npm8。19。22。6尝试使用Nodewatch 当导入的文件发生更改时,以watch模式运行的程序会重新启动,此功能已经在v19。0。0和v18。11。0中可用。server。jsconstexpressrequire(express);constpathrequire(path);constappexpress();app。use(express。static(path。join(dirname,。。build)));app。listen(8080,()console。log(Expressserverisrunningonlocalhost:8080)); 启动命令如下:nodewatchserver 输出内容如下:(node:67643)ExperimentalWarning:Watchmodeisanexperimentalfeature。Thisfeaturecouldchangeatanytime(Usenodetracewarnings。。。toshowwherethewarningwascreated)Expressserverisrunningonlocalhost:8080 Node。js14将于2023年4月结束更新维护,Node。js16(LTS)预计将于2023年9月结束更新维护。建议大家开始计划按需升级到Node。js16(LTS)或Node。js18(LTS),更多说明可以阅读文末资料。参考资料 https:github。comnodejsloaderstest https:github。comnodejsnodeissues44550 https:nodejs。orgenblogannouncementsv19releaseannouncenodewatchexperimental https:github。comnodejsnodepull43522 https:github。comnodejsnodepull44859 https:baijiahao。baidu。coms?id1626332802026818591wfrspiderforpc