This Stack Overflow describes the problem in details:
http://stackoverflow.com/questions/38651209/how-can-i-wrap-an-import-with-jsdom
But basically my question is this: jsdom has to "wrap" code to get used, but it's impossible to "wrap" an ES6 module import (ie. import foo form 'bar'
) because they have to come before any code. And if DOM-using code is part of the import itself, it needs to be wrapped by JSDom
Is there a way around this?
Since JS modules are not supported in any engine, you are presumably using some transpiler like Babel or TypeScript to convert your source to normal, supported JavaScript that can run in Node.js or browsers. You should do the same thing before feeding your code to jsdom. We have no intention of supporting something that is not yet implemented in browsers.
Well, I am using Babel, as part of Mocha, ie mocha --compilers js:babel-core/register test.js
. So, I am using a transpiler "before feeding [my] code to jsdom." It just doesn't help, because of the problem I described.
It's true that ES6 modules are new and not supported in the browser, so I would totally understand not supporting them. However, major libraries are using them in their documentation as if they were the standard (eg. Redux, http://redux.js.org/docs/basics/ExampleTodoList.html) ... which makes sense because they (arguably) are the standard module system for JS.
So I guess what I'm saying is, ES6 modules aren't going away, and this problem seems to be intrinsic to them. JSDom can solve the problem now or kick the can down the road (a _totally_ legitimate option), but ultimately if the library is going to work with this increasingly popular standard then someone will have to address the problem.
Either way, thanks for considering the issue.
There are two issues you're encountering here.
First off, thanks for the wiki link; it was a piece in the puzzle which ultimately led me to the solution (at this awesome blog: http://www.2ality.com/2014/09/es6-modules-final.html). As it explains, there _is_ a way to do imports in a way that they can be wrapped by JSDom: System.import
.
Here's the solution to the problem for other ES6/JSDom-lovers:
import jsdom;
jsdom({
html: '<div></div>',
done: () => {
// don't do this:
// import setup from 'setup';
// do this:
System.import('setup')
.then((setup) => {
// test code that uses setup
})
}
});
NOTE: If you're using a test framework like Mocha, you'll need to use it's asynchronous test functionality to make this work (ie. you need a done
argument in your it
function, and then you'll need to invoke done
after the test finishes).
Anyhow, I hope that helps anyone else going down this road, and thanks again for the help in solving it.
Most helpful comment
First off, thanks for the wiki link; it was a piece in the puzzle which ultimately led me to the solution (at this awesome blog: http://www.2ality.com/2014/09/es6-modules-final.html). As it explains, there _is_ a way to do imports in a way that they can be wrapped by JSDom:
System.import
.Here's the solution to the problem for other ES6/JSDom-lovers:
NOTE: If you're using a test framework like Mocha, you'll need to use it's asynchronous test functionality to make this work (ie. you need a
done
argument in yourit
function, and then you'll need to invokedone
after the test finishes).Anyhow, I hope that helps anyone else going down this road, and thanks again for the help in solving it.