Javascript 如何在节点中使用全局URLSearchParams

Javascript 如何在节点中使用全局URLSearchParams,javascript,node.js,Javascript,Node.js,我正在编写一个(客户端)JavaScript库(节点/角度模块)。 在这个库中,我使用URLSearchParams类 const form = new URLSearchParams(); form.set('username', data.username); form.set('password', data.pass); 由于这是一个共享库,它被打包为一个npm模块。 但是,在运行mocha单元测试时,我得到一个错误,即没有定义URLSearchParams。原因似乎是节点在全局范围内

我正在编写一个(客户端)JavaScript库(节点/角度模块)。 在这个库中,我使用URLSearchParams类

const form = new URLSearchParams();
form.set('username', data.username);
form.set('password', data.pass);
由于这是一个共享库,它被打包为一个npm模块。 但是,在运行mocha单元测试时,我得到一个错误,即没有定义URLSearchParams。原因似乎是节点在全局范围内没有URLSearchParams,但必须使用
require('url')
导入:

$node
>新的URLSearchParams()
ReferenceError:未定义URLSearchParams
回复:1:5
在sigintHandlersWrap(vm.js:22:35)
在sigintHandlersWrap(vm.js:73:12)
在ContextifyScript.Script.runInThisContext(vm.js:21:12)
在REPLServer.defaultEval上(repl.js:340:29)
绑定时(domain.js:280:14)
在REPLServer.runBound[as eval](domain.js:293:12)
在服务器上。(回复js:538:10)
在emitOne(events.js:101:20)
在REPLServer.emit上(events.js:188:7)
如何使节点内的客户端代码可以使用URLSearchParams,以便使用mocha测试库

这不起作用:

> global.URLSearchParams = require('url').URLSearchParams
undefined
> new URLSearchParams()
TypeError: URLSearchParams is not a constructor
    at repl:1:1
    at sigintHandlersWrap (vm.js:22:35)
    at sigintHandlersWrap (vm.js:73:12)
    at ContextifyScript.Script.runInThisContext (vm.js:21:12)
    at REPLServer.defaultEval (repl.js:340:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:538:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:188:7)
>global.URLSearchParams=require('url').URLSearchParams
未定义
>新的URLSearchParams()
TypeError:URLSearchParams不是构造函数
回复:1:1
在sigintHandlersWrap(vm.js:22:35)
在sigintHandlersWrap(vm.js:73:12)
在ContextifyScript.Script.runInThisContext(vm.js:21:12)
在REPLServer.defaultEval上(repl.js:340:29)
绑定时(domain.js:280:14)
在REPLServer.runBound[as eval](domain.js:293:12)
在服务器上。(回复js:538:10)
在emitOne(events.js:101:20)
在REPLServer.emit上(events.js:188:7)

更新:节点v10在全局对象上内置了
URLSearchParams
,因此可以按照问题中的预期直接使用

旧版本的节点:

一个选项是在测试运行程序的启动脚本中将其设置为全局:

import { URLSearchParams } from 'url';
global.URLSearchParams = URLSearchParams
例如,对于Jest,您可以使用指向上述启动脚本的

作为补充说明,如果您希望在创建通用代码的服务器端Webpack捆绑包时获得类似的结果,您可以通过Webpack实现这一点:


在使用Node8.10的AWS Lambda中,我必须执行以下操作:

const {URLSearchParams} = require('url')
const sp = new URLSearchParams(request.querystring)


如果我们想在应用程序中支持大范围的
nodejs
版本,我们可以使用如下脏代码:

if(typeof URLSearchParams === 'undefined'){
    URLSearchParams = require('url').URLSearchParams;
}

注意:
要求
带有条件不是最佳做法。

您可以使用polifill@ungap/url搜索参数,对于网页包,可以使用@ungap/url搜索参数/cjs

旧的NodeJS 8(在AWS和GCloud中使用)不支持URLSearchParams,因此此选项有帮助

在节点10中,当使用TypeScript时,可以启用库dom,其中包括URLSearchParams实现。更改tsconfig.json:


如果我
导入“url搜索参数/build/url搜索参数”
,我得到的HtmlanchoreElement没有定义。为什么不在测试文件中导入它呢?节点v10在
全局
对象上内置了
URLSearchParams
,因此它可以在没有上述设置的情况下使用。我还没有测试过此解决方案,但感谢您指出节点v10现在内置了此功能。这就解决了问题。如果你更新你的答案,我可以接受。@Martinnylot我已经更新了答案。如果这就是你想要的,我会很感激你接受的。
const {URLSearchParams} = require('url')
const sp = new URLSearchParams(request.querystring)
const url = require('url')
const sp = new url.URLSearchParams(request.querystring)
if(typeof URLSearchParams === 'undefined'){
    URLSearchParams = require('url').URLSearchParams;
}
{
  "compilerOptions": {
    "lib": [
      ...
      "dom"
      ...
    ]
  }
}