Search code examples
requirejsphantomjswirejs

Running a RequireJS/WireJS app using PhantomJS


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.

Solution

  • 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.