dc.js icon indicating copy to clipboard operation
dc.js copied to clipboard

3.1.9 crossfilter is not a function

Open Spacarar opened this issue 5 years ago • 5 comments

Recently I tried to run npm update on a vue website that uses dc.js and it changed the crossfilter import that is exposed by dc.js.

Here is a screenshot of the updated package list in case this was not a direct result of dc.js being updated

dc version from 3.1.2 -> 3.1.9 d3 version from 5.10.0 -> 5.15.0 crossfilter2 version from 1.4.7 -> 1.5.2 (problem?)

Screenshot of package.json diff

Screen Shot 2020-02-07 at 3 28 02 PM

after some quick inspection it appears that the dc.crossfilter wasn't imported correctly and can be fixed by either:

updating the reference on on dc.js:13925 from dc.crossfilter = crossfilter to dc.crossfilter = crossfilter.default

or

just using dc.crossfilter.default(dataArray) without editing any dc.js source directly

I definitely feel that the workaround listed above isn't the correct way to solve the issue I've come across, but judging by the version numbers, it looks like dc.js should be compatible with the version of d3 and crossfilter being used but may not be imported correctly into dc 3.1.9.

Spacarar avatar Feb 07 '20 22:02 Spacarar

Hi @Spacarar, sorry for the slow response.

If you're still around, are you able to force [email protected]? We changed the crossfilter2 build system from browserify to rollup and this may have confused your bundler. It could also be the upgrades to your bundler.

Unfortunately there is a fundamental problem here, which is that crossfilter is both a function and a module. This was legal JavaScript (since a function is an object) but it may not be legal ES6; some variants of Typescript allow this and some don't.

When I check the dc.js 3.1.9 examples in a browser, typeof(dc.crossfilter) === "function". So I think this a bundler issue and not a JS issue. (There could be a better way to define the rollup module, I'm not sure.)

See also crossfilter/crossfilter#147: Angular doesn't like the Typescript syntax and once again you end up with a crossfilter module containing a crossfilter function/class.

Reductio also had a similar problem which was solved by switching from gulp to rollup.

As @kum-deepak points out in #1651, dc.crossfilter is itself an anachronism. dc.js does not directly use crossfilter as of 3.1.2, even though it is still listed as a dependency in the AMD scaffolding.

If different build systems treat crossfilter differently, I think the best solution is just to remove this export. If you're indirectly depending on it, you can just directly depend on it. I think I'll release a 3.2 version with this change.

Sorry for the long response. As far as I can tell, this is a case of a once-clever design being trampled under the march of progress.

gordonwoodhull avatar Feb 11 '20 13:02 gordonwoodhull

so I did also try using [email protected] with [email protected] and that also didn't seem to work properly so I just rolled back to [email protected] and [email protected] and things are working fine again. It seems like something in dc between version 3.1.2 and 3.1.9 changed how crossfilter was included, but looking at the code the section that appears to be handling the import appears unchanged. Thanks for the explanation, I'll just close this issue as moving forward I expect to be using the latest versions rather than the versions described in this issue.

Spacarar avatar Feb 11 '20 17:02 Spacarar

Thanks @Spacarar!

But, the latest versions don’t work, right? Have you by any chance tried dc.js 4.0?

I am also mystified why 3.1.2 would work and 3.1.9 no. I don’t see any relevant changes at all.

I’ll reopen until crossfilter is fully removed from the interface (but thanks for being conscientious and closing it!)

gordonwoodhull avatar Feb 11 '20 17:02 gordonwoodhull

I didn't try using dc.js 4.0 as this is in a pretty large project currently and was worried about reworking the code at the moment though may not be that much work looking at your upgrade guide.

currently everything is working using [email protected] [email protected] and [email protected]

It seems the d3 version doesn't affect my current implementation as it was updated from 5.10.0 -> 5.15.0 and worked with any of the dc/crossfilter2 versions I have tried.

after retrying [email protected] and [email protected] it appears I may have been mistaken or this was a caching issue from when I had installed [email protected] because this combination appears to be working for me.

I can however confirm that [email protected] with [email protected] does not work for me running a vue project on a Mac with the error described in the original post that crossfilter is not a function.

I'm unfamiliar with how npm update actually works but could [email protected] be limited to [email protected] rather than [email protected]?

Spacarar avatar Feb 11 '20 18:02 Spacarar

Thanks very much for your thorough testing.

It sounds like it is “simply” a bug in [email protected] where the interface is not backward compatible when used in the vue bundler. I suspect it’s the same issue in the above crossfilter/Angular issue. From your dependency list it doesn't look like you are using Typescript, but maybe Babel transpilation has something to do with it.

I don't see any reason to believe this has to do with dc.js in particular, so I'm going to open a crossfilter issue. And yeah, I supposed dc.js could peg to the old version of crossfilter but I'd rather not do that, especially since this doesn't seem to be a JavaScript issue but a bundler issue.

I'll leave this issue open as a reminder to remove crossfilter from the public interface of dc.js in 3.2, since it just complicates things.

gordonwoodhull avatar Feb 11 '20 20:02 gordonwoodhull