RaveJS / rave

Zero-configuration application bootstrap and development
278 stars 8 forks source link

Auto-sniff module type when moduleType is missing from bower packages #45

Closed unscriptable closed 10 years ago

unscriptable commented 10 years ago

Even though a rave-overrides package (#43) could solve the missing moduleType problem, the number of bower packages that are missing the moduleType property is just so huge. I'd bet that 99% of AMD packages are missing it. Perhaps a programmatic solution would be better.

Since we're fetching the source code as text, we could scan the file for the well-known AMD define() signature. It seems that scanning the code for CommonJS patterns could be a bit hairier. Devs do all sorts of crazy (creative?) things when trying to support both globals and node in the same codebase. However, I think we'll cover 99.9% of cases if we just concentrate on globals and AMD. The 0.1% of packages on bower that are node-formatted can be fixed by rave-overrides.

Scanning is expensive, of course, so we should try to include the most popular packages in rave-overrides. (Scanning won't happen at run-time when the dev is using built mode, fwiw.)

Here's the code where we can decide whether to scan: https://github.com/RaveJS/rave/blob/master/lib/hooksFromMetadata.js#L52-L64

Possible algorithm:

function instantiate (load) {
    var pkg, moduleType;

    pkg = metadata.findPackage(load.metadata.rave.packages, load.name);
    moduleType = pkg.moduleType;

    // prefer amd-formatted modules since they use less string manip
    if (hasModuleType(moduleType, 'amd')) {
        return instantiateAmd(load);
    }
    else if (hasModuleType(moduleType, 'node')) {
        return instantiateNode(load);
    }
    else if (hasModuleType(moduleType, 'globals')) {
        return instantiateScript(load);
    }
    else if (moduleType = guessModuleType(load)) {
        pkg.moduleType = moduleType; // fix package!
        return instantiate(pkg); // try again :)
    }
    else {
        throw new Error('Unable to determine moduleType for ' + load.name);
    }
}
unscriptable commented 10 years ago

I've started working on this and will PR soon. First, I extracted the code-finding algorithm out of rave/lib/findRequires so I could reuse it (and could also reuse it for parsing ES6 modules).

unscriptable commented 10 years ago

Fixed by #46.