1

I'm trying to display a D3 geo projection in a React component.

When viewing any page, this error happens inside the D3 Geo projection module:

Object doesn't support property or method 'readFileSync'

It is thrown at this line in the module's index.js:

module.exports = new Function("d3", 
  fs.readFileSync(path.join(__dirname, "d3.geo.projection.js"), "utf-8"));

Here are the modules added to the package.json as dependencies:

"d3": "^3.5.16",
"d3-geo-projection": "^0.2.16",
"topojson": "^1.6.25"

The following is the code for my GeoMap React component using D3 geo projection plugin:

var React = require('react');
var ReactDOM = require('react-dom');
var d3 = require("d3");

require("d3-geo-projection")(d3);

var d3GeoMap = {};

d3GeoMap.create = function(el, props, state) {
    var svg = d3.select(el).append("svg")
        .attr("class", "geoChart")
        .attr("width", props.width)
        .attr("height", props.height);

    this.update(el, state);
};

d3GeoMap.update = function(el, state) {
    d3.select(el).select("svg").append("rect")
        .data(state.data)
        .enter()
        .attr("class", "map")
        .attr("d", d3.geo.path().projection(d3.geo.mercator()));
};

var GeoMap = React.createClass({
    propTypes: {
        data: React.PropTypes.object
    },

    componentDidMount: function() {
        var el = this.refs.geoRoot;
        d3GeoMap.create(el,
            {
                width: 900,
                height: 900
            },
            {
                data: this.props.data
            });
    },

    render: function() {
        return (<div ref="geoRoot"></div>);
    }
});

module.exports = GeoMap;

NOTE: This error happens when hitting any page, even ones that do not use my GeoMap component.

Does anyone have insight on why the D3 Geo Projection plugin cannot find the 'fs' module?

WillardSolutions
  • 2,316
  • 4
  • 28
  • 38

1 Answers1

0

require("d3-geo-projection") when bundled assumes that fs.readFileSync is replaced with the actual code which for example in browserify is done with the brfs transform

However the index.js file is just doing the following

module.exports = function (d3) {
  // all the code of ./d3.geo.projection.js is included here
}

Therefore if you're not using a bundler with this transform use this instead

var d3 = require("d3");
// assumes that d3 is already defined here
require("d3-geo-projection/d3.geo.projection")
Mauricio Poppe
  • 4,817
  • 1
  • 22
  • 30
  • Thanks!! This did the trick. To clarify how this worked for me though, I placed the suggested code block into my react component, AND REMOVED `module.exports = new Function("d3", fs.readFileSync(path.join(__dirname, "d3.geo.projection.js"), "utf-8"));` from the D3 Geo Projection's `index.js` file. – Vinchenzo89 May 05 '16 at 15:22