2

I've recently incorporated PostCSS, Gulp and Webpack into my workflow, however the learning curve is pretty steep (Webpack in particular!) and I'm having issues getting it to compile d3. I've installed d3 with npm install d3 --save and have tried importing it as:

var d3 = require("d3");

which didn't work. I tried installing a loader, adding

     new webpack.ProvidePlugin({
        d3: "d3"
    }),

to my webpack.config file and importing as

var d3 = require("d3!");

which didn't work either. I've tried the stuff here and here (last answer re the loader) as well.

I get the following error from my browser:

Uncaught ReferenceError: d3 is not defined

And gulp gives me the following error in the command line:

..../node_modules/loader-runner/lib/loadLoader.js:35 throw new Error("Module '" + loader.path + "' is not a loader (must have normal or pitch function)");

My code repo is here.

Thanks in advance!

Community
  • 1
  • 1
Tom
  • 123
  • 7

2 Answers2

3

Just thought I would point out that the update of d3 from v3 to v4 was quite disruptive. I had a similar problem as the one you mentioned until I realized that the d3 code has changed in almost every circumstance.

I was able to import d3 (installed as a node module) normally with webpack by using

import * as d3 from "d3";

Afterwards, errors made it look as tho d3 was not being imported, however it was because I was using d3 v3 style code.

for example:

d3.layout.pie() 

is now simply:

d3.pie()

After refactoring, everything worked as expected. I'm not sure if this is the cause of your problems, but it's something to be mindful of.

MFave
  • 1,044
  • 2
  • 8
  • 19
2

The reason the loader didn't work was because in Webpack 2 the full name is necessary:

var d3 = require('d3-webpack-loader!');

However as this loader isn't Webpack 2 compatible (at this time), the normal d3 package can be used. However in a Node env (remember Gulp/Webpack are run in Node), the build/d3.node.js version is imported by default, this isn't what you want here, so the following webpack alias will solve the problem:

resolve: {
    alias: {
        d3: 'd3/build/d3.js'
    }
},

Add this to your webpack.config.js. With this, you can continue to use:

var d3 = require('d3');
mikeapr4
  • 2,830
  • 16
  • 24
  • That solved the problem, although I've upgraded my webpack also. Now I get a new error: Uncaught Error: Module build failed: TypeError: Cannot read property 'map' of undefined at getModuleDirectories (/Users/tssuser/work/d3/tut/node_modules/d3-webpack-loader/index.js:51:38) at Object.d3Loader (/Users/tssuser/work/d3/tut/node_modules/d3-webpack-loader/index.js:79:27) ..... Any ideas @mikeapr4? – Tom May 08 '17 at 12:38
  • That loader unfortunately hasn't been updated in 7 months, the code isn't actually compatible with Webpack 2 yet :( - update the question with your webpack config and I'll see if I spot something which would cause the npm d3 package not to work with `require('d3')` - also you could examine the object returned from this require call – mikeapr4 May 08 '17 at 13:04
  • require('d3') successfully compiles the JS but for some reason I get a reference error whenever I reference d3. And thankyou! – Tom May 08 '17 at 13:56
  • @Tom - did you get the alias to work, or are you still having problems? – mikeapr4 May 08 '17 at 14:27
  • No, still having problems – Tom May 08 '17 at 17:31
  • Ah, now I see, you want to setup d3 inside Webpack, but use it on the page. That won't work, add: `$(function() {d3.select("h1").append("span").text("Hello D3");});` to your `App.js`, you'll find it works fine. – mikeapr4 May 08 '17 at 18:02