thlorenz / browserify-shim

📩 Makes CommonJS incompatible files browserifyable.
MIT License
933 stars 87 forks source link

Just explain what happens please #178

Closed jeron-diovis closed 8 years ago

jeron-diovis commented 9 years ago

It's probably a stupid newbie's issue, but I definitely need clarifying.

I'm trying to build project with Rivets library.

Rivets depends on external lib Sightglass like this:

if (typeof (typeof module !== "undefined" && module !== null ? module.exports : void 0) === "object") {
      module.exports = Rivets.factory(require("sightglass"));
    } else if (typeof define === "function" && define.amd) {
      define(["sightglass"], function (sightglass) {
        return this.rivets = Rivets.factory(sightglass);
      });
    } else {
      this.rivets = Rivets.factory(sightglass);
    }

And Sightglass exports itself like this:

    if (typeof module !== "undefined" && module.exports) {
      module.exports = sightglass;
    } else if (typeof define === "function" && define.amd) {
      define([], function () {
        return this.sightglass = sightglass;
      });
    } else {
      this.sightglass = sightglass;
    }

In package.json I have:

{
 "browser": {
   “rivets”: “path/to/rivets.js”,
   “sightglass”: “path/to/sightglass.js”
 }
}

Running browserify with browserify-shim with only this config works just fine. require call in rivets module is replaced with __browserify_shim_require__, and a sightglass dependency is added to bundle automatically. Everything is put into module, no globals.

Then I thought that I need to export rivets to globals:

{
"browserify-shim": {
    "rivets": {
      "exports": "rivets"
    }
}

But after this sightglass no more appears in bundle.

Ok, probably, if shim is defined for module, it manages this module completely, disabling auto-discovering dependencies. So I need to do it manually now:

{
"browserify-shim": {
    "rivets": {
      "exports": "rivets",
      "depends": [ "sightglass" ]
    }
}

After this sightglass appears in bundle again - but under it's full file path instead of just sightglass alias. And nothing works, because module named "sightglass" can't be found.

So, to make things finally work, I must either get rid of this shim and export to globals manually in my code with window.rivets = ..., or run browserify with -r option to force it to finally add a module named "sightglass".

And now my question is simple - is this all how things supposed to work? Am I doing something wrong, didn't I found some option in manual which will solve my problem - or everything above is just a standard usecase?

bendrucker commented 9 years ago

Can you please set up a project that reproduces this? No task runners please, just a minimal package.json and the two libs.

jeron-diovis commented 9 years ago

https://github.com/jeron-diovis/bshim_demo

While preparing this repo I've learned, that adding shim with exports section for module forces builder to don't pass a module variable inside, so such module works just as if it was loaded in browser. Probably, that was my mistake, and using shims for "exporting" isn't a correct usecase.

Still, I will describe my steps here - maybe, there are something more important things I didn't understand yet.

So, on each following step run "npm start" to build an app and then load index.html.

Steps:

  1. git checkout no_shim_all_works It's a "clear" default configuration without shims. Everything works, and no globals available. Actually, even require isn't replaced with __browserify_shim_require__.
  2. git checkout shim_exports_only Add shim for rivets to export it to globals. In build.js you see, that sightglass has just disappeared. Of course, nothing works.
  3. git checkout shim_with_deps Add explicit dependency for rivets in shim. Sightglass is again present in build.js, but still nothing works. Now I understand, that it's because rivets tries to load Sightglass from globals, not through require - while Sightglass is still exported to it's module.
  4. git checkout shims_for_everything Add shim for sightglass too. Now all works again, but I have both rivets and sightglass in globals.
  5. git checkout shim_deps_only This is a strange one. Leave only depends section in rivets shim. Sightglass is still present in build, but under it's filepath - while rivets tries to load it by alias. This can be fixed using -r sightglass option for browserify - it adds an alias and maps filepath to it. But, unexpectedly, rivets now again gets it's module variable, so everything works like on step 1, with only difference - require not is replaced with __browserify_shim_require__. Whether this all makes any sense, I don't understand.

That's all. So what I understood:

What I still don't understand:

bendrucker commented 8 years ago

Were you able to resolve this?

jeron-diovis commented 8 years ago

why modules from depends section are added to build under their filepaths instead of aliases, defined in config?

This is the last thing I can't understand myself. Such behaviour looks quite strange for me. Besides this, I learned where I was wrong.

bendrucker commented 8 years ago

You can configure using aliases or paths:

https://github.com/thlorenz/browserify-shim#b-config-inside-packagejson-with-aliases