-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[feat] treat typescript namespace like import * as foo from 'foo'
which refer to ImportNamespaceSpecifier
in AST
#3077
Comments
You also filed #3076 about a similar thing. But regardless of how you generate a JavaScript object, it's still a huge increase in complexity to tree-shake JavaScript objects in the way you are asking for, so this is not something that esbuild does. The problem is that JavaScript objects are not namespaces, and they do not work like real namespaces do in languages which have that feature. One source of complexity is that you can still access all other properties via It looks like Rollup and Parcel don't do this transformation either, which is presumably due to the same complexity issues. I recommend that you use normal ESM exports the way they are intended to be used if you are interested in enabling tree shaking of your code: ==> entry.mts <==
-import TypeRegistry from './lib.mjs'
+import * as TypeRegistry from './lib.mjs'
TypeRegistry.Clear()
==> lib.mts <==
const map = new Map<string, unknown>()
-function Entries() {
+export function Entries() {
return new Map(map)
}
-function Clear() {
+export function Clear() {
return map.clear()
}
export default /* @__PURE__ */{ Entries, Clear } |
Awesome! // lib.mts
var map = /* @__PURE__ */ new Map();
function Clear() {
return map.clear();
}
// entry.mts
Clear(); |
What about treat namespace like this behavior too?
Ast parse it as But that may require library has typescript entry when bundling, because there is no namespace in js runtime. If you think this not actionable, I'm OK to close this feat. |
import * as foo from 'foo'
which refer to ImportNamespaceSpecifier
in AST
Sorry, I don't understand what you're saying. I don't know what you mean by "namespace" or "ImportNamespaceSpecifier". |
typescript have namespace And babel parse But typescript namespace have zero tree-shake support. And |
import * as foo from 'foo'
which refer to ImportNamespaceSpecifier
in ASTimport * as foo from 'foo'
which refer to ImportNamespaceSpecifier
in AST
TypeScript's namespaces are just syntax sugar for constructing a mutable JavaScript object, which has all of the same issues. It would be equally unsafe for esbuild to do this for TypeScript namespaces. One important difference between normal JavaScript objects and the objects that you get when you import a namespace (called module namespace exotic objects in the JavaScript specification) is that module objects don't allow you to mutate their properties. That means esbuild doesn't have to account for the possibilty of them being mutated. It's the opinion of the TypeScript team that if you are already using ESM syntax, then you should probably shouldn't be using TypeScript namespaces for code organization: microsoft/TypeScript#30994 (comment). Instead you should be using ES modules. They are standardized across the JavaScript ecosystem, they have better support from existing tooling (e.g. you get tree shaking), they generate smaller code when minifying (since export names can be minified), and they even make your code run faster at run-time (since you avoid property access overhead). The TypeScript code base itself even moved away from TypeScript namespaces to ES modules because ES modules are better. I don't think it's worth it for esbuild to add additional complexity to support these unusual and non-recommended workflows. Instead, I recommend that you do code organization using normal ESM exports the way they are intended to be used. |
Thanks for your very professional and very detailed explaination! Close in favor of sinclairzx81/typebox#408 |
Reproduce
$ npm exec -- esbuild --format=esm --bundle ./entry.mts
Actual
Expected
Related
sinclairzx81/typebox#401
The text was updated successfully, but these errors were encountered: