markmarkoh / datamaps

Customizable SVG map visualizations for the web in a single Javascript file using D3.js
http://datamaps.github.io
MIT License
3.78k stars 1.01k forks source link

Universal javascript compatibility #280

Open Guibod opened 8 years ago

Guibod commented 8 years ago

My project is partially rendered server-side. I stumble on importation issue while behind my express server.

  import Datamap from 'datamaps';

Triggers an error "ReferenceError: window is not defined"

  var d3 = window.d3, topojson = window.topojson;

How do I properly import datamaps ?

markmarkoh commented 8 years ago

@Guibod that's a great question - I've never tried running it on the server before.

Can you give this branch a shot and see if it gets around the error?

Guibod commented 8 years ago

Sure, I'll give it a shot. Yet I won't be able to test it right now, maybe on saturday.

I checked the changes, and that indeed all that's needed. There were 2 lines that triggered error on servers and you changed them. I don't know if the root trick will work though.

I'm using Webpack and Babel 6, so that's maybe a somewhat special setting that won't validate for the rest of the server side guys.

Thanks a lot for the library, that's really awesome to use it. :)

markmarkoh commented 8 years ago

I'm using Webpack+Babel6 for a project now as well, but not a project that needs DataMaps. Keep me posted on how the build comes together w/ DataMaps.

If the above branch fixes it I'll merge it soon.

epicallan commented 8 years ago

@markmarkoh I have given this branch a shot and I am not getting the reference errors. Thanks.

sedenardi commented 8 years ago

@markmarkoh That branch works great from the server. Any chance you can push the new version to NPM?

Guibod commented 8 years ago

I confirm, it is working.

darkalor commented 8 years ago

We're using react with some of the stuff rendered on server side, and we actually managed to run this fine with the current version just by deferring any rendering of maps by calling require("datamaps") only when components have mounted (i.e. things got sent to client side). Alternatively if you use webpack you can inject some variables and have a fake "window" object.

@markmarkoh I'm a bit confused by your solution. In the code you have

  if (typeof exports === 'object') {
    d3 = require('d3');
    topojson = require('topojson');
    module.exports = Datamap;
  }
  else if ( typeof define === "function" && define.amd ) {
    define( "datamaps", ["require", "d3", "topojson"], function(require) {
      d3 = require('d3');
      topojson = require('topojson');

      return Datamap;
    });
  }
  else {
    window.Datamap = window.Datamaps = Datamap;
  }

Meaning that you already have proper handling for server side imports.

So what exactly is the point of fetching your dependencies here (outisde the environment check) instead of in the above block?

  // Save off default references
  var d3 = root.d3, topojson = root.topojson;