CommonJS导入纯EMS模块

最近用nodejs做后端写了一些小工具。发现sync-request模块总报错。

Error: nodeNC failed:

node:events:489
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED 127.0.0.1:36999
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1574:16)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 36999
}

Node.js v20.3.1

    at sendMessage (/home/www/koa/node_modules/sync-rpc/lib/index.js:146:13)
    at /home/www/koa/node_modules/sync-rpc/lib/index.js:175:25
    at request (/home/www/koa/node_modules/sync-request/lib/index.js:28:15)
    at TvService.get (/home/www/koa/src/common/tv-service.js:279:27)
    at VideoService.get (/home/www/koa/src/services/video-service.js:10:41)
    at get (/home/www/koa/src/controllers/cqyxvideo-controller.js:14:44)
    at dispatch (/home/www/koa/node_modules/koa-compose/index.js:42:32)
    at /home/www/koa/node_modules/koa-router/lib/router.js:425:16
    at dispatch (/home/www/koa/node_modules/koa-compose/index.js:42:32)
    at /home/www/koa/node_modules/koa-compose/index.js:34:12

原以为给这个请求这个加上try catch就可以了,但是不行,这个会影响后面不是这个文件里的其他sync-request请求都报错,这属于严重bug了。
超时返回就算是报错,也不能影响后续请求才对。
sync-request的同步实现依赖sync-rpc,但是sync-rpc对超时的实现有点问题,sync-rpc上次修复是2019年也就是4年前。等待官方修复遥遥无期了。
相关的issue可以看这里
https://github.com/ForbesLindesay/sync-rpc/issues/3

所以决定改用got
got在11版本前支持CommonJS导入语法,之后弃用了CommonJS,必须使用ESM导入。
got11版本CommonJS模块安装与导入 

# 安装
npm install [email protected]
# 导入
const got = require('got');
#使用
const {data} = await got.get(url, {
    headers: header
}).json();
console.log(data);

got新版esm安装与导入

# 安装
npm install [email protected]
# 导入
import got from 'got';
#使用
const {data} = await got.get(url, {
    headers: header
}).json();
console.log(data);

对于纯esm项目可以按新版这么使用。但对于大部分主流模块来说有点问题。
对于纯esm项目可以看这个:https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
纯esm项目一个明显的标志是package.json里有 "type": "module"这样的字段。


如果原有项目本身是CommonJS的话,改写成纯esm项目改动还是比较大的。不过好在支持动态导入的方式引用。
CommonJS动态导入esm模块方式使用

# 安装
npm install [email protected]
# 导入
async function getGot () {
    const { got } = await import("got")
    return got
}
#使用
const got = await getGot()
const {data} = await got.get(url, {
    headers: header
}).json();
console.log(data);

注意:这里的CommonJS项目不要引入babel之类的es6混编语法,以免引起动态导入混乱。

顺便盘点了一些nodejs下的网络请求库

https
node内置,编写繁琐

request
目前已经废弃,但是目前没有合适的options预检请求替代。

sync-request
同步请求基于sync-rpc项目,最近刚好遇到一个严重的bug是sync-rpc,sync-rpc4年没更新,不建议使用
bug参考
https://github.com/ForbesLindesay/sync-rpc/issues/3
这个bug参考是,try catch没用,其他sync-request请求会直接报错。

axios
npm install --save axios
浏览器端常用

got
npm install --save got
got12版本开始激进的放弃了CommonJS导入,只支持esm,老项目基本都是CommonJS的,引新版优先动态引入。毕竟把项目改成纯esm短期内不现实

superagent
npm install --save superagent
古老的库,benchmark速度不如新出的几个

node-fetch
npm install --save node-fetch
Node.js v17.5之后版本支持较好。低版本不支持
CommonJS 仅支持到v2
ES Modules (ESM) 支持v2v3

needle
定位简单的请求,如果需要一些认证请求,需要使用其他库

undici
esm模块

可以看到,旧库基本是CommonJS的,带新功能的新库基本都在转向纯esm模块。esm现在是大势所趋了。所以为了新特性,还是尽量使用新版本的新库比较方便。有人比喻这个过程像是在开油电混动的车。

你可能感兴趣的:(node,CommonJS,esm)