stealjs / steal

Gets JavaScript
https://stealjs.com
MIT License
1.37k stars 521 forks source link

steal-clone issue in IE9 #1466

Closed justinbmeyer closed 6 years ago

justinbmeyer commented 6 years ago

I think, but am unsure, there is a steal-clone issue in IE9.

This can be seen by cloning canjs/can-types and running its tests in IE9. The test can-types: should throw if can-namespace.types is already defined will fail.

image

The test tries to reload can-types with types already defined and see that the import() is rejected:

QUnit.test('should throw if can-namespace.types is already defined', function() {
    stop();
    clone({
        'can-namespace': {
            "default": {
                types: {}
            },
            __useDefault: true
        }
    })
    .import('./can-types')
    .then(function() {
        ok(false, 'should throw');
        start();
    })
    .catch(function(err) {
        var errMsg = err && err.message || err;
        ok(errMsg.indexOf('can-types') >= 0, 'should throw an error about can-types');
        start();
    });
});

The import is NOT rejected. It is resolved and the test fails.

CURIOUSLY, the error is thrown as clone seems to be injecting a new namespace. A debugger (or console.log), will be hit here in can-types.js

if (namespace.types) {
        debugger;
    throw new Error("You can't have two versions of can-types, check your dependencies");
} else {
    module.exports = namespace.types = types;
}

The error is caught and seemingly handled right up to doDynamicExecute where linkError is called. Within linkError it even seems to be rejecting a deferred like linkSet thing.

function doDynamicExecute(linkSet, load, linkError) {
    try {
      var module = load.execute();
    }
    catch(e) {
      linkError(load, e);
      return;
    }
    if (!module || !(module instanceof Module))
      linkError(load, new TypeError('Execution must define a Module instance'));
    else
      return module;
  }

After this point, I gave up :-).

justinbmeyer commented 6 years ago

In unsuccessful hopes to simplify the problem, I tried using System.import directly:

System.import("can-types/weird").then(function(){
 console.log("worked")
}, function(){ 
  console.log("borked")
})

Where weird looks like:

console.log("weird");
throw new Error("I DON'T WORK");

This produced expected results:

LOG: weird 
LOG: borked 
matthewp commented 6 years ago

Is there a branch where I can see this problem occurring?

justinbmeyer commented 6 years ago

it's the master branch.

matthewp commented 6 years ago

The master branch of canjs? That doesn't support IE9...

justinbmeyer commented 6 years ago

Noted above:

This can be seen by cloning canjs/can-types

matthewp commented 6 years ago

Ok thanks.

matthewp commented 6 years ago

The problem is with the error, not with steal-clone. I think this is behaving correctly but the assertion is expecting a certain error message.

The problem seems to be that the code-frame plugin we use (the thing that pretty-prints source code) doesn't work in IE9. Going to quickly see if that can be fixed.

matthewp commented 6 years ago

Well, first going to verify that the test will pass once this is bypassed.

matthewp commented 6 years ago

Yeah that's the problem. Given that I can likely isolate the problem further...

matthewp commented 6 years ago

Looks the specific problem with IE is that babel-code-frame depends on __proto__ and IE9 doesn't support that. So we can just check for that support.

matthewp commented 6 years ago

This is fixed in https://github.com/stealjs/steal/releases/tag/v1.12.6. I just ran can-types tests and they pass in IE9.