TypeScript: umd module compiler option doesn't have a fallback for global namespace.
Most umd patterns have a third fallback that allows exporting to the window.namesapace = export; As such the current umd module export is pretty broken when a huge number of users / library developers need to support all three.
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else if (typeof exports === 'object') {
module.exports = factory(require, exports, module);
} else {
root.exceptionless = factory();
}
}(this, function(require, exports, module) {}
About this issue
- Original URL
- State: open
- Created 8 years ago
- Reactions: 87
- Comments: 41 (13 by maintainers)
Commits related to this issue
- chore: try to use tsc output UMD but fail,https://github.com/microsoft/TypeScript/issues/8436 — committed to do-once/cbb by BryanAdamss 2 years ago
If the
umd
module can not support global variable, why typescript call itumd
? So I suggest remove this option if it can not support.@kitsonk Although I have some words to refute you, I shut up at this time to avoid meaningless argument in this thread. I just want
typescript
to fix this, or if you really want to keep it, at least document it explicitly. The UMD, as a convention, usually supports global variable. current situation really makes users confused.How about this solution:
Example input
source/index.js
When following options are specified in
tsconfig.json
, it enables code generation for global object exports:Generated
compiled/index.js
:It does generate a lot of overhead code for every file, but it’s completely optional.
Edit: For this to work, every library imported must either be contained in one file (i.e. all the libs that use UMD with globals currently) or use the same scheme. It’s a pretty big win IMO.
@kitsonk,
Why? TS is already doing that and it isn’t too ugly.
We don’t need a bundler, instead we need a proper emission for
export as namespace
.Any news on this issue? At moment what is “bes tway” (or just an acceptanle one) to implement an UMD module with TypeScript? I mean a module that falls back on globals i needed.
I need to implement a library composed of several modules that user may select accordint to its need. I would like each module be UMD, so user may decide how and if bundling the modules it needs.
It appears that my plan at moment is very difficult to implement in TypeScript. The only way I can think of is:
The above appears to me the only way to get TRUE UMD modules from TypeScript.
Any thought about this?
Better proposals?
There is precedent [1] [2] for compilers that output UMD to take a separate parameter for the global name. But I guess since you already have
export as namespace
you might as well use it.Wow, just ran into this today. It’s 2021. This started in 2016.
tsc
is the easiest way to compile, but I can’t use it. All I want is a simple application that runs in the browser without having to load something else. 😬I ran into this issue today.
I really need an
else
block as this 😉I was disappointed when I saw my UMD module did not work in browser. Standard or not, UMD means something to web developers and Typescript is just misleading when it says UMD but does not output proper UMD.
Is it not possible for the typescript compiler to incorporate a bundle process, either one that already exists - webpack/rollup or one that theoretically shouldn’t be too difficult to implement? I mean there are solutions to this problem, namely export as CommonJS and have a bundler re-bundle as UMD. However that kind of defeats the purpose of having the UMD option in typescript.
You wouldn’t really have to change anything for the current UMD process, just add an extra config option so previous code is still maintained in the same way.
As discussed in #9678, if we use
export as namespace
for setting the global name, then the export clause needs to be allowed in normal code other than declarations (.d.ts
), otherwise library authors that are deriving their declarations from the--declaration
flag have to add the clause at each recompile because it’s overwritten.So merging the two needs, my proposal is:
When
--module
isumd
and there’s anexport as namespace
in module code, TypeScript should:.d.ts
with the same clauseexport as namespace
Example: developer is writing a library “myreact” to be consumed in modules and in global:
myreact.ts
:Typescript output
myreact.d.ts
:myreact.js
:You can find a discussion on why UMD implementation does not support the global in https://github.com/Microsoft/TypeScript/pull/2605.
mainly, what is the variable name to use, and how to manage dependencies.
One possibility is to use the new
export as namespace <id>
syntax added in https://github.com/Microsoft/TypeScript/pull/7264, but we will need a proposal for that.@saschanaz I am not saying that solving the problem isn’t warranted. I am just pointing out that there is no UMD “standard” to adhere to and it makes it non-sensical to suggest removing the feature as @njleonzhang suggested.
Of course once you start dealing with deep creation of the global var, you start making the emit pretty darn ugly and starts really encroaching on contravening non-goal:
If you need a bundler, use a bundler.
Maybe we can accept some popular behavior, for example from rollup.js . https://github.com/twitter/twitter-text/blob/master/js/rollup.config.js#L36-L37
@njleonzhang, UMD is a convention, not a standard and global modification is not entirely consistent or common in implementations. It is also a bit too late to remove it.
Is this the only blocker here? How about allowing
export as namespace A.B.C
, with the behavior similar withnamespace A.B.C
?This no clear reason why you’d need hacks or additional tools to accomplish such a small thing.
Why can’t we have something like
"moduleGlobal": "var_name"
, which would add a global variable fallback for module types likeamd
,commonjs
andumd
? That makes it opt-in and doesn’t interfere with existing projects that might not want it.I really don’t want hacks (or big tools like webpack) for a simple small library 😐
I just found another hacky workaround for rollup at https://github.com/rollup/rollup/issues/494#issuecomment-268243574