-
Notifications
You must be signed in to change notification settings - Fork 62
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(component-testing): ability to import esm modules #1024
Conversation
c123e41
to
7ecf23d
Compare
1) `import pkg from "package"` -> `const pkg = new Proxy({}, {get: ..., apply: ...})` | ||
2) `import {a, b as c} from "package"` -> `const {a, c} = new Proxy({}, {get: ..., apply: ...})` | ||
*/ | ||
function mockEsmModuleImport(t: typeof babel.types, path: NodePath<babel.types.ImportDeclaration>): void { |
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.
Used method from here - https://babeljs.io/docs/babel-types.
In order to implement it I did use ast explorer - https://astexplorer.net/.
node: NodePath<babel.types.ImportDeclaration>["node"], | ||
): babel.types.Identifier | babel.types.ObjectPattern { | ||
if (node.specifiers.length === 1) { | ||
if (["ImportDefaultSpecifier", "ImportNamespaceSpecifier"].includes(node.specifiers[0].type)) { |
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.
ImportDefaultSpecifier
-> import pkg from '...'
,
ImportNamespaceSpecifier
-> import * as pkg from '...'
return t.identifier(node.specifiers[0].local.name); | ||
} | ||
|
||
return t.objectPattern([ |
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.
Here support case like:
import {a, b, c as d} from "..."
t.identifier(node.specifiers[0].local.name), | ||
t.identifier(node.specifiers[0].local.name), | ||
false, | ||
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.
shorthand
, it means use {a}
instead of {a: a}
assert.match(transformedCode, new RegExp(`require\\("${moduleName}"\\)`)); | ||
}); | ||
|
||
describe.only("replace import of esm module with a proxy", () => { |
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.
todo: remove it
7ecf23d
to
3847147
Compare
return; | ||
} | ||
|
||
if ((err as NodeJS.ErrnoException).code === "ERR_REQUIRE_ESM") { | ||
mockEsmModuleImport(t, path); | ||
return; |
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 you return here?
Doesn't it make it work only once?
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 use return
here just for the case if some another handler will be add below.
Doesn't it make it work only once?
This code located inside ImportDeclaration
which is called on each import
declaration. So it can ignore few esm modules.
3847147
to
46ef7f0
Compare
What is done
In component testing user can import esm modules in the test file, because it executes in the browser, which support them. But test files also import in nodejs environment which supports only cjs. Because of this all esm only modules throw
ERR_REQUIRE_ESM
error in nodejs env.So i implement replacing import esm module to variable with proxy. Like this:
This proxy gives ability to call every method or getter that user want.
Need review only second commit.