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
Refactor and simplify umd wrapper #2594
Conversation
remove unnecessary parentheses in UMD and IIFE
do not render global if not used in intro
@doug @DanielRuf This is a follow-up to your PRs, please see if this solves your issue. I did not adjust the IIFE wrapper as this would have become much more complex when accounting for a different |
}};${n}`; | ||
globalExport += `${t}})()`; | ||
globalExport = | ||
`(function()${_}{${n}` + |
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.
food for thought on readability: I've often used a single template literal enclosure (and line breaks within them) to make the contents more readable in code, and then stripped newlines afterwards. that is of course, a stylistic preference.
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.
Definitely a good idea though I would feel bad about doing something at runtime that can be done at compile time. Then again, I am not 100% satisfied with the code quality in these wrappers but could not muster the energy and time to do a larger refactoring :( I.e. if we extract more and meaningful sub-strings, the template strings would not get that complicated and the outermost string would just concatenate a few abstract building blocks.
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 taking a look!
`${_}${cjsExport}factory(${cjsDeps.join(`,${_}`)})${_}:${n}` | ||
: ''; | ||
|
||
const wrapperIntro = |
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.
👍
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 picking this one up @lukastaegert.
Since there are cases when self could be defined but not point to the global object would the following also work |
Hmm, actually a good point. Since with the latest refactoring, the global object is only retrieved when it is actually needed and therefore everything will fail if both |
In Node.js |
@guybedford Since node doesn't define self as a global object by default. The current(or previous) umd wrapper has worked so far for node so isn't this what you'd want? |
I guess |
Explicit access to the global object is only and will only ever be necessary for the IIFE path but we still need to pass in How about changing the wrapper like this and only testing for // default export
(function (globalThis, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(globalThis || self).myBundle = factory();
}(this, function () {
// body
})); // named exports
(function (globalThis, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
factory((globalThis || self).myBundle = {});
}(this, function (exports) {
// body
})); |
Sounds good, and if there are any global issues we can always fix them later. |
I might have missed something in the release notes but it seems that {
input: 'src/index.js',
output: {
file: `dist/${pkg.name}.js`,
banner: banner,
format: 'umd',
globals: {
'chart.js': 'Chart'
}
},
external: [
'chart.js'
]
} I'm getting this wrapper: (function (factory) {
typeof define === 'function' && define.amd ? define(['chart.js'], factory) :
factory(global.Chart);
}(function (Chart) { 'use strict';
... with this error:
and in case of CJS loader, shouldn't we expect |
Yes, it seems I missed something here. I hope I have the fix together tomorrow, I am currently working on better tests so this does not happen again. |
@simonbrunel Fix at #2600 |
Thanks a lot @lukastaegert |
How do I output the following example code? // new wrapper with default export
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.myBundle = factory();
}(typeof self !== 'undefined' ? self : this, function () { 'use strict';
var main = 42;
return main;
})); I need to get typeof self !== 'undefined' ? self : this We can use Webpack in the following ways module.exports = {
// ...
output: {
library: 'myLib',
libraryTarget: 'umd',
filename: 'myLib.js',
// to replace global this
globalObject: `typeof self !== 'undefined' ? self : this`,
},
}; |
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers:
Closes #2274,
closes #1964
Description
This PR refactors the UMD header to achieve several things:
this
to find the global variable, which does not work in strict mode, it will first check ifself
is present and can be used.self
is similar towindow
but should work properly in more contexts.noConflict
option is not used, there is no difference between the CJS and IIFE intro. Thus we skip the check if we are in a CJS environment. The difference will be that if we are in a CJS environment that is also an AMD environment, AMD will not receive preference. I hope this is not an issue for anyone.noConflict
option is not used, the global variable is not used and is now removed entirely from the wrapperSome examples:
I hope I did not miss anything here. Just look at the adjusted tests for more examples. I also removed an unnecessary pair of parentheses from the IIFE wrapper.