Skip to content
This repository has been archived by the owner on Dec 31, 2019. It is now read-only.

Default export/import from external module is not working as expected when running coverage #96

Open
kkluijtmans opened this issue Nov 27, 2015 · 7 comments

Comments

@kkluijtmans
Copy link

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?

@marijer
Copy link

marijer commented Dec 16, 2015

+1

@harmens
Copy link

harmens commented Dec 16, 2015

I need this fix too! +1

@ldd
Copy link

ldd commented Jan 19, 2016

+1

3 similar comments
@peterjuras
Copy link

+1

@chauthai
Copy link

+1

@screendriver
Copy link

+1

@piebe
Copy link

piebe commented Feb 23, 2016

I tried to analyse what is happening, and seems that:

  1. isparta translates import statements into commonjs require statements
  2. the modules inside the systemjs bundle do no include an __esModule export
  3. 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:

  1. isparta allows import transpilation into something different then commonjs require (is this possible?)
  2. 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;
      }
    });
 }  

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants