Immutable bindings of es6 modules


#1

Hey,

i’m trying to get d3 v4 to work with Meteor.
In this version, d3 uses an immutable binding to the event object. But with Meteor (1.3.3.1) i cannot access the updated export, instead the imports still points to the original null.

I created a small reproduction here:

Any ideas?


#2

Yeah, seems to be 1.3.3.1 specific:

transpiled in 1.3.2.4:

var _d = require('d3');                                           
                                                                   
require('./main.html');                                    
                                                                     
Template.d3.onRendered(function () {                                
  function rendered() {                                             
                                                                     
    // get main d3 selector                                          
    var canvas = (0, _d.select)('svg.canvas');            
    // init the pan & zoom behaviour                                 
    canvas.call((0, _d.zoom)().on('zoom', function () {              
      console.log(_d.event);                                         
    }));                                                             
  }                                                                  
                                                                     
  return rendered;                                                   
}());  

transpiled in 1.3.3.1:

var zoom, select; 

module.import('d3', {
  "zoom" : function (v) {
    zoom = v;
  },
  "select" : function (v) {
     select = v;
  }});

var currentEvent; 

module.import('d3', {
  "event" : function (v) {
    currentEvent = v;
}});

module.import('./main.html');
                                                                     
Template.d3.onRendered(function () {                                 
  function rendered() {                                              
                                                                   
    // get main d3 selector                                         
    var canvas = select('svg.canvas');                               
    // init the pan & zoom behaviour                                 
    canvas.call(zoom().on('zoom', function () {                      
      console.log(currentEvent);                                    
    }));                                                             
  }                                                                 
                                                                    
  return rendered;                                                  
}());   

@benjamn may know more


#3

The functions passed to module.import are meant to be called whenever the value of a named export is updated by the exporting module. Can you point me to where the event export is reassigned in d3 code?


#4

Yes, it happens right here.


#5

This will be fixed as part of fixing https://github.com/benjamn/reify/issues/29.

In the meantime, you can work around the problem by using the require function directly:

// Get the raw module.exports object from d3.
const d3 = require("d3");

Template.d3.onRendered(function () {
  return function rendered() {
    select('svg.canvas').call(zoom().on('zoom', function () {
      // The d3.event property will stay up-to-date over time.
      console.log(d3.event);
    }));
  };
}());

#6

Yeah, that’s what i’m doing right now.
Thanks for taking the time!