Polyfill too, or just ponyfill? #21
Replies: 7 comments
-
Note that the polyfill could just be a complete no-op when imported and bundled for a browser environment 👍 // package.json
{
"exports": {
"./polyfill.js": {
// I am honestly unsure if you need an empty file or if you can just do this
"browser": "data:text/javascript,",
"deno": "data:text/javascript,",
"default": "./polyfill-node.js" // Or whatever filename
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Creating worker inside of a worker atm is kind of like a polyfill (cuz it gets added to the globalThis atm) I'm a bit afraid if NodeJS would one day go ahead and implement a spec'ed working web worker. Don't really feel like being in any conflict with them if they added it globally But i'm open for suggestion. |
Beta Was this translation helpful? Give feedback.
-
Here's a basic demo of a possible idea or design pattern thing for polyfill/ponyfill stuff: https://github.com/jcbhmr/html-event-error // package.json
{
"imports": {
"#error-event-polyfill.js": {
"node": "./dist/error-event-polyfil-node.js",
"default": "./dist/error-event-polyfill.js"
}
},
"exports": {
".": "./dist/index.js",
"./error-event-polyfill.js": {
"node": "./dist/error-event-polyfil-node.js",
"default": "./dist/error-event-polyfill.js"
},
"./*.js": "./dist/*.js",
"./internal/*": null
},
} // index.ts
if (typeof ErrorEvent === "undefined") {
await import("./ErrorEvent-polyfill.js");
}
if (!("onerror" in globalThis)) {
await import("#error-event-polyfill.js");
}
export {}; // ErrorEvent-polyfill.ts
import ErrorEvent_ from "./ErrorEvent.js";
import ErrorEventInit_ from "./ErrorEventInit.js";
declare global {
// @ts-ignore
type ErrorEvent = ErrorEvent_;
// @ts-ignore
var ErrorEvent: typeof ErrorEvent_;
// @ts-ignore
type ErrorEventInit = ErrorEventInit_;
}
globalThis.ErrorEvent = ErrorEvent_; The gist is that there's many layers of usage. You can use the author's default feature-detection strategy via the default exported path like this. Sometimes it makes more sense to actually have the default export be the ponyfill version though, particularly when a feature-detect is uncertain because there is no standard implementation. In whatwg-workers maybe we want to ponyfill by default? import "@jcbhmr/html-event-error";
onerror = console.log; Or, you could choose to ALWAYS apply the polyfill WITHOUT doing the default feature-detect if gates. This is useful when dealing with prollyfills or stuff that isn't set-in-stone and could change or is unknown. This way, if the actual import "@jcbhmr/html-event-error/ErrorEvent-polyfill.js";
new ErrorEvent("error", { error: new Error() }); 👆 This is particularly interesting given that we don't know if or when or how Node.js will implement the Worker interface. An ungated always-applied polyfill may be a good thing? And finally in this example there's just importing something directly from the innards: import ErrorEvent from "@jcbhmr/html-event-error/ErrorEvent.js";
new ErrorEvent("error", { error: new Error() }); Hopefully that made some sense 😅 I'm trying to push for a similar pattern in web4more/html-navigator#9 |
Beta Was this translation helpful? Give feedback.
-
the hole package.json conditional exports feels like very convoluted to me. kind of like globalThis.ErrorEvent ??= await import('./error-event-polyfill.js') I think it makes things easier for developer who create things like CDN like esm.sh, jsdeliver, unpkg jspm, bundlers etc to not have to deal with this kind package.json things. |
Beta Was this translation helpful? Give feedback.
-
The reason for this: https://github.com/jcbhmr/node-45981 if (!("onerror" in globalThis)) {
await import("#error-event-polyfill.js");
} is that you can't reliably detect whether you're on Node.js without a lot of fuss. For this particular polyfill and some others, you don't want a For something like this: "exports": {
"deno": "./DNE",
"bun": "./DNE",
"node": "./index.js",
"default": "./DNE"
}, This is the behaviour you want in that case. I agree, bad example here since this polyfill whatwg-workers probably doesn't rely on Node.js-specific private symbols. 🤣 |
Beta Was this translation helpful? Give feedback.
-
As for about the "how best to apply polyfill" remark and when where or why to use |
Beta Was this translation helpful? Give feedback.
-
You got a point there. I have done similar practices that checks OS versions once const getIP = unix
? () => exec('ifconfig')
: () => exec('ipconfig') Instead of doing the conditional check every time, (those making it impossible to garbage collect the unix variable and taking up more memory. const getIP = () => exec(unix ? 'ifconfig' : 'ipconfig') (just a simple example) but the same rule applies, better to do things at compile time rather than runtime checks. |
Beta Was this translation helpful? Give feedback.
-
Is this package intended to be both a polyfill and a ponyfill, or just a ponyfill? I like isomorphic polyfills, but that's just personal preference.
Beta Was this translation helpful? Give feedback.
All reactions