Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closure Externs for D3? #224

Closed
shripadk opened this issue Jul 14, 2011 · 10 comments
Closed

Closure Externs for D3? #224

shripadk opened this issue Jul 14, 2011 · 10 comments

Comments

@shripadk
Copy link

Is it possible to have a externs file available for d3 so that for those of us who want to use d3 along with closure can easily use the library? d3 variables/functions are rewritten when compiled in ADVANCED mode.

@mbostock
Copy link
Member

Sure, but I'm not going to write it. :) I highly recommend UglifyJS over Closure. It's faster, the resulting JavaScript files are generally as small or smaller, and you avoid the bugginess of "advanced" optimizations.

@shripadk
Copy link
Author

I agree with you. But since I'm using Closure Library itself I have no choice but to go with the compiler rather than uglifyjs! I'll write one myself and create a pull request when done. :)

@jhickner
Copy link

jhickner commented Oct 1, 2011

@shripadk Did that externs file ever get made? I can't seem to find it in the repo. Itching to try out d3 with ClojureScript!

@shripadk
Copy link
Author

shripadk commented Oct 1, 2011

@jhickner Here you go: https://github.com/shripadk/d3-externs

Please note that it is incomplete. I have only added definitions that are used in my app.

@jhickner
Copy link

jhickner commented Oct 1, 2011

Thanks! The format looks pretty straightforward. I wonder if these could be autogenerated?

@mbostock
Copy link
Member

mbostock commented Oct 1, 2011

With very few exceptions, D3 does not store private state in publicly-accessible objects, so there's no benefit to the "advanced" renaming of attributes. D3 uses closures for private state, and nearly every JavaScript minifier can rename local vars without a hand-coded "externs" file.

The only exception that comes to mind is d3.layout.tree, which creates a temporary _tree object on the nodes to store some state as the algorithm runs; that state is later deleted. We could rewrite this to use private state, say an array of objects accessed by node.index. But you're likely to only save a handful of bytes.

If you are running Google Closure on your code combined with D3, such that it can rename everything including public methods, and stripping out code you don't use… then I'd see a benefit. But you don't need an externs file for that, either. :)

@jhickner
Copy link

jhickner commented Oct 1, 2011

Hi @mbostock, thanks for the rundown. I'm just using the standard minified js distribution of d3 and then trying to interop with it from clojurescript. The problem is that without an externs file for d3, in my clojurescript code (which is compiled in advanced mode) calls to, say, d3.select get munged into something like d3.a by the advanced compilation.

@mbostock
Copy link
Member

mbostock commented Oct 2, 2011

Ah, that makes sense. Sounds like you could automate the generation of this file, at least, say by writing a Node script. If you require("d3"), you could then iterate over all of the attributes defined on the d3 object and generate an externs file accordingly. It gets a bit harder if you want to include instance methods, though I suppose you could use the same technique given a default scale instance, empty selection, etc.

@pallosp
Copy link

pallosp commented Oct 20, 2016

I've created externs for d3 v4.2.7 and shared them at http://pastebin.com/A4an42b2

I've also been experimenting with compiling d3 together with its caller using advanced optimizations. I replaced the bootstrapping code with a simpler version that Closure Compiler understands, blacklisted 171 properties that would break after renaming, and suppressed a few warning classes.

The results are promising. Besides the simple optimizations the compiler can also remove roughly 60% of the unused code. The only blocker is that the function inlining pass breaks some functions that declare variables after their first use (#2978).

@sfinktah
Copy link

@pallosp you are an absolute legend. I needed externs for d3-hexbin so here those are, although not with the same level of detail, but working.

var d3_hexbin = {
    "version": {},
    "hexbin": function () {},
};
d3_hexbin.hexbin.prototype.hexagon = function(radius) {};
d3_hexbin.hexbin.prototype.centers = function() {};
d3_hexbin.hexbin.prototype.mesh = function() {};
d3_hexbin.hexbin.prototype.x = function(_) {};
d3_hexbin.hexbin.prototype.y = function(_) {};
d3_hexbin.hexbin.prototype.radius = function(_) {};
d3_hexbin.hexbin.prototype.extent = function(_) {};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

5 participants