Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand the list with some new replacements #192

Open
outslept opened this issue Jan 21, 2025 · 6 comments
Open

Expand the list with some new replacements #192

outslept opened this issue Jan 21, 2025 · 6 comments

Comments

@outslept
Copy link

outslept commented Jan 21, 2025

1. querystring

Current Status: Deprecated.
Author Message: "The querystring API is considered Legacy. New code should use the URLSearchParams API instead."

Replacement: URLSearchParams API.

Reference: npmjs [1], also an indication in the README of the repository [2]

Package Using querysting

2. request

Current Status: Deprecated.
Author Message: "The most valuable thing request can do for the JavaScript ecosystem is to go into maintenance mode and stop considering new features or major releases."

Reference: Issue [1]

Replacement:

Feature request Modern Replacement
Basic GET request(url, callback) await fetch(url)
Basic POST request.post(url) fetch(url, {method: 'POST'})
Streaming Download request(url).pipe(fs.createWriteStream()) pipeline(response.body, fs.createWriteStream())
URL-encoded Forms request.post(url, {form: data}) fetch(url, {body: new URLSearchParams(data)})
Multipart Forms request.post(url, {formData: data}) fetch(url, {body: new FormData()})
JSON Body request({url, json: true}) await fetch(url).then(r => r.json())
Custom Headers request({headers: {...}}) fetch(url, {headers: {...}})
Basic Auth request.get(url).auth(user, pass) fetch(url, {headers: {'Authorization': 'Basic ' + btoa(user + ':' + pass)}})
Bearer Auth request.get(url).auth(null, null, true, token) fetch(url, {headers: {'Authorization': 'Bearer ' + token}})
Query Parameters request({qs: {key: 'value'}}) new URL(url).searchParams.set('key', 'value')
Cookies request({jar: true}) fetch(url, {credentials: 'include'})
Redirects request({followRedirect: false}) fetch(url, {redirect: 'manual'})
Timeouts request({timeout: 1000}) AbortController + setTimeout
Proxy request({proxy: 'http://....'}) fetch(url, {agent: new HttpsProxyAgent()})
SSL/TLS Options request({cert: fs.readFileSync()}) fetch(url, {agent: new https.Agent({cert: ...})})
Gzip/Deflate request({gzip: true}) fetch(url)
Custom CA request({ca: fs.readFileSync()}) fetch(url, {agent: new https.Agent({ca: ...})})
Keep-Alive request({forever: true}) fetch(url, {agent: new http.Agent({keepAlive: true})})

Note

I haven't dived deep enough so the list at the top is not 100% feature coverage, but the cases here should cover up to trivial 90+% needs of previous request users. Also check out the article down below.

References:

  1. Fetch API Standard: https://fetch.spec.whatwg.org/
  2. Node.js Fetch: https://nodejs.org/api/globals.html#fetch
  3. Fetch API: https://developer.mozilla.org/docs/Web/API/fetch
  4. Node.js Streams: https://nodejs.org/api/stream.html
  5. URLSearchParams: https://developer.mozilla.org/docs/Web/API/URLSearchParams
  6. FormData API: https://developer.mozilla.org/docs/Web/API/FormData
  7. RFC 7578 (Multipart Forms): https://datatracker.ietf.org/doc/html/rfc7578
  8. Fetch Response: https://developer.mozilla.org/docs/Web/API/Response
  9. Headers API: https://developer.mozilla.org/docs/Web/API/Headers
  10. HTTP Authentication: https://developer.mozilla.org/docs/Web/HTTP/Authentication
  11. RFC 7617 (Basic Auth): https://datatracker.ietf.org/doc/html/rfc7617
  12. RFC 6750 (Bearer Auth): https://datatracker.ietf.org/doc/html/rfc6750
  13. URL API: https://developer.mozilla.org/docs/Web/API/URL
  14. AbortController: https://developer.mozilla.org/docs/Web/API/AbortController
  15. Node.js HTTP Agent: https://nodejs.org/api/http.html
  16. Node.js HTTPS: https://nodejs.org/api/https.html
  17. TLS Options: https://nodejs.org/api/tls.html
  18. HTTP Keep-Alive: https://nodejs.org/api/http.html

Also check this article for more possible replacements.

Package's npmjs

3. clamp

Current Status: Simple utility for clamping values.
Replacement: Could be inlined

// clamp:
const clamp = require('clamp');
console.log(clamp(10, 0, 5)); // 5

// native:
const clamp = (value, min, max) => 
  min < max
    ? Math.min(Math.max(value, min), max)
    : Math.min(Math.max(value, max), min);

console.log(clamp(10, 0, 5)); // 5

Package's npmjs

4. uniq

Current Status: Utility for removing duplicates from arrays.
Replacement: Native Set

// uniq:
const uniq = require('uniq');
const array = [1, 2, 2, 3, 4, 4, 5];
console.log(uniq(array)); // [1, 2, 3, 4, 5]

// Set:
const array = [1, 2, 2, 3, 4, 4, 5];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // [1, 2, 3, 4, 5]

Package's npmjs

5. isomorphic-fetch & node-fetch

Warning

This needs further investigation, but it looks like this can be fully replaced with native fetch by now.

Package's npmjs (isomorphic fetch)
Package's npmjs (node-fetch)

According to caniuse:

"Since March 2017, this feature works across the latest devices and major browser versions (Learn more about Baseline)"
Reference

Also check out this thread

@outslept
Copy link
Author

This came out more than I expected, if I find anything else I'll post it in a separate issue. Would love to hear community feedback on this.

@ljharb
Copy link

ljharb commented Jan 21, 2025

what's the native implementation for clamp?

@outslept
Copy link
Author

outslept commented Jan 21, 2025

what's the native implementation for clamp?

const clamp = (value, min, max) => Math.min(Math.max(value, min), max);

However, this doesn't handle the case when min > max.
For a more robust implementation that handles reversed ranges:

const clamp = (value, min, max) => 
  min < max
    ? Math.min(Math.max(value, min), max)
    : Math.min(Math.max(value, max), min);

This will be a 1:1 port of the mentioned dependency

@ljharb
Copy link

ljharb commented Jan 21, 2025

To be clear tho, that's not a native implementation, that's inlining the implementation of the function. A native implementation would be like Math.clamp().

@outslept
Copy link
Author

To be clear tho, that's not a native implementation, that's inlining the implementation of the function. A native implementation would be like Math.clamp().

You're absolutely right with this point. I've chosen not the best terminology for this

@43081j
Copy link
Contributor

43081j commented Jan 21, 2025

this is a great list, really good detail

clamp is really the only non-obvious one since it is an inlining job rather than there being a native clamp function. but many of the JS community would still rather do that in the packages they maintain, so its still worth noting and actioning on. those who don't want that code inlined can keep clamp (it is a tiny package)

adding these to the replacements repo makes sense, but its probably also a good idea to open related issues in the cleanup repo. others in the community may be able to help us find high impact dependents we can start replacing these in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants