-
-
Notifications
You must be signed in to change notification settings - Fork 6.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
fix: check exactly in proxyESM #5512
Conversation
cc @Shinigami92 @patak-js thanks 😊 |
I will add test as soon as possible |
test has done, please view it @Shinigami92 😄 |
Seems it was good that we add tests 🙂 |
Is there any progress? |
has updated 😊 @Niputi |
PTAL @sodatea 😊 |
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.
Though this PR does solve the issue for vuex, I feel it's more like a hack than a fix.
Let's fix it in vuex instead. vuejs/vuex#2081
@sodatea yeah,but not only |
Oh, I get it. There are several cases here:
So yeah, there needs to be a compatibility layer in Thanks for bringing this up! |
@@ -212,7 +212,7 @@ function proxyESM(id: string, mod: any) { | |||
return new Proxy(mod, { | |||
get(mod, prop) { | |||
if (prop === 'default') return defaultExport | |||
return mod[prop] | |||
return mod[prop] ?? defaultExport?.[prop] |
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 approach is fragile. If a named export equals undefined or null, the default export is assumed to be an object, but we can't guarantee that.
#5197 was using this logic in proxyESM
...
if (prop in mod) {
return mod[prop]
}
// commonjs interop: module whose exports are not statically analyzable
if (isObject(mod.default) && prop in mod.default) {
return mod.default[prop]
}
// throw an error like ESM import does
throw new SyntaxError(
`The requested module '${id}' does not provide an export named '${prop.toString()}'`
)
...until @matthewp reverted it without explanation.
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 digging into this, @natemoo-re @matthewp could you check why this was removed? Maybe as part of the trials to make CI pass? Let's add this back before releasing 2.7
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'm not sure why this was removed, but this approach LGTM.
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.
The throw was a problem there. Since mod
is an object, any code that imports the namespace can inspect it for keys just like you can do with any object. The throw assumed that the get
always comes from a static import statement but that's not necessarily the case:
// This is valid code
import * as mod from './something.js';
if(mod.someKeyThatDoesntExist) {
// Oops this threw
}
Also the second condition looks wrong to me too. Given this example:
mod.js
export default { color: 'green' };
main.js
import * as mod from './mod.js';
console.log(mod.color);
Should log undefined
but will log 'green' instead. If commonjs interop is needed it needs to verify that the module is commonjs first.
Description
The below code
proxyESM
function judge is not exact in some case like vuex see this pr which not have named export in cjs file.vite
useresolve.sync
get main field from module package.json which point at a commonjs format file generallyAdditional context
when
import { createStore } from 'vuex'
,resolve.sync
will returnvuex.cjs.js
file and this is vuex export codeIt cause we can't use named import from
vuex
only getundefined
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123
).