-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
Add noConflict entry mode to @babel/polyfill #6371
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/5768/ |
Came to make this exact change, is there anything preventing this from being incorporated in the next patch version? If the merge conflict is the only blocker, I'd be happy to re-fork and make this change against the latest version. |
Actually, does it makes sense to prevent further execution if an existing global._babelPolyfill is found? |
d6d1f9b
to
1504a91
Compare
@jbenner rebased and adjusted the implementation |
The title of this says it will show a warning, but you don't appear to have that in the code. The warning is specific because the polyfill is global, so if you're loading multiple copies you, or something else on the page with you, is likely doing something wrong. I'm fine with it not being a hard error, but it should at least have a warning for users since 90% of the time this will be a bug, even if it isn't 100% of the time. |
@loganfsmyth that was the original implementation, sorry for the confusion. I agree with @jbenner that simply not applying the polyfill more than once by checking for the global flag is a more elegant solution. If you'd like I can definitely also add a warning, but this behavioral revision |
Nice - I think a warning if global._babelPolyfill === true when babel-polyfill is loaded is helpful. The console.warn makes sense, similar to what's seen when minifying the development version of React (a gentle prodding that implies "are you sure this is what you meant to do?"). Thanks for updating this! |
@evan-scott-zocdoc The issue is that If we're not going to throw, we absolutely at least need to keep running the polyfill both times, with a warning for users. The reason this warning exists is because |
@loganfsmyth Perhaps the guard should be discarded then and split apart into separate guards for each of the polyfills. The specific use case where this error becomes very annoying is when you do own a page and you're injecting multiple of your own bundles onto it in various combinations. |
Have you explored using Webpack's chunking plugins? Usually I'd expect that to be configured so even when you eventually load multiple pages of an app, the common stuff only loads once. Otherwise you're also wasting tons of bandwidth redownloading something you already got. |
@loganfsmyth yeah, we have a mixed environment so this sort of stuff becomes very challenging, unfortunately. |
There's nothing stopping you from doing |
We currently use Webpack's chunking plugin to extract shared libraries to a common file, but have an ecosystem where not all developers are integrated into our unified frontend build (yet). Much of the desire behind this is to avoid careful release timing between non-integrated applications that reside in the shared space. It would seem that a developer using Can you help me understand the use case where it's valid to import babel-polyfill multiple times at different versions and expect them to coexist happily, without additional work? If I am picturing this correctly, changing from a I do admit that a |
Totally agree. I was suggesting it because I'd expect most of the people running into this today who want to work around it fall into that
The polyfills will happily coexist. The regenerator runtime is the tough part, but I also don't know of any expected changes to it, so it's kind of a toss-up, so realistically I see no reason to throw. The goal is 100% to say "hey you're downloading two copies of the polyfill and that's probably an accident", so changing it to a warning, and exposing a way to explicitly opt out of the warning seems fine to me.
Maybe we can expose a
that would set the global flag then unset it with the |
Actually that would work wonderfully. Especially if you could just import it like import 'babel-polyfill/noConflict'; |
I could see that getting complicated though when used in conjunction with babel-preset-env, since it replaces the import call with individual ones when "usage" mode is enabled. |
Fair. We could pretty easily make preset-env detect both though. |
How would noconflict work with webpack when used in entry? would it just be: 'entry': [
'test': ['babel-polyfill/noConflict', srcdir + '/test/app.jsx'],
] |
@rhan-mentad yeah exactly |
1504a91
to
a580c2d
Compare
a580c2d
to
4fa188d
Compare
@loganfsmyth Revised, let me know what you think! |
packages/babel-polyfill/src/index.js
Outdated
global._babelPolyfill = true; | ||
|
||
import "core-js/shim"; | ||
import "regenerator-runtime/runtime"; | ||
require("core-js/shim"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed these to require
since import
by spec has to be at the top of the file, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you feel about ordering? Most frameworks would do this logic as essentially
require("core-js/shim");
require("regenerator-runtime/runtime");
if (global._babelPolyfill) {
throw new Error(
"@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended and may have consequences if different versions of the polyfills are applied sequentially. If you do need to load the polyfill more than once, use @babel/polyfill/noConflict instead to bypass the error.",
);
}
global._babelPolyfill = true;
modue.exports = function(){
global._babelPolyfill = false;
};
with /noConflict
just doing
require("./index").noConflict();
so if something loaded first in non-conflict mode, it'd error, but you can explicitly say that the version you are loading should not conflict with things loaded later.
.eslintrc
Outdated
@@ -6,7 +6,8 @@ | |||
"rules": { | |||
"curly": ["error", "multi-line"], | |||
"prettier/prettier": ["error", { "trailingComma": "es5" }], | |||
"no-case-declarations": "error" | |||
"no-case-declarations": "error", | |||
"max-len": ["error", { "ignoreStrings": true }] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd just wrap the string with concatenation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay :( just felt gross
c8c0988
to
1f01a5c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your PR.
LGTM if that can fix your issue.
@xtuc can this be merged? |
Isn't it quite different from what |
What would you name it then? |
|
So, why is That:
But:
|
@arfordweb for what it’s worth, I 100% agree with making this a console error or warning rather than a hard one and that was even the original PR before code review |
As @evan-scott-zocdoc mentioned in his comment, will this PR manage multiple polyfills bundled with different PS: Would it be nice to add some guidelines to babel doc for developers releasing Web libraries? (like bundling 2 libraries, one with polyfills and another one without any polyfill.. I duno.. 🤷♂️) |
@yvele they'd still clobber each other, the way we compile code via babel would need to change a lot to overcome this :/ |
packages/babel-polyfill/src/index.js
Outdated
console.warn( | ||
"@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended " + | ||
"and may have consequences if different versions of the polyfills are applied sequentially. " + | ||
"If you do need to load the polyfill more than once, use @babel/polyfill/noConflict " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this has to be @babel/polyfill/lib/noConflict
right? since it's not the main file.
packages/babel-polyfill/src/index.js
Outdated
@@ -1,7 +1,13 @@ | |||
import "core-js/shim"; | |||
import "regenerator-runtime/runtime"; | |||
|
|||
if (global._babelPolyfill) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we do
if (global._babelPolyfill && typeof console !== "undefined" && console.warn) {
so that this doesn't throw on platforms that don't have console
?
packages/babel-polyfill/src/index.js
Outdated
console.warn( | ||
"@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended " + | ||
"and may have consequences if different versions of the polyfills are applied sequentially. " + | ||
"If you do need to load the polyfill more than once, use @babel/polyfill/lib/noConflict " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if we want to expose this, we should make a noConflict
in the root that proxies through. I don't like people even knowing lib
exists really.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok for sure I don't like the lib thing either
@@ -0,0 +1 @@ | |||
import "lib/noConflict"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would need to be require
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and ./lib/
, not lib/
Currently if babel-polyfill is used twice on the same page, a hard error is emitted. This is unfortunate from a developer experience perspective because we can't always be in control of what is being loaded by library authors or other packages.
Assuming loading polyfill twice doesn't actually break anything, a warning would be much more friendly and avoid breaking build systems that halt on JS errors when the application remains functional.