Question

I'm using yepnope to load scripts conditionally, based on some tests, and I'm also using browserify, via grunt-browserify to build my scripts. Now I want one script to replace the other, but still be called via the same require:

// if svg support, then d3.js, otherwise r2d3.js
var d3 = require('d3');

So d3 is used as a require in my code, and also as a dependency for another lib.

The issue is that it can't be done with different require statements, because those are done during the build and the test can't happen because it depends on the users browser.

So I need a way to specify that the dependency uses d3 from window.d3, so I can set the window object with either of the libs. This is my grunt-browserify config..

options: {
  external: ['d3'],
  shim: {
    'd3-chart': {
       path: 'assets/bower_components/d3.chart/d3.chart.js',
       exports: null,
       depends: {
         d3: 'd3'
       }
    }
  }
}

I get Cannot find module 'd3' when r2d3 is loaded, even though that exports a window.d3.

Was it helpful?

Solution

With regards to Browserify, if you are using Browserify 3.0 you are able to utilize the browserify-shim as a transform, and expose a global reference to d3 by sticking a reference to D3 in your package.json like so:

 "browserify-shim": {
   "d3": "global:d3"
 }

After installing the shim will need to add a transform for the browserify-shim if you have not already

options: {
  transform: ['browserify-shim']
}

I wasn't able to confirm that this worked correctly in my build, as I discovered an alternate solution to my problem (I'm using xCharts). (Furthermore, I just switched to gulp.)

OTHER TIPS

There's a couple ways to handle this with browserify.

1.) You could use load in your D3 libraries conditionally outside of browserify and create a file that:

'use strict';
module.exports = window.D3

then when you are using D3 chart in your code require that file.

2.)The other way could be to use promethify, where you could conditionally require this. https://github.com/johnkpaul/promethify

3.) You can manually shim it by exporting a function that takes d3 as the param:

https://gist.github.com/michaelBenin/9557281
var d3 = window.d3;
require('../d3-plugin/d3.chart.js')(d3);

4.) You could have 2 browserify builds, one for legacy, one for modern.

I'd go with option 3 and pass in window.d3 as the argument.

Update: Also checkout exposify instead of using window.D3 https://github.com/thlorenz/exposify

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top