Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We���ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r.js optimizer: Cannot read property '0' of undefined at Function.findAnonDefineFactory #157

Closed
idflood opened this issue Apr 26, 2012 · 10 comments
Milestone

Comments

@idflood
Copy link

idflood commented Apr 26, 2012

HI,

I have a relatively large project using most of the require.js plugins. The current master branch of this project already use r.js to optimize the final build and is working nicely. However r.js breaks when optimizing the dev branch (both branches runs fine without optimization). There are two major differences between the two branches. The dev uses the cs! plugin and also namespace.coffee. There is probably something wrong with one of these but I find debugging this with the following error really difficult.

The complete error looks like this

TypeError: Cannot read property '0' of undefined
at Function.findAnonDefineFactory (/Applications/MAMP/htdocs/ThreeNodes/node_modules/requirejs/bin/r.js:9634:26)
at Function.findAnonDefineFactory (/Applications/MAMP/htdocs/ThreeNodes/node_modules/requirejs/bin/r.js:9651:38)
...

In the findAnonDefineFactory function from r.js the call from call = node[1]; is simply undefined when this error appear. So changing the condition

if ((call[0] === 'name' && call[1] === 'define') || (call[0] === 'dot' && call[1][1] === 'require' && call[2] === 'def'))

to

if (call && ((call[0] === 'name' && call[1] === 'define') || (call[0] === 'dot' && call[1][1] === 'require' && call[2] === 'def')))

makes the error disappear but the resulting js is not working. So this is not a good idea. I reverted this change and then modified the function where this get called. If I change the parse.getAnonDeps function like this:

    parse.getAnonDeps = function (fileName, fileContents) {
        try{
            var astRoot = parser.parse(fileContents),
                defFunc = this.findAnonDefineFactory(astRoot);

            return parse.getAnonDepsFromNode(defFunc);
        }
        catch (err) {
            err.message = "Error in : " + fileName + ". " + err.message;
            throw(err);
        }
    };

The error shown become a little bit interesting.

TypeError: Error in : /Applications/MAMP/htdocs/ThreeNodes/src/scripts/libs/coffee-script.js. Cannot read property '0' of undefined
at Function.findAnonDefineFactory (/Applications/MAMP/htdocs/ThreeNodes/node_modules/requirejs/bin/r.js:9638:26)
....

Should I make a pull request for the last proposed change? Any idea why this error is happening?

@idflood
Copy link
Author

idflood commented Apr 26, 2012

Still trying to figure out what is wrong, I modified one of the last line of coffee-script.js temporarily from

define(function() { return CoffeeScript; });

to

define([], function() { return CoffeeScript; });

With this modification the optimization doesn't crash but the resulting js doesn't run properly neither. It throw an error about Unexpected token return. The error comes from a line that appear at the end of underscore, this may be added by r.js and/or the use! plugin.

define("Underscore", function(){});
define('use!Underscore', [],return typeof _ !== "undefined" ? _ : void 0);

This is too much "strange" errors, I must be missing something essential here.

@idflood
Copy link
Author

idflood commented Apr 27, 2012

I've created a minimal project reflecting the setup I'm using: https://github.com/idflood/next-boilerplate.js

The r.js optimize function is called there: https://github.com/idflood/next-boilerplate.js/blob/master/src/scripts/_build.coffee#L72
Main requirejs config file: https://github.com/idflood/next-boilerplate.js/blob/master/src/scripts/require-config.js
The file to optimize: https://github.com/idflood/next-boilerplate.js/blob/master/src/scripts/boot.js

In this minimal setup the app and tests runs just fine using the non optimized files. The problem only occur when running node server.js build. The issue seems to appear as soon as there is a "cs!" require somewhere in the optimization target.

edit: updated links

@jrburke
Copy link
Member

jrburke commented Apr 29, 2012

Thanks for the test case! I did this following modification to parse.findAnonDefineFactory(), from this:

    if (isArray(node)) {
        if (node[0] === 'call') {

to this:

    if (isArray(node)) {
        if (node[0] === 'call' && node.length > 2) {

and the build completes for me. However if you want to confirm that fixes the issue for you, that the code runs correctly after a build, then I'll push a fix. Although the fix may end up going in the dev2.0 branch as that is the current development focus.

@idflood
Copy link
Author

idflood commented Apr 30, 2012

Thanks, it looks like it is compiling with this modification but the output gives a javascript error.

I've my next-boilerplate.js directory in a httpdocs apache directory and when accessing the index.html from http://localhost/next-boilerplate.js/output_static/index.html i get the following error in chrome. Firefox doesn't throw the error but the app doesn't run.

Uncaught SyntaxError: Unexpected token return

In fact it is the same error as posted before, it appears here:

define("Underscore", function(){});
define('use!Underscore', [],return typeof _ !== "undefined" ? _ : void 0);

Maybe this remaining issue is caused by the use! plugin, what do you think?

@jrburke
Copy link
Member

jrburke commented Apr 30, 2012

Right, that looks like a use.js error, when it tries writing out the define() call with its write() method.

I'll put a fix in for the build parse step, putting this in the 2.0 milestone.

@idflood
Copy link
Author

idflood commented Apr 30, 2012

I've played with this a little more and may have found a solution on the use.js side:
tbranyen/use-amd#17

The change you proposed above is still required to make the optimization works so maybe this should get committed.

Thank you : )

jrburke added a commit that referenced this issue Apr 30, 2012
@jrburke
Copy link
Member

jrburke commented Apr 30, 2012

Fix committed to dev2.0 branch as that is the active dev branch.

@idflood
Copy link
Author

idflood commented May 2, 2012

Any chance of backporting this one line fix?

Or maybe, create a requirejs-dev package on npm so that it become possible to target it from a package.json file (don't know if this is a good idea).

@jrburke
Copy link
Member

jrburke commented May 3, 2012

I'm hoping to just do the 2.0 release in a short while, instead of managing two trees. However, I labeled this with a "1.0 maintenance?" label for consideration in any future 1.0.x release if the 2.0 one takes too long.

@idflood
Copy link
Author

idflood commented May 3, 2012

Ah, I didn't expected that the 2.0 branch will be shortly released. I have a lot of things to fix and build on my project so take your time, I bet the 2.0 will be released long before I finish some major features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants