8

I'm currently working on a JavaScript project using Backbone.js and I wonder how can I navigate between files, based on method and object definitions.

For example, I keep references to some of my views in the global object App.Views, and I would like to be able to navigate to each individual definition (App.Views.Home, App.Views.SomePage, etc.) if I encounter one. Also, there are a lot of closures used for avoiding namespace leaking, and I want to know how can I automatically follow these definitions.

I've seen tern but there are not many examples on how to configure it so I have not been able to do much.

What are some good tools for this?

  • 1
    "... but there are not many examples on how to configure it ..." -- Under the "Documentation" heading on the tern home page it says "The reference manual should be your first stop for figuring out how to use Tern." At least they're honest o.O – itsjeyd Nov 4 '14 at 22:24
8

I would absolutely recommend tern. I discovered it halfway through my internship (working in Node.js) last summer, and it worked wonderfully with company-mode and js2-mode.

js2-mode by itself is quite powerful. It can handle the usual M-. jumping within a file most of the time, and tern complements it nicely with inter-file/module jumping (esp. in the node ecosystem).

The first step to using tern is installing the binary. I personally used npm to do so:

$ sudo npm install -g tern

Then install in Emacs. The relevant section from my init.el is:

;;; tern
(package-require 'tern)
(add-hook 'js2-mode-hook (lambda () (tern-mode t)))

The final step is to set up a .tern-project file in the root directory of your project. For Node.js projects, I use this as a starting point:

{
    "loadEagerly": [
        "src/**.js"
    ],
    "plugins": {
        "node": {
        }
    }
}

If you use company-mode, then installing company-tern is also highly recommended:

(package-require 'company-tern)
(eval-after-load 'company
    '(add-to-list 'company-backends 'company-tern))

As a note, I did have some trouble with the tern server occasionally dying this past summer (2014). Running the following fixed it consistently:

M-: (delete-process "Tern") RET

I wasn't able to figure out exactly what was causing it, but it happened infrequently enough to be little more than a nuisance.

References:

  • This looks pretty much like the configuration I got. The thing is I'm almost always prompted with No definition found. That's why I thought there may be something wrong with my configuration. For example, in one file I have app.eventBus = _({}).extend(Backbone.Events); and in another I have app.eventBus.trigger("changeURL","");. But when I do tern-find-definition for my latter eventBus I get No definition found. Is there something I do wrong, or is just tern not supporting the kind of behaviour I imagine it would support? – caisah Nov 5 '14 at 16:36
  • With some frontend frameworks it has issues. It was almost always unable to figure out what to do with Angular (although I avoided the Angular bits and didn't try to figure out how to make it work with them). If the files are not referencing each other via RequireJS-style calls then you'll have to do more digging. It looks like somebody got it working (?) but I don't have enough experience with that to tell. – J David Smith Nov 5 '14 at 19:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.