在package.json
中直接修改了依赖版本号后执行npm i
可能会出现各种报错,比如Error: Cannot find module xxx
之类的。
这时候需要删除package-lock.json
并删除node_modules
目录后重新执行npm i
应该就可以恢复正常
在package.json
中直接修改了依赖版本号后执行npm i
可能会出现各种报错,比如Error: Cannot find module xxx
之类的。
这时候需要删除package-lock.json
并删除node_modules
目录后重新执行npm i
应该就可以恢复正常
express本身可以写async函数作为路由或者中间件(以下简称路由)使用,但如果在其中直接抛出异步错误的话则不会被捕获并传递给错误处理路由,需要在每一个async路由中手动写try/catch来捕获并处理错误,这显然对于拥有统一错误处理逻辑的框架是不友好的。
我不知道为什么express始终没有在4.x版本添加这个支持,看起来这应该并不会导致什么兼容性问题,即使不默认全局开启这个功能,也可以添加一个选项或开关函数来允许使用者开启异步错误捕获,但它始终没有这么做。
在这之前npm上也已经有一些可以实现这个功能的补丁包,不过它们几乎都是给创建出的app实例的所有相关路由方法套了一层壳在里面try/catch错误,导致如果是自己用一些特殊方法创建的路由对象,就失效了。
我原本用了一个直接修改express源码中相关原型方法的包,叫做
asyncPatch
函数需要传入一个创建出来的app实例, 为的是能获取到app所属的express包里的构造函数,不是为了在实例上包装方法。该函数在任何阶段调用都可以,只要在处理请求前调用即可。
reids本身是一个基于键值对数据存储的内存数据库,也就是只能通过数据的key来获取数据项目,那么它自然也就没有任何数据搜索方面的功能,只能依靠一定规则生成的key来获取数据。
虽然它的本体是这样,但redis也提供了几个模块为其添加了一部分搜索功能的支持,并将这些模块整合为了redis-stack,官网介绍:https://redis.io/docs/stack/,我暂时还没测试它是否可以直接替代原本的redis实例,但就命令形式上来看,应该是兼容的。
本文是对于redis-stack官网上提供的node.js示例记录的笔记。
redis-stack的安装我就不介绍了,直接从官网下载就好,或者使用docker之类的,本文只记录如何使用。
要在node.js中使用redis-stack的相关特性,我们需要redis-om
模块,使用npm i redis-om
安装进需要它的项目,关于该模块更详细的API介绍可以去其npm包页面上或者github仓库查看:https://github.com/redis/redis-om-node,不过要注意的是官方的示例中有些地方是错的,我会在下面对应的部分说明。 继续阅读[node.js]在redis上使用数据搜索
本文为node包sass的使用笔记。
写这篇文章,是因为我碰到了引用node_modules
目录中模块的scss
文件的需求,但是它总是提示找不到: “Error: Can’t find stylesheet to import.”,于是我搜了搜,发现说是要在渲染参数中添加loadPaths
数组来告诉sass去哪里找依赖文件,我在这个模块的typescript类型定义中也找到了这个参数名,但是我加上了之后并没有用,于是研究一番发现这个包使用的实际上并不是loadPaths
,而是includePaths
这个参数名,所以觉得有必要写篇笔记记录一下。
另外我发现有的解决方案中说可以在import的url前面加个~
来表示这个文件在node_modules
里,但我试了也没有用,这个特性似乎是webpack给sass引入的importer,所以单独使用sass的render api时此方式是不起作用的,如果使用的是sass-loader
的话可以使用这个方法。
在使用ES导入语法的文件中想要使用require导入一个CommonJS模块的话,可以使用module.createRequire来创建一个require函数。
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
在一般的使用CommonJS导入语法的文件中想要使用ES语法导入模块的话,可以使用import
函数,要注意的是这是一个异步函数,返回一个Promise
,所以需要await
它或者使用then
来等待返回结果,如下
(async()=>{ const fs=await import('fs); })();
写了个Browserify插件,之前一直没问题,但今天我改了点打包流程,结果一直报write after end
错误,找了半个晚上,发现是因为我的插件函数写的是异步的,里面有个await异步读文件。
之前一直没出问题是因为后面的打包流程时间够长,能让这个插件正常执行完,但今天改了流程之后部分情况下很快就执行完了,于是当插件异步流程执行完后继续就出错了,修正方法是把异步文件读取改成同步的。
不是我想水一篇博文,在解决完前一篇博文的问题之后,立刻就又碰上另一个奇葩问题,进程直接跑着跑着没了,留下一个错误码3221226505。
在我左思右想把代码改来改去,包换来换去之后依然不能解决问题,然后发现是canvas包的问题,之所以一直没有发现是它,是因为出问题的代码里并没有用到这个包,它是在别的地方被引用到的,可能它的二进制模块破坏了node的环境,导致别的代码执行的时候触发了异常导致程序崩溃。
这个问题其实也不是第一次出现了,而且每次都是因为项目中同时有canvas和sharp两个模块才出现问题,在某些版本下不会出问题,某些版本下又会出现不一样的错误,这次就是和上次不一样所以才没能快速发现。
就这点破事,又浪费了我一个晚上,这时候我真想给搞出这bug的人屁股上来一脚。
node.js 做的socks5服务端,支持socks5/4/4a,支持无验证和用户名密码验证模式,支持tcp和udp模式,bind模式暂时还没做
每次换一个环境执行npm i都会碰到这样的问题,记录一下解决方法,
方法1:手动去报错的文件里指定编码为UTF-8,我自己第一次解决这个问题就是用的这个办法,刚刚想找找看有没有别的解决方法的时候发现别人也有去手动改源码的,放个参考链接。
简单地说就是找到报错的那行,给open函数加个encoding='utf-8'
参数就可以解决问题,但这样属于改了人家文件,更新后还是会变回去的,所以现在我不这样做了。
方法2:去控制面板的区域设置里到“管理”标签页下,“更改系统区域设置”,把“Beta版:使用Unicode UTF-8提供全球语言支持(U)”勾上,然后重启一下,python就会默认用utf-8来读文件了。
这个方法会改变整个系统的默认代码页,最主要的影响是会导致使用非Unicode的程序乱码甚至崩溃,还有在gbk设置时以ansi保存的含有中文的bat脚本会乱码。如果影响不大的话倒是可以让系统一直保持在这个区域选项上,影响某些软件的正常使用的话在执行完需要的编译任务后还得改回去。在这种模式下可以使用“locale emulator”这样的软件以Chinese模式启动程序,以解决程序的乱码和崩溃问题。
方法3:我没试过,理论上应该可行,从python本体入手,把它的默认编码设置成utf-8,参考这里的方案2。这个没用
昨晚写了个重命名工具,使用正则表达式匹配并替换文件名。
现在给npm包起个合适的名字是真难
GitHub: https://github.com/JiaJiaJiang/node-namer
效果
$ namer -f "/.+(?=\.txt$)/" -r "#COUNTERpoi$&" match: /.+(?=\.txt$)/ find: /.+(?=\.txt$)/ replacement: #COUNTERpoi$& Match list: 1.txt > 1poi1.txt 2.txt > 2poi2.txt 3.txt > 3poi3.txt 4.txt > 4poi4.txt 5.txt > 5poi5.txt 6.txt > 6poi6.txt 7.txt > 7poi7.txt 8.txt > 8poi8.txt 9.txt > 9poi9.txt 10.txt > 10poi10.txt 11.txt > 11poi11.txt 12.txt > 12poi12.txt 13.txt > 13poi13.txt 14.txt > 14poi14.txt 15.txt > 15poi15.txt 16.txt > 16poi16.txt 17.txt > 17poi17.txt 18.txt > 18poi18.txt 19.txt > 19poi19.txt 20.txt > 20poi20.txt 21.txt > 21poi21.txt 22.txt > 22poi22.txt 23.txt > 23poi23.txt 24.txt > 24poi24.txt 25.txt > 25poi25.txt 26.txt > 26poi26.txt 27.txt > 27poi27.txt 28.txt > 28poi28.txt 29.txt > 29poi29.txt 30.txt > 30poi30.txt 31.txt > 31poi31.txt 32.txt > 32poi32.txt 33.txt > 33poi33.txt 34.txt > 34poi34.txt 35.txt > 35poi35.txt 36.txt > 36poi36.txt 36matches found. Confirm? (control+c to exit) Finished. 36succeeded,0failed
由于解决这个问题花了我一些时间,所以记录一下说不定可以帮到其他人。
process.stdout是一个getter,所以我们不能用普通的替换来换掉process.stdout来拦截写入它的数据。同时,process.stdout是一个Writable Stream,所以也不能简单地直接从它里面获取写入的数据。
一开始我花了不少时间来研究怎么可以从这个Writable Stream里读出数据,但是这似乎太麻烦了,然后我甚至想到了利用child process来拦截数据。最后发现其实很简单,我们只要重新定义这个Getter就可以了。
var stream=require('stream'); var rawStdout=process.stdout,//先拿到原来的stdout newStdout=new stream.PassThrough();//创建一个passthrough流,这是一种特殊的Transform流,会直接把写入的数据吐出来 process.__defineGetter__('stdout',function(){//重新定义process.stdout的Getter return newStdout;//返回我们的passthrough流 });
这样我们就成功拦截到标准输出了,要注意,这段代码必须放在有任何输出之前,一旦在之前有了内容输出,它就没用了。
然后我们就可以自己决定怎么处理stdout了比如:
newStdout.pipe(rawStdout);//内容输出到控制台 newStdout.pipe(文件的writable stream);//内容写入文件 newStdout.pipe(其它可写流);//随你怎么处理
同理,process.stderr也可以这样拦截
node执行完所有代码以后就会退出(部分监听服务除外),如果不希望node立刻退出,只要在任意位置加上一行
setInterval(function(){},9999999);//时间设置多少都没有关系,这只影响这个空回调函数的调用频率
node就不会退出了(除非出错
如果你希望即使是出错了,也不让Node退出,那么就需要加入以下事件监听器
process.on('uncaughtException',(err,origin)=>{//捕捉uncaughtException console.error('[uncaughtException]',err,origin); }); process.on('unhandledRejection',(err,promise)=>{//捕捉unhandledRejection console.error('[unhandledRejection]',err); });
加入这两个监听器之后,node遇到任何未捕捉的错误,都会交给第一个监听器处理,碰到任何未catch的异常Promise,都会交给第二个监听器处理,你可以在里面做些事情,比如打个日志之类的。
==========更新log===========
从node分离出来农民起义的iojs终于取得了革命胜利。现在node的版本一下从0.12.x飞升到了4.0.0。
Node.js ChangeLog 2015-09-08, Version 4.0.0 (Stable), @rvagg Notable changes This list of changes is relative to the last io.js v3.x branch release, v3.3.0. Please see the list of notable changes in the v3.x, v2.x and v1.x releases for a more complete list of changes from 0.12.x. Note, that some changes in the v3.x series as well as major breaking changes in this release constitute changes required for full convergence of the Node.js and io.js projects. child_process: ChildProcess.prototype.send() and process.send() operate asynchronously across all platforms so an optional callback parameter has been introduced that will be invoked once the message has been sent, i.e. .send(message[, sendHandle][, callback]) (Ben Noordhuis) #2620. node: Rename "io.js" code to "Node.js" (cjihrig) #2367. node-gyp: This release bundles an updated version of node-gyp that works with all versions of Node.js and io.js including nightly and release candidate builds. From io.js v3 and Node.js v4 onward, it will only download a headers tarball when building addons rather than the entire source. (Rod Vagg) #2700 npm: Upgrade to version 2.14.2 from 2.13.3, includes a security update, see https://github.com/npm/npm/releases/tag/v2.14.2 for more details, (Kat Marchán) #2696. timers: Improved timer performance from porting the 0.12 implementation, plus minor fixes (Jeremiah Senkpiel) #2540, (Julien Gilli) nodejs/node-v0.x-archive#8751 nodejs/node-v0.x-archive#8905 util: The util.is*() functions have been deprecated, beginning with deprecation warnings in the documentation for this release, users are encouraged to seek more robust alternatives in the npm registry, (Sakthipriyan Vairamani) #2447. v8: Upgrade to version 4.5.103.30 from 4.4.63.30 (Ali Ijaz Sheikh) #2632. Implement new TypedArray prototype methods: copyWithin(), every(), fill(), filter(), find(), findIndex(), forEach(), indexOf(), join(), lastIndexOf(), map(), reduce(), reduceRight(), reverse(), slice(), some(), sort(). See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray for further information. Implement new TypedArray.from() and TypedArray.of() functions. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray for further information. Implement arrow functions, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions for further information. Full ChangeLog available at https://github.com/v8/v8-git-mirror/blob/4.5.103/ChangeLog
以上是搬过来的changeLog,同时在changeLog页面往下翻一番,全都是iojs之前的版本号,很明显node原本的项目是直接被iojs项目覆盖掉了,注意这一行
node: Rename "io.js" code to "Node.js" (cjihrig) #2367.
iojs重命名为nodejs,革命军变成了正规军,推翻了原本的帝国统治。
现在点开iojs.org官网里的changelog也是直接跳转到https://github.com/nodejs/node/blob/master/CHANGELOG.md,也就是node的changelog。
这对native mod开发者来说是个福音,不用再去考虑兼容iojs和node携带的两个版本差距悬殊的v8版本了。
出现这个错误表示端口绑定失败,需要提高权限来运行程序。
我在安装webkit-devtools-agent
模块的时候node-gyp rebulid过程中碰到了这个错误,node版本为0.12.7。
把node换成版本为0.10.x的就可以通过编译了。
手动安装node的时候一不注意就会出现这个错误,装好了之后使用命令npm
测试一下出来了这个错误:Error: Cannot find module 'npmlog'
。
这一般是放在/bin里的链接不对导致的。
链接指向的不是node_modules/npm/bin/npm-cli.js
,初次手动安装难免会搞不清要链接哪个文件,把链接指向正确的位置即可。
使用的不是软链接,由于npm-cli.js中使用的是相对路径,要是你一不小心链了个硬链接,那么npm就会从/bin解析相对路径,所以就找不到npmlog模块了。要使用软链接,在ln命令后加上-s
选项:ln -s node_modules/npm/bin/npm-cli.js /bin/npm