d3 / d3-request

A convenient alternative to XMLHttpRequest.
BSD 3-Clause "New" or "Revised" License
110 stars 54 forks source link

Last publish breaks webpack build. #24

Closed kevinbror closed 7 years ago

kevinbror commented 7 years ago

It seems that the last publish of this commit https://github.com/d3/d3-request/commit/d635b894fee995930f7419189255da8e66062710 broke d3 for the browser. I have an angular 1.5 app that uses d3 and since d3 was updated to require 1.0.6 of this package, I get this error when trying to load the app after building:


XMLHttpRequest.js:15 Uncaught Error: Cannot find module "child_process"
    at webpackMissingModule (XMLHttpRequest.js:15)
    at Object.eval (XMLHttpRequest.js:15)
    at eval (XMLHttpRequest.js:622)
    at Object.<anonymous> (bundle.js?version=13.1.3:10487)
    at __webpack_require__ (bundle.js?version=13.1.3:20)
    at eval (d3-request.node.js:3)
    at Object.<anonymous> (bundle.js?version=13.1.3:10481)
    at __webpack_require__ (bundle.js?version=13.1.3:20)
    at eval (d3.node.js:25)
    at Object.<anonymous> (bundle.js?version=13.1.3:10343)
    at __webpack_require__ (bundle.js?version=13.1.3:20)
    at eval (dashboard.timelines.controller.js:26)
    at Object.<anonymous> (bundle.js?version=13.1.3:10319)
    at __webpack_require__ (bundle.js?version=13.1.3:20)
    at eval (dashboard.timelines.directive.js:14)
    at Object.<anonymous> (bundle.js?version=13.1.3:10295)

I have not been able to figure out which dependency update in the commit is causing this yet, but I figured I'd post this first. Reverting to d3 4.10.0 is a temporary workaround, since it requires 1.0.5 of d3-request.

mbostock commented 7 years ago

This error occurs because webpack is trying to consume code intended for Node rather than the browser.

In earlier versions of d3 (and d3-request; see d3/d3#3138) the browser field of the package.json pointed to a UMD bundle intended for browsers, whereas the main field pointed to a CommonJS bundle intended for Node. In cases where the code did not depend on any browser-specific functionality, as is the case with most D3 modules, there was no browser field and the main field pointed to a UMD bundle suitable for both Node and browsers.

The browser field was never intended to support bundlers; it was to provide short URLs for unpkg. The only supported entry point for bundlers is module, which points to the ES modules (and assumes a browser environment).

Alas, unpkg’s use of the browser field conflicted with Browserify and other bundlers that use this field to indicate a CommonJS bundle that may need shims for Node APIs not available in browsers, so unpkg is switching to a new unpkg-specific field, unpkg (see unpkg/unpkg-website#63).

If you want to rebundle D3 using webpack, or another bundler such as Rollup, you must configure it to consume the module entry point, which should be the default behavior of resolve.mainFields now that the browser field is gone.

kevinbror commented 7 years ago

Got it thanks!

pmuellr commented 7 years ago

Seems like this is still an issue w/browserify, which I guess must be dependent on the browser entry in package.json.

We just upgraded to 1.0.6, and found that we were getting the node version of d3-request instead of the browser one, then chased the issue down to here.

I just hacked the d3-request/package.json in my node_modules to add back

"browser": "build/d3-request.js",

then rebuilt w/browserify, and it looks like it picks up the browser version instead of the node one.

Perhaps there's something wrong in our build, or some option I can use w/browserify to work around this, but ... not obvious to me ATM.

My guess is that this will hit more people using d3-request via browserify ...

mbostock commented 7 years ago

I think if you’re using Browserify, you’ll also need Babelify so that you can consume the ES modules rather than trying to re-bundle the generated UMD.

joeldouglass commented 7 years ago

Anyone figure out how to configure Browserify to use the module entry point? We're using Browserify/Babelify and have recently run into this same issue.

nwshane commented 7 years ago

In case anyone is having this problem with webpack version 1, you can add 'module' to the front of resolve.packageMains as a workaround. See this issue: https://github.com/gatsbyjs/gatsby/issues/2107#issuecomment-330076798

Sheparzo commented 6 years ago

It seems to me, based on comments here and create-react-app issue 3166 that the latest D3 may not be compatible with a non-ejected create-react-app. Can anyone confirm this?

mbostock commented 6 years ago

I don’t support webpack, but I am surprised it doesn’t work by default; it’s my understanding that webpack should prefer the module entry point (over the CJS bundle targeted at Node).

ffflabs commented 6 years ago

If you want to rebundle D3 using webpack, or another bundler such as Rollup, you must configure it to consume the module entry point, which should be the default behavior of resolve.mainFields now that the browser field is gone.

You'll need to explicitly configure webpack resolve.mainFields as ['module', 'jsnext:main', 'main']. That what I did in a project that needed webpack. Wouldn't have used webpack otherwise.