cujojs / cram

Simple, yet powerful, AMD and CommonJS module bundler.
http://cujojs.com
58 stars 9 forks source link

Using wire with cram #5

Closed joefiorini closed 11 years ago

joefiorini commented 11 years ago

Here's where I am right now with this issue:

I change cram/lib/compile.js:133 to:

plugin.compile(fileCtx.absId, parentCtx.require, pio, parentCtx.config());

which got me one step further, but now I'm getting the error:

cram failed:  Module not resolved: main
Error: Module not resolved: main
    at localRequire (/Users/joe/Projects/d-i/Intention-Web/vendor/cram/support/curl/dist/curl-for-ssjs/curl.js:333:13)
    at processSpec (/Users/joe/Projects/d-i/Intention-Web/vendor/wire/builder/cram.js:63:12)
    at Array.forEach (native)

I'm guessing that it's not handing an absolute path to require, but making it absolute (prepending config.baseUrl) gives the same error with the full path.

Does the change I made to compile.js make sense? Is this new error valid?

Thanks!

unscriptable commented 11 years ago

I've reproduced this with a very simple config. Looking into it further.

unscriptable commented 11 years ago

heh. This might be caused by wire being both an AMD plugin and a main module. Rare, but useful case.

unscriptable commented 11 years ago

Actually, it was an API change that hadn't been applied to wire, yet. I also found some other issues in both wire and cram. Pull the latest from cram/dev and wire/cram-build. :)

joefiorini commented 11 years ago

Cool, thanks @unscriptable! Got it working with just define({}); in my main.js. Once I add back define(["plugins-init"], {}) I get an error:

cram failed:  window is not defined
ReferenceError: window is not defined
    at Object.<anonymous> (/Users/joe/Projects/d-i/Intention-Web/vendor/assets/javascripts/jquery/index.js:9301:5)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

Gist is at https://gist.github.com/0aebca8c63c7774e702a.

joefiorini commented 11 years ago

I got past that by installing jsdom via npm. Unfortunately, it's not an AMD module, so I'm not sure how to properly load it. I set define.amd.jQuery to true, and then required 'jsdom' at the top of of jquery/index.js, like so:


window = require("jsdom").jsdom().createWindow();
/*!
 * jQuery JavaScript Library v1.8.1
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/

...

and here's the error I'm getting:

cram failed:  define() missing or duplicated: /Users/joe/Projects/d-i/Intention-Web/vendor/cram/../../app/assets/javascripts/../../../vendor/assets/javascripts/jquery/index.js
Error: define() missing or duplicated: /Users/joe/Projects/d-i/Intention-Web/vendor/cram/../../app/assets/javascripts/../../../vendor/assets/javascripts/jquery/index.js
    at core.fetchResDef (/Users/joe/Projects/d-i/Intention-Web/vendor/cram/support/curl/dist/curl-for-ssjs/curl.js:931:19)
    at loadScriptViaRequire (/Users/joe/Projects/d-i/Intention-Web/vendor/cram/support/curl/dist/curl-for-ssjs/curl.js:1435:4)
    at Object.priv.core.loadScript (/Users/joe/Projects/d-i/Intention-Web/vendor/cram/support/curl/dist/curl-for-ssjs/curl.js:1416:11)
    at Object.core.fetchResDef (/Users/joe/Projects/d-i/Intention-Web/vendor/cram/support/curl/dist/curl-for-ssjs/curl.js:919:9)
    at Object.core.fetchDep (/Users/joe/Projects/d-i/Intention-Web/vendor/cram/support/curl/dist/curl-for-ssjs/curl.js:993:10)

Do you think this is because jsdom isn't an AMD module?

unscriptable commented 11 years ago

Ah, ok. I see the problem with define(["plugins-init"], {}). The wire cram plugin currently assumes plain specs without AMD dependencies. Since it actually loads each spec as an AMD module to inspect it, curl will automatically fetch any dependencies. If those dependencies can't run in the environment (node in your case), the load fails. jQuery doesn't like to be loaded in node without significant assistance. :)

I'm kinda guessing here, but I think what you want is this instead:

define({
    pluginsInit: { module: 'plugins-init' }
});

We're cross-posting! :)

joefiorini commented 11 years ago

Did that, but doesn't that in essence hide 'plugins-init' from the file built by cram? I'm trying to package all of my files together for production so that it doesn't have to do any extra downloading. I've used jQuery in node before using jsdom to create a window. Does this make sense?

unscriptable commented 11 years ago

Nope. The wire cram plugin finds modules in the specs, hoists them to the define, and lets' cram do the rest. :)

Don't use jsdom. It's not needed. :)