is there any replacement for the nodejs url.resolve function?
nodeJs provides the https://nodejs.org/api/url.html module which allows to:
- resolve two relative urls:
require('url').resolve(`profile/user/99/details/`, `../../55/details/`) // -> 'profile/user/55/details/'
- resolve a relative url and an absolute url:
require('url').resolve(`profile/user/99/details/`, `http://example.com`) // -> 'http://example.com/'
- resolve an absolute url and a relative url:
require('url').resolve(`http://example.com`, `profile/user/99/details/`) // -> 'http://example.com/profile/user/99/details/'
- resolve two absolute urls:
require('url').resolve(`http://example.com`, `https://stackoverflow.com`) // ->
'https://stackoverflow.com/'
however require('url').resolve
was deprecated
what would be the correct (as in non deprecated) way to resolve the urls like in the examples above?
Solution 1:
For urls specific, you can use the new URL()
constructor defined by the WHATWG standard.
// syntax
const url = new URL(url [, base]); // (url: string | URL, base?: string | URL) => URL
The href
property holds the resolved url.
console.log(new URL(`profile/user/99/details/`, `http://example.com`).href);
console.log(new URL(`https://stackoverflow.com`, `http://example.com`).href);
For paths, you can use the path.posix.join()
function provided by Node.js to force joining the paths with forward slashes.
const path = require("path");
path.posix.join(`profile/user/99/details/`, `../../55/details/`));
You could also combine the two.
const path = require("path");
const joined = path.posix.join(`profile/user/99/details/`,"..", "..", `55/details/`);
// 'https://stackoverflow.com/profile/user/55/details/'
const { href } = new URL(joined, "https://stackoverflow.com");
Examples.
const path = require("path");
// two relative paths => 'profile/user/55/details/'
path.posix.join("profile/user/99/details/", "../../55/details/");
// absolute and relative path (right) => 'http://example.com/profile/user/99/details/'
new URL("profile/user/99/details/", "http://example.com").href;
// absolute and relative path (wrong) => throws TypeError [ERR_INVALID_URL]
new URL("http://example.com", "profile/user/99/details/").href;
// two absolute paths => 'https://stackoverflow.com'
new URL("https://stackoverflow.com", "http://example.com").href;
// combined => 'http://example.com/profile/user/55/details'
new URL(path.posix.join(
"profile", "user", "99", "details",
"..", "..", "55", "details"
), "http://example.com").href;
// or
new URL(path.posix.join(
"profile/user/99/details/",
"../../55/details"
), "http://example.com").href;
Solution 2:
You can use build-in new URL() constructor:
new URL(`https://stackoverflow.com`, `http://example.com`)
returns:
URL {
href: 'https://stackoverflow.com/',
origin: 'https://stackoverflow.com',
protocol: 'https:',
username: '',
password: '',
host: 'stackoverflow.com',
hostname: 'stackoverflow.com',
port: '',
pathname: '/',
search: '',
searchParams: URLSearchParams {},
hash: ''
}
The problem with that:
- Constructor takes the first arg as primary. So as you wished:
resolve(`http://example.com`, `https://stackoverflow.com`)'
would not returnhttps://stackoverflow.com
. - Returns whole class so you have to "collect" the .href only.
If you can use non-build-in methods, I would suggest https://www.npmjs.com/package/resolve-url .