Pergunta

I'm trying to execute a basic app that uses RequireJS (2.1.8), WireJS (0.10.2) and PhantomJS (1.9.2):

  • When running the app using PhantomJS (this is my goal), WireJS fails to load (see error below).
  • When running the app using Chrome, it completes properly.

Please help to point out the missing part for WireJS to run properly under PhantomJS.

Following are my app files.

1) app.html

<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="utf-8">
<title>SaphirJS.core</title>
<script data-main="app" src="../../../target/deps/require-0.0.1/2.1.8/require.js">  </script>
</head>
<body>
</body>
</html>

2) app.js

"use strict";

require.config({
    baseUrl: ".",

    packages: [
        { name: 'wire', location: '../../../target/deps/wire-0.0.1/0.10.2', main: 'wire' },
        { name: 'when', location: '../../../target/deps/when-0.0.1/2.4.1', main: 'when' },
        { name: 'meld', location: '../../../target/deps/meld-0.0.1/1.3.0', main: 'meld' }
    ]
});

require(["wire!wireContext"], function(wireContext) {
    alert(wireContext.message);
});

3) wireContext.js

define({
    message: "Hello World!"
});

4) phantom-runner.js

(function() {
    'use strict';

    var args = require('system').args,
        timeoutRef = undefined,
        timeLimit = 10000;

    // arg[0]: scriptName, args[1...]: arguments
    if (args.length !== 2) {
        console.error('Usage:\n  phantomjs runner.js [url-of-your-qunit-testsuite]');
        phantom.exit(1);
    }

    var url = args[1],
        page = require('webpage').create();

    // Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
    page.onConsoleMessage = function(msg) {
        console.log(msg);
    };

    page.onInitialized = function() {
        timeoutRef = setTimeout(function(){
            console.error('Test Run Failed. Timeout Exceeded. Took longer than '+ timeLimit / 1000 +' seconds.');
            phantom.exit(1);
        }, timeLimit);
    };

    page.onAlert = function(message) {
        clearTimeout(timeoutRef);
        phantom.exit(0);
    };

    page.open(url, function(status) {
        if (status !== 'success') {
            console.error('Unable to access network: ' + status);
            phantom.exit(1);
        }
    });
})();

5) The error when running the app under PhantomJS

TypeError: 'undefined' is not a function (evaluating 'Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty)')

  <path-to-deps>/wire-0.0.1/0.10.2/lib/object.js:13
  <path-to-deps>/require-0.0.1/2.1.8/require.js:1635
  <path-to-deps>/require-0.0.1/2.1.8/require.js:871
  <path-to-deps>/require-0.0.1/2.1.8/require.js:1142
  <path-to-deps>/require-0.0.1/2.1.8/require.js:779
  <path-to-deps>/require-0.0.1/2.1.8/require.js:1169 in callGetModule
  <path-to-deps>/require-0.0.1/2.1.8/require.js:1529
  <path-to-deps>/require-0.0.1/2.1.8/require.js:1656
Error: Load timeout for modules: wire!wireContext_unnormalized2
http://requirejs.org/docs/errors.html#timeout

  <path-to-deps>/require-0.0.1/2.1.8/require.js:138 in defaultOnError
  <path-to-deps>/require-0.0.1/2.1.8/require.js:536 in onError
  <path-to-deps>/require-0.0.1/2.1.8/require.js:691 in checkLoaded
  <path-to-deps>/require-0.0.1/2.1.8/require.js:710

Test Run Failed. Timeout Exceeded. Took longer than 10 seconds.
Foi útil?

Solução

You are right, Younes. PhantomJS doesn't support Function.prototype.bind for some reason.

You can polyfill Function.prototype.bind by using either cujoJS/poly or kriskowal/es5-shim.

Outras dicas

As mentioned in the comments to the question, the origin of this problem is the fact that PhantomJS doesn't implement 'Function.prototype.bind()' function.

As suggested by the people from PhantomJS and WireJS, the problem would be fixed using an ES5 polyfill. The implementation suggested by MDN didn't help as it is a partial implementation of the specs. The implementation included in CujoJS/PolyJS has solved my problem. Now, WireJS is happy with PhantomJS.

Hereinafter is the new version of app.js

"use strict";

require.config({
    baseUrl: ".",

    packages: [
        { name: 'wire', location: '../../../target/deps/wire-0.0.1/0.10.2', main: 'wire' },
        { name: 'when', location: '../../../target/deps/when-0.0.1/2.4.1', main: 'when' },
        { name: 'meld', location: '../../../target/deps/meld-0.0.1/1.3.0', main: 'meld' },
        { name: 'poly', location: '../../../target/deps/poly-0.0.1/0.5.2', main: 'poly' }
    ]
});

require(["poly/function", "wire!appWireContext"], function(poly, wireContext) {
    alert(wireContext.message);
});

Cheers

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top