Как использовать глобальные URLSearchParams в node
Я пишу (клиентскую) библиотеку JavaScript (модуль node/angular).
В этой библиотеке я использую класс URLSearchParams.
const form = new URLSearchParams();
form.set('username', data.username);
form.set('password', data.pass);
Поскольку это общая библиотека, она упакована как модуль npm.
Однако при запуске mocha unit test я получаю сообщение об ошибке, что URLSearchParams не определен. Причина заключается в том, что node не имеет URLSearchParams в глобальной области, но должен быть импортирован с помощью require('url')
:
$ node
> new URLSearchParams()
ReferenceError: URLSearchParams is not defined
at repl:1:5
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)
Как я могу сделать URLSearchParams доступным для клиентского кода внутри node, чтобы я мог протестировать библиотеку с помощью 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)
Ответы
Ответ 1
Обновление: Node v10 имеет встроенную доступность URLSearchParams
для глобального объекта, поэтому его можно использовать напрямую, как и предполагалось в вопросе.
Старые версии Node:
Один из вариантов - установить его как глобальный в стартовом скрипте бегуна:
import { URLSearchParams } from 'url';
global.URLSearchParams = URLSearchParams
Например, в Jest вы должны использовать setupTestFrameworkScriptFile
чтобы указывать на приведенный выше сценарий запуска.
В качестве примечания: если вы хотите достичь аналогичного результата при создании пакета универсального кода на стороне сервера, вы можете добиться этого с помощью ProvidePlugin
:
{
name: 'server',
target: 'node',
// ...
plugins: [
// ...
new webpack.ProvidePlugin({
URLSearchParams: ['url', 'URLSearchParams'],
fetch: 'node-fetch',
}),
],
}
Ответ 2
В AWS Lambda, которая использует Node8.10, мне нужно было сделать:
const {URLSearchParams} = require('url')
const sp = new URLSearchParams(request.querystring)
или
const url = require('url')
const sp = new url.URLSearchParams(request.querystring)
Ответ 3
Я попробовал это, и он отлично работает, вот URL документации
const url = require('url');
const params = new url.URLSearchParams();
Ответ 4
Если мы хотим поддерживать большой диапазон версий nodejs
в нашем приложении, мы могли бы использовать такой грязный код, как этот:
if(typeof URLSearchParams === 'undefined'){
URLSearchParams = require('url').URLSearchParams;
}
Примечание: Это не лучшая практика, чтобы require
с условием.