Reputation: 1212
I want use d3-tip in my angular 2 project. I'm using angular-cli
In polyfills.ts I am adding:
import "d3";
import "d3-tip";
In component I tried:
import * as d3 from "d3";
...
private tip = d3.tip().attr('class', 'd3-tip')
but I have an error:
__WEBPACK_IMPORTED_MODULE_2_d3__.tip is not a function
I'm installing @types/d3 and @types/d3-tip. Without d3-tip everything working.
I can't understand why @types/d3-tip doesn't working.
Build error:
Property 'tip' does not exist on type 'typeof "/node_modules/@types/d3/index"'.
Upvotes: 1
Views: 683
Reputation: 83
I'm not familiar with d3, but I had an identical problem with firebase.
The trouble starts from the fact that the firebase.js file doesn't declare it's namespace variable firebase
(or what would be the d3
global var in your case) as an object containing methods, but rather just says var firebase=null;
and then proceeds to build it's contents up in several internal function calls that happen when the file is imported and executed by the browser.
When this gets trough the angular-cli build, it is transformed into a different structure, traces of which you can see in your error message __WEBPACK_IMPORTED_MODULE_2_d3__.tip ....
and because the build process doesn't execute the .js files first, it takes only what it's able to see, which is a var firebase=null;
and var d3=null;
in your case, if I'm right.
This is the cause of the problem. Saddly I have no easy solution, in my case I was able to work around it because the firebase API is initialized via a call to initializeApp()
, which is global and outside the firebase.anything
space and it returns an object that provides pretty much everything needed to use the library, so I can do things via this object and avoid calls to firebase.stuff
altogether.
One way that might work for you, but is rather hard in terms of future maintenance, is to find where the d3 variable is declared in a .js file and modify the declaration, so that it is an object containing the names of the methods and properties which you are going to use, for example
var d3 = {
tip: function();
.....
}
It doesn't need to have anything but the structure there, like a .d.ts file - just so, that the webpack builder will pick up that this is not an empty variable, but an object. As I described above, it is not smart enough to link it to the .d.ts and find out the structure of the object - it just takes what it sees declared in the .js file.
This might require you to manually add a call to whatever code the library executes to initialize the d3
var, preferably in some component's ngOnInit()
method, but it might also work without it.
EDIT: In the meantime "scripts": [] in angular-cli.json got fixed and it resolves this. For some reason it wasn't working before, but with angular-cli-beta.25 adding my firebase.js there solves the problem.
Upvotes: 1