Can’t run sinon in node when webpacked

webpack is converting this:

    var isNode = typeof module !== "undefined" && module.exports;
    var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;

    if (isAMD) {
        define(function(){
            return sinon;
        });
    } else if (isNode) {
        ...
    }

into this:

    var isNode = typeof module !== "undefined" && module.exports;
    var isAMD = 'function' === 'function' && typeof (require(11)) === 'object' && (require(11));

    if (isAMD) {
        {var __WEBPACK_AMD_DEFINE_RESULT__ = (function(){
            return sinon;
        }(require, exports, module)); if(__WEBPACK_AMD_DEFINE_RESULT__ !== undefined) module.exports = __WEBPACK_AMD_DEFINE_RESULT__;};
    } else if (isNode) {
        ...
    }

and ’11’ refers to some webpack code which is definitely defined.

Is there a way to make webpack not load a module in such a way that define.amd gets converted to something that is defined?

Author: Fantashit

9 thoughts on “Can’t run sinon in node when webpacked

  1. And in case anyone stumbles on this in the future, you want to work around such issues in your webpack configuration, both because the library itself my require itself (such as SinonJS does) or some other library might require it, and you want all of them to require the same AMD-undefined version of sinon. So in my configuration I have this:

        webpack: {
          options: {
            module: {
              loaders: [
                { test: /sinon.js$/,                loader: "imports?define=>false" }
              ]
            },

    K, I’ll stop talking to myself now 🙂

  2. @jbaiter I ran into the same issue when using require("imports?define=>false!sinon");

    SinonJS requires itself with several circular dependencies. Requiring sinon.js requires sinon/spy.js which in turn requires sinon.js. But when spy.js requires sinon.js, it does not use the imports?define=>false shim, so you end up with an error.

    To get everything to work properly, you must do two things:

    1. npm install imports-loader --save-dev
    2. Add the sinon shim to webpack config
    // webpack.config.js
    modules: {
      loaders: [
        {
          test: /sinon\.js$/,
          loader: "imports?define=>false"
        }
      ]
    },

    Then just use require('sinon'); as normal and everything should work.

    Thanks to @altano for the solution above. I just missed his comment the first time and also didn’t have imports-loader installed.

  3. I encountered the same issue: sinon doesn’t export itself correctly when webpacked.


    Solution without karma

    I first ended up with this solution.

    Add the following imports loader configuration in webpack configuration loaders array:

    {
        test: /sinon\.js$/,
        loader: "imports?define=>false,require=>false"
    }

    Notice the addition of require=>false to @simple10 ‘s solution.
    Then sinon can be required using the built package:

    const sinon = require('sinon/pkg/sinon');

    You are free to add an alias from “sinon” to “sinon/pkg/sinon” in your test webpack configuration.


    Solution with karma

    My case was browser-side, so packages like karma-sinon-chai which can make the browser load the built file of sinon are a solution. Sinon is not part of the test webpacked bundle file any more.

  4. We ran into this issue when using Enzyme to test react components, and what worked for us (to document for posterity) was a combination of above approaches:

    webpack: {
      resolve: {
        alias: {
          'sinon': 'sinon/pkg/sinon'
        }
      },
      module: {
        // don't run the sinon module through babel-loader
        noParse: [
          /sinon/
        ],
        // ...
  5. I have to read the entire thread to figure out what I actually need to do. To summarize this for everyone, all the webpack.config changes required to get sinon to work (don’t forget to install imports-loader):

    resolve: {
            alias: { sinon: 'sinon/pkg/sinon' }
        },
        loaders: [{ test: /sinon.*\.js$/,   loader: "imports?define=>false,require=>false"  }],
        noParse: [/sinon/]
    

Comments are closed.