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

url is not a valid polyfill for Node's native url #7801

Open
Lazauya opened this issue Mar 6, 2022 · 14 comments
Open

url is not a valid polyfill for Node's native url #7801

Lazauya opened this issue Mar 6, 2022 · 14 comments

Comments

@Lazauya
Copy link

Lazauya commented Mar 6, 2022

🐛 bug report

Name describes it. Namely, the titular object is URL in Node, not Url as it is in url. This means that using code that calls new URL does not work. The npm url also does not parse the url when creating the url.

🎛 Configuration

Any configuration, though obviously the polyfill will only apply when the URL lib is invoked.

🤔 Expected Behavior

You should be able to use any of the Node URL lib's code.

😯 Current Behavior

new URL does not work due to wrong name.

💁 Possible Solution

I made a patch locally by copying https://github.com/defunctzombie/node-url and changing the export from Url to URL and making the constructor parse the url.

🔦 Context

Just kinda annoying.

Conclusion

This seems like a relatively simple fix. I'm thinking just a new npm package that forks/leverages existing URL parsing packages so that actual syntax parity is met with the native Node URL module.

@sznowicki
Copy link

Out of curiosity: how is this related to parcel?

@Lazauya
Copy link
Author

Lazauya commented Mar 6, 2022

Out of curiosity: how is this related to parcel?

Because Parcel explicitly uses the npm url library in Node emulation. See here. Parcel assumes that it is exactly the same as the native library, when it is not.

@mischnic
Copy link
Member

mischnic commented Mar 6, 2022

If you do require("url") (or import), Parcel will treat it as require("node-ur").

The URL global ("whatwg-url") doesn't have any special handling.

So please describe exactly the code you're using which doesn't work.

@Lazauya
Copy link
Author

Lazauya commented Mar 6, 2022

If you do require("url") (or import), Parcel will treat it as require("node-ur").

I'm confused. I don't see any package anywhere called node-url or node-ur. There is one, however, that does have the name url as per the docs. As for code that replicates this issue, just see var url = require('url'); var mycoolurl = new url.URL('https://example.com') which works in Node but not un Parcel by default.

@mischnic
Copy link
Member

mischnic commented Mar 6, 2022

(That was a typo, it should have been require("node-url").)

Yes, so this is essentially the same request as defunctzombie/node-url#33

@Lazauya
Copy link
Author

Lazauya commented Mar 6, 2022

So it seems like the solution is to use whatwg-url as the polyfill instead of url. Is this correct?

@mischnic
Copy link
Member

mischnic commented Mar 6, 2022

If you are targetting modern browsers and modern node with your code, simply use the URL global withouts any imports.

Otherwise, yes: import URL from whatwg-url instead.

@Lazauya
Copy link
Author

Lazauya commented Mar 6, 2022

If you are targetting modern browsers and modern node with your code, simply use the URL global withouts any imports.

Otherwise, yes: import URL from whatwg-url instead.

I'm talking about what Parcel does to other packages during Node emulation, not how I should build my packages. Specifically in the case of Node emulation. Packages that use var url = require('url') are broken in Parcel when they don't need to be.

@mischnic
Copy link
Member

mischnic commented Mar 8, 2022

Yeah, we might have to fork node-url. They have pretty strict requirement to support very old Node versions, which is very much opposed to our usecase. In our case, we could just add export.URL = URL.

@Lazauya
Copy link
Author

Lazauya commented Mar 8, 2022

Yeah, we might have to fork node-url. They have pretty strict requirement to support very old Node versions, which is very much opposed to our usecase. In our case, we could just add export.URL = URL.

Actually, I think that this package might just be the perfect candidate. It seems widely used and stable.

@mischnic
Copy link
Member

mischnic commented Mar 8, 2022

But that's a polyfill for URL , not require("url"). And many project wouldn't even want to ship a URL polyfill (at least not automatically) because it's supported for quite some time now in browsers.

@Lazauya
Copy link
Author

Lazauya commented Mar 8, 2022

But that's a polyfill for URL , not require("url"). And many project wouldn't even want to ship a URL polyfill (at least not automatically) because it's supported for quite some time now in browsers.

require("url") (the native Node library) is completely WHATWG compliant in the latest version. Perhaps in previous versions of Node it was not, but now it is, so that WHATWG library is a valid polyfill for the latest version. That's my understanding at least.

@mischnic
Copy link
Member

mischnic commented Mar 8, 2022

No:
The only similarity is that require("whatwg-url").URL === require("url").URL (equal as in duck-typing-equivalent):

> require("whatwg-url")
{
  URL: [class URL],
  URLSearchParams: [class URLSearchParams],
  parseURL: [Function (anonymous)],
  basicURLParse: [Function (anonymous)],
  serializeURL: [Function: serializeURL],
  serializeHost: [Function: serializeHost],
  serializeInteger: [Function (anonymous)],
  serializeURLOrigin: [Function (anonymous)],
  setTheUsername: [Function (anonymous)],
  setThePassword: [Function (anonymous)],
  cannotHaveAUsernamePasswordPort: [Function: cannotHaveAUsernamePasswordPort],
  percentDecodeString: [Function: percentDecodeString],
  percentDecodeBytes: [Function: percentDecodeBytes]
}
> require("url")
{
  Url: [Function: Url],
  parse: [Function: urlParse],
  resolve: [Function: urlResolve],
  resolveObject: [Function: urlResolveObject],
  format: [Function: urlFormat],
  URL: [class URL],
  URLSearchParams: [class URLSearchParams],
  domainToASCII: [Function: domainToASCII],
  domainToUnicode: [Function: domainToUnicode],
  pathToFileURL: [Function: pathToFileURL],
  fileURLToPath: [Function: fileURLToPath],
  urlToHttpOptions: [Function: urlToHttpOptions]
}

@Lazauya
Copy link
Author

Lazauya commented Mar 8, 2022

No:
The only similarity is that require("whatwg-url").URL === require("url").URL (equal as in duck-typing-equivalent):

You are very correct, sir. So it seems a fork would be needed after all.

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

No branches or pull requests

3 participants