phonegap / phonegap-app-developer

PhoneGap Developer App
app.phonegap.com
Apache License 2.0
2k stars 2.51k forks source link

RequireJS + Phonegap Developer App problem #339

Open kvzaytsev opened 9 years ago

kvzaytsev commented 9 years ago

Hello!

I'm trying to use RequireJS in Phonegap Application. It works great on real device with applicaiton built using Phonegap cloud building, but sometimes does not work using Phonegap Developer App. (tested with iOS and Android 5). That is simple project I created: https://drive.google.com/file/d/0B2GGYFr2TYMNcmI0MUE5R3dfb0U/view?usp=sharing

Could you please help me with this problem?

Thanks in advance!

simar88 commented 9 years ago

I found the same issue this morning using iphone 6. Any solutions for this problem? Thanks in advance!

bakineugene commented 9 years ago

Hi. We investigated this problem a bit and found out that it's caused by script socket.io.js which is appended to body by phonegap serve. So it's not strictly phonegap-app-developer issue.

It uses require.js when available and that causes "Mismatched anonymous define()" error. http://requirejs.org/docs/errors.html#mismatch

Solution is described here: http://stackoverflow.com/questions/15371918/mismatched-anonymous-define-module

"load the non-require.js standalone bundles in script tags before require.js is loaded"

mwbrooks commented 9 years ago

@EugeneBakin thanks for tracking this down. I can likely fix this issue if you need to have socket.io.js loaded before the other scripts.

bakineugene commented 9 years ago

@simar88 Another possible way to work around it - is to namespace your require related functions: http://requirejs.org/docs/faq-advanced.html#rename

bakineugene commented 9 years ago

@mwbrooks

It should be executed before require.js defines its functions. If not it would use define and would not expose itself as a global variable.

ghost commented 8 years ago

The bug is still present but i managed to fix it using setTimeout()'s and script injection.

Also you should extend the console object instead of overwriting it with socket.io wrappers. I relied on console.groupCollapsed() and since you removed it my code broke.

For everyone else having these problems: You can find the code that monkey-patches my App below. Add it as the first script to your <head> and it should just work

function injectRequirejs() {
    var h = document.getElementsByTagName('head')[0];
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.src = 'bower_components/requirejs/require.js';
    s.setAttribute('data-main', 'js/Main.js');
    h.appendChild(s);
}

function fixConsole(callback) {
    if (window.console.log.toString().match(/.*socket.*/gi) !== null) {
        window.console.log = function (msg, format) {
            __console__.log(msg, format);
        };

        window.console.groupCollapsed = function (msg, template) {
            __console__.groupCollapsed(msg, template);
        };

        window.console.groupEnd = function () {
            __console__.groupEnd();
        };

        callback();
    } else {
        setTimeout(function () {
            fixConsole();
        }, 500);
    }
}

(function () {
    window.__console__ = window.console;

    setTimeout(function () {
        if (typeof window.phonegap !== typeof undefined) {
            console.log('Monkey-patching phonegap... (This may take some time)');
            fixConsole(injectRequirejs);
        } else {
            injectRequirejs();
        }
    }, 1000);
})();

Remember to remove this script in non-debug builds.