Search code examples
javascriptcommonjs

How do I make this window when .call(this) from a commonJS module


I am using Webpack to package my dependency I am trying to load the method-combintator. The dependency looks like this...

// Generated by CoffeeScript 1.3.1
(function() {
  var __slice = [].slice;

  this.before = function(decoration) {
    return function(base) {
      return function() {
        decoration.apply(this, arguments);
        return base.apply(this, arguments);
      };
    };
  };
  ...
}).call(this);

Then I include in my TS file like...

require("method-combinators/lib/method-combinators.js");

When I breakpoint on the inside function I notice this != window. If I try to add...

require.bind(window);

I get

Critical dependencies: 20:0-7 require function is used in a way in which dependencies cannot be statically extracted

What is the right way to do this?

Update

> this
Object {}
> window
Window {...}

If I do

window['comb'] = require("method-combinators/lib/method-combinators.js");

It seems to work, but because this is legacy code it is really hard to search for all instances of after and begin.

Update 2

This kinda works...

var comb = require("method-combinators/lib/method-combinators.js");
window['after'] = comb.after;
window['before'] = comb.before;

Which is similar to the answer provided by @tcooc but the problem is I have to list out each function. For underscore I have something like this...

var s = require("underscore.string");
window['_'].mixin(s.exports());

But the problem here is comb does not have exports

Update 3

This was my final

var comb = require("method-combinators/lib/method-combinators.js");
window['_'].extend(window, comb);

Solution

  • commonjs modules, by design, do not access or modify to the global scope (or at least they shouldn't). The this variable in your code is referencing the exported value from that module, not window. The code is actually wrapped in something like (simplified for your use case):

    // you want to load "method-combinator.js"
    require('method-combinator.js');
    // load "method-combinator.js" as "dependency()"
    var exports = {};
    dependency.call(exports);
    

    Now whenever you try to load "method-combinator.js", exports is returned.

    The correct way to use the dependency is:

    var combinators = require('method-combinator.js');
    

    If you wish to add all values of combinators to the window, assuming you have underscore:

    _.extend(window, combinators);
    // or if _ is somehow not resolving properly (for some reason?)
    window._.extend(window, combinators);