Default export/import from external module is not working as expected when running coverage
Opened this issue · 7 comments
Default export/import from external module is not working as expected when running coverage
Hello,
I've found an issue when using an external module/library which provides a default export.
The external module is compiled from es6 -> es5 with systemjs. When i import this external module foo.js
in my bar.js
everything works, as expected, in the browser as well as in my unit tests.
But as soon as i enable the coverage and prepreprocessor options in karma.conf.js my test will fail.
I have created a small project to illustrate the issue: https://github.com/kkluijtmans/module-bar
The external module can be found in lib/module-foo.js
The bar.js
in js/bar.js
When running the test with coverage js/bar.spec.js
is called which imports bar.js
via the import {foo, fooName} from './bar.js';
statement
The following is happening bar.js
:
import es5ModuleFoo from 'module-foo/foo.js';
...
console.log('## es5ModuleFoo: ' + es5ModuleFoo.name + ' -> ' + JSON.stringify(es5ModuleFoo)); // ## es5ModuleFoo: undefined -> {"default":{"name":"foo"}}'
...
es5ModuleFoo
is resolved as {"default":{"name":"foo"}}
but it should be resolved as {"name":"foo"}
I've added several log statements in bar.js
to illustrate the issue and added more info in my readme.md from the module-bar project
The es6 version of foo.js
from lib/module-foo.js
looks like this:
var foo = {
name: 'foo'
};
export default foo;
Am i doing something wrong or is this really a bug?
+1
I need this fix too! +1
+1
+1
+1
+1
I tried to analyse what is happening, and seems that:
- isparta translates import statements into commonjs require statements
- the modules inside the systemjs bundle do no include an __esModule export
- babel expects an __esModule flag to be set in order to properly handle default exports inside a module when using commonjs.
So a few systems are involved. I'm not familiar enough with the systems to know where to change what to get this working. Options I see:
- isparta allows import transpilation into something different then commonjs require (is this possible?)
- systemjs includes __esModule flag (There is a lot of discussion about this see among others Consider default export convenience #304, at the moment it appears this not going to happen)
I used the hack below when creating a systemjs bundle. This seems to work in a very small test project. I doubt it will work for more complex project that include non es6 modules, but I will give it a try:
Inside the option object of the builder.bundle call, add the following
fetch: function (load, fetch) {
var src = fetch(load);
return src.then(function(thesource) {
//HACK to force proper loading as commonjs module during unittest coverage
if (thesource.indexOf('export default') > -1) {
return 'export var __esModule = true;\n' + thesource;
} else {
return thesource;
}
});
}