Static Call Graph analyzer for Javascript - javascript

I can't seem to find a basic piece of tooling which is a static analyzer that shows me which pieces of code use methods from which other pieces. I could even do with a very primitive one that only shows me which source files contain references to names found in other files in a NodeJS project (still using CJS require here). So far all I have found is a couple of abandoned projects, but one should think there simply must be something out there.
Edit: Graphical output is not required (but certainly a plus); what I primarily need is a tabulation (text) of which functions in which module call functions from which other modules so I can order dependencies.
Sublime text has this feature where when you hover over a name you get the location where that name was defined; this even works across modules and with CoffeeScript. Does anybody know how that is implemented?

This is an actively maintained proprietary call graph generator that supports multiple languages.
Usage : callGraph <files> <options>
https://github.com/koknat/callGraph

I’ve been looking for a similar tool to help my team track the indirect usage of a deprecated function, so I ended up writing a script based on the ts-morph module: https://gist.github.com/adrienjoly/fc117b187f87cca3417abc4a8433e3a2
It’s a node.js CLI that generates the call tree (a.k.a. call hierarchy, or dependency graph) of a function. You can probably modify it to support JavaScript projects. Or create a tsconfig.Json file that includes your JavaScript files.
Hope this helps!

Related

Intellisense of VS Code is poor

Hi I am using VS Code for quite some while and it's Suggestions of, for Example Class properties or methods is kinda poor. I wanted to check out if this is suppose to be like that or if that is an Issue only for me. I am using it mostly for frontend development with JS/TS or JS Frameworks and often when I install npm packages and import them Intellisense is not showing me their properties which is very lame because this should be in my opinion the number one support it should provide. Many other features of it are great so I would like to keep using it but if that is the supposed behaviour I think I have to switch to a new IDE.
For Example I am using Three JS right now which has in my opinion a very solid Object Oriented Style where it is very essential to know what properties and methods a class has, though Intellisense kind of does not know unless I have typed it once manually, e.g:
I have imported Three JS as follows at the top of the file:
import * as THREE from '../node_modules/three/src/Three.js';
and I am looking for TextureLoader which suppose to be a method of the THREE class which it is when I type it manually, everything works fine though VS Code does not seem to recognize it which is very poor behaviour for an IDE. The Suggestions you see in the Image are the only ones it suggests me. (There is textureLoader typed with a small t at the beginning, but that is because I have used a variable with that name) so VS Code only suggests me things that I have typed already. And
I have checked all the related Posts Stackoverflow is showing me but nothing is related to this topic and All the bug fixes only are related when you have a literal bug in VSCode, but I am not even sure this is an actual bug. Also many people love VSCode and claim it is the best free IDE and I am wondering why if it even can't provide the most fundamental things. I remember Eclipse for Java where it showed you every attribute and method of a class.
I thought it could be a problem of JS since it has no types but I think I remember that Webstorm provided the suggestions correct for JS
So my question is, is that expected? Should the Intellisense mechanism not detect Methods and variables defined in a imported class and just provide you with a list of all of them?
So I have found out that it is not just a problem with my VS Code. VS Code just cannot know what types or methods are available for a class or object. I thought it might have some parsing capabilities running through an class and picking up it's methods to display it in the suggestion/code completion box, but I guess this is to overkill.
So Type completion is available if you use Typescript. For me event though I am using Typescript together with Three.js I still haven't had any useful suggestions in my VSC. So I have found out that the IDE relies on the type definition files "[name].d.ts" where types for Typescript are defined. These should be provided by the author of libraries/ packages you use.
If their are not there is a repo where you can check if such types are available on the npm registry found under #types so for me I had to manually run:
npm install --save-dev #types/three
which installed me a new directory under #types/three with a d.ts for every three JS Module.
when you do then an import like:
import * as THREE from 'three';
typescript knows to also look for declaration files d.ts under "node_modules/#types/three" I guess
So to summarize:
No code completion because of js dynamic type system like [python, ruby]
You can have code completion using typescript since it has static types like [java, #c]
There must a [name].d.ts file provided telling the ide how a class is defined.
For build-in things like the 'dom' and 'window' it is provided by default when installing typescript
correct me if I'm wrong

Webpack: How to have runtime (not buildtime) feature flags with same module names?

I'm hoping to find a way to have alternate versions of the same file available from the same webpack run and same output url, with a different chunk/bundle being dynamically loaded after a service call determines which group a user falls into.
Background:
Putting alpha/beta changes into production in the same build and output url lets us develop and test features with external users, but sticking conditionals everywhere (and later removing them) that needs can change is error-prone and generates more complicated code.
My thought was to have alternate versions of the same files in specially named subdirs - e.g. foo/file.js and foo/flagged--special/file.js - and then when something does import blah from 'foo/file' it will automatically get the correct version for that user.
This avoids conditionals in the code itself, and making a feature available for all is just overwriting the base file with the alternate. It also doesn't involve huge changes to our existing codebase and webpack config, nor does it involve a lot of funky and product-specific syntax to replace all our import statements. (After I put the idea together, someone pointed me to Mendel, where Yahoo did much the same thing, albeit as their own framework that is not friendly with webpack, so I'm assuming the base idea isn't crazy)
Problems:
I see examples of feature-flagging a build to one version or the other, but not any examples of having both in one build.
I could write a custom loader or plugin to wrap each file load to do this (I think - not sure about how the output of webpack works in terms of runtime evaluation), but that would result in adding both versions to the bundle.
I'm thinking I can create a base output chunk that does little more than fetch the user's options, then dynamically load one of two alternate chunks that have the different versions...but I have no idea if that will work, or if I'm fighting a losing war vs the webpack internals.
Can this work?
Has someone already done this?
Is there a better way?
Thanks in advance!

Is it possible to load a JS library to DocumentDB?

I like to use complex functions in DocumentDB, inside a SP.
Can I load a JS library to be called from the SP ?
A library I created called documentdb-utils has limited support for including libraries in your sprocs using require(...). Note, it doesn't load them into DocumentDB independently to be called from another sproc, it simply inlines them in each sproc that needs it. It's surprising how big a library you can fit but it is not unlimited. You'll have multiple copies of some libraries on the server, one in each sproc that needs it but that doesn't seem to be a problem and I reload the sprocs every time I startup so I don't have a version control issue. There is only one version of each npm module in my project so the same one gets loaded regardless of how many sprocs it's required from.
You can use many npm modules with this functionality but not all. For instance, I couldn't get lowdash to work, so I had to settle for underscore. I have included examples of how to load underscore and async.js in the library. Here is the test for loading and executing async.js. Here is the test for loading underscore.
Note, I'm using CoffeeScript to create the library. The tests and most of the examples are in CoffeeScript, but I have a few examples in JavaScript. Not to worry though because you can easily compile CoffeeScript to JavaScript. There is a lot of help on the web automating this.

difference between d3.v3.js and entire D3 repository

For d3, or any javascript package in general, what is the difference between the js file which has the entire source code(say, d3.v3.js) and the github repo for it(in the case of d3, it is https://github.com/mbostock/d3).
What does the github repo contain that the entire source code does not?
I read on Scott Murray's tutorials that the D3 repository contains "all of the component source code". Can someone explain what's meant by 'component'?
Let's look at the Whatever library. It does whatever. The repo for it is located at https://github.com/someone/whatever.js (this is not a real repo).
The repo itself usually contains a variety of info, including documentation, style guides, and code organization. Whatever.js is actually made up of three files: lib/whatever.js, lib/whatever-tools.js, and lib/whatever-xml.js. These get concatenated for actual use, but for development of whatever.js itself it's easier to work with separate files.
Having to deal with just commits all on a single file is absolutely horrible. Pull requests would be even worse.
The distributed version, aka whatever.js and whatever.min.js, is a version of the repo code after it's been dealt with however it needs to be. In the case of most libraries the files just get concatenated, but for some libraries fancy things happen. The .min.js version is the normal file, but after being run through a minification tool, these days usually UglifyJS2.
Some libraries will not even have all of the code in the main generated file, usually due to usage reasons. For example, Angular.js doesn't have the ng-route module in angular(.min).js, you need to include angular-route(.min).js too. This is for sanity reasons, because quite a lot of Angular uses don't need or want the routing system, and it's a fairly big addon.
it is the same as with any project in development environment and deployment environment, so in github that's a development environment for d3.js d3.v3.js is the compiled library that you need to use in your product.
Zeke Sonxx's answer is excellent. I'll just add that in the case of Javascript, because the source code can be run directly, there might be less need for a github repo. But even in the simplest cases, you get to add additional files when needed, keep track of problems and plans in the github issue system, etc. Example: The gexf-parser repo only has one main source file, src/parser.js, but there is a collection of files for testing as well, and a few other useful files. Javascript can also be "compiled", but it's not compilation in the sense of some languages (C, Java, Clojure, etc.). The application distributed will often be built from many different source files in the repo.

Packaging client-side scripts at runtime with support for Common.js

I am writing a web server in Node.js, and I want it (among other things) to deliver a single JavaScript file to the client which contains my client SDK. The SDK is basically an object which provides lots of functionality the client can use.
I need to build the SDK from various sources:
3rd party libs, such as AngularJS
Custom code, which is stored in static .js files on the server
Custom code, which is created dynamically in-memory at runtime
For being able to test my custom code (#2) easily, and for being able to share this code with the server-side as well, it would be great if I could write it according to CommonJS.
I do not have too much experience with bundling things up for the client-side, but I know UglifyJS and Browserify.
If it was only about concatenating some files (and perhaps minifying them), I knew what to do with UglifyJS. If it was only about delivering some stuff that is compatible to CommonJS, I also knew what to do with Browserify. What I don't get is their combination, and this in addition with demand #3 - the dynamically generated code.
This essentially means that I am not able to use Grunt for this, but that everything needs to be done at runtime (please let's not discuss why I want to do it like this).
So … I'm somewhat lost. Can anybody help clarify things for me? How do I have to put all these pieces together so that I finally end up with a single deliverable that can be sent to the client, and that the client can use?
Basically, what the client should end up with is a number of global objects such as $, angular and my very own custom object, but all this by only loading one single file.
How could I do this?
PS: I do not have the need to put the result to disk on the server, if it's a pure in-memory solution that's perfectly fine for me (and is even preferred, as then I do not need write access to the file system).
Imho webpack provides all the features you need. It's a bundler like browserify but I find it more flexible and extensible. webpack is agnostic to different module styles (CommonJS, AMD, ES6 or old-school globals) and is able to apply and chain pre-processors on modules. These are called loaders (according to the CommonJS spec) and can be used to generate code dynamically. Usually they transform LESS to CSS or CSS to JavaScript, but they can be used for any dynamic task.
To provide your global $, angular and your custom object you could use the script-loader, which runs the given module classically in a global context.
What you're looking for is called "asset pipeline".
You can use mincer (I didn't try it, but it looks very promising) or asset-pipeline (certainly will do the job, but is kinda deprecated).

Categories