duojs / duo

A next-generation package manager for the front-end
3.42k stars 118 forks source link

ReferenceError when using Duo as a module #433

Closed darsain closed 9 years ago

darsain commented 9 years ago

Seeing as CLI works fine, it's weird that using Duo as a module:

var Duo = require('duo');

new Duo(__dirname)
    .entry('var index = require(\'component/indexof\'); console.log(index([0,1], 1));', 'js')
    .run(save);

function save(err, src) {
    if (err) return console.error(err);
    console.log(
        'Generated %d kb big file starting with:\n%s',
        (src.length / 1024).toFixed(2),
        String(src).substr(0, 77) + '...'
    );
}

throws this error:

ReferenceError: component_compat is not defined
    at Step.component_compat (D:\test\node_modules\duo\node_modules\duo-css-compat\index.js:220:8)
    at Step.<anonymous> (D:\test\node_modules\duo\node_modules\co\index.js:40:16)
    at call (D:\test\node_modules\duo\node_modules\step.js\index.js:87:14)
    at null._onTimeout (D:\test\node_modules\duo\node_modules\step.js\index.js:68:5)
    at Timer.listOnTimeout (timers.js:110:15)

Running:

darsain commented 9 years ago

I've made the report above more concise, removed anything gulp related (as it was not related), and added a minimal code snippet required to replicate this issue.

This really hinders my development workflow as I can't use Duo from gulp, so I run everything manually. Really irritating, so could someone please look at it? I've tried but got spaghetti poisoning :)

dominicbarnes commented 9 years ago

Ok, looks like we have an issue with the "compiled" script on npm. (looks like it may not have been compiled from ES6 generators into ES5)

Adding the --harmony flag fixes this issue for me, does that work for you @darsain ? (I'll work on a proper fix asap)

darsain commented 9 years ago

Yes, --harmony fixes the issue. Thx, gonna switch it on until this gets fixed :)

dominicbarnes commented 9 years ago

Thanks! Sorry about the delay, but I'll see about merging a fix for this tonight.

darsain commented 9 years ago

Awesome! :)

dominicbarnes commented 9 years ago

Blah, the problem is deeper than I thought. Looks like some interaction between code that was compiled by regenerator and ware/wrap-fn is not cooperating. I'm trying to narrow down the exact code-path that causes the problem, but I haven't finished yet.

Thus, I won't be able to fix this tonight as I previously thought. I'll keep working on it though!

matthewmueller commented 9 years ago

Chiming in here because I know I've made this mistake in the past... using fn.name to call functions does NOT work when the code is minified / compiled and the function names are changed. Not sure if it's relevant though.

dominicbarnes commented 9 years ago

I was able to find a workaround for this problem. By exporting a hoisted function instead of a function expression, it looks like the compiled code doesn't lose access to the fn by name.

// works
module.exports = compatibility;
function *compatibility() {}

// breaks
module.exports = function *compatibility() {};

It's lame to use a workaround like this, but it's another necessary evil I guess.

dominicbarnes commented 9 years ago

As it turns out, that doesn't work in our case. Other libraries (in particular, co-parallel) export/return expressions.

As far as I'm concerned, this is a bug in regenerator itself, so I'll submit an issue upstream.

ArmorDarks commented 9 years ago

Got similar error during using of grunt-duojs task. CLI version works normally

What is really curious that if I call task directly with grunt duojs — all works fine. However, if I call it in stack, with grunt default for example — I'll receive same error.

What is more interesting, that error happens only if task called after certain other tasks.

For example, this will work:

  grunt.registerTask 'default', [
    'clean'
    'copy:build'
    'duojs' # grunt-duojs
    'nunjucks' # grunt-nunjucks-2-html
    'sprite'
    'webfont'
    'sass'
    'autoprefixer'
    'responsive_images:thumbnails'
    'browserSync'
    'watch'
  ]

but this will throw same error:

  grunt.registerTask 'default', [
    'clean'
    'copy:build'
    'nunjucks' # grunt-nunjucks-2-html
    'duojs' # grunt-duojs. Loaded after nunjucks task
    'sprite'
    'webfont'
    'sass'
    'autoprefixer'
    'responsive_images:thumbnails'
    'browserSync'
    'watch'
  ]

Why other tasks can cause that error — completely unclear for me, since they all quite isolated.

dominicbarnes commented 9 years ago

@ArmorDarks your problem should be submitted upstream to the grunt-duojs package.

dominicbarnes commented 9 years ago

I'm going to close this issue now. If you're getting these errors when requiring duo, chances are you've not included the appropriate --harmony-generators flag. For anyone who still encounters errors after this point, please create new issue with all relevant details so we can resolve it.