Skip to content

jart/js2-closure

Repository files navigation

Emacs Logo

js2-closure.el

Google Closure dependency manager


MELPA MELPA Stable

Do you use Emacs, js2-mode, and Google's Closure Library? Do you get frustrated writing your goog.require statements by hand? If that's the case, then this extension is going to make you very happy.

js2-closure is able to analyse the JavaScript code in your buffer to determine which imports you need, and then update the goog.require list at the top of your buffer. It works like magic. It also runs instantaneously, even if you have a big project.

This tool only works on files using traditional namespacing, i.e. goog.provide and goog.require. However js2-closure is smart enough to turn itself off in files that use goog.module or ES6 imports.

Installation

Install this package from MELPA using M-x install-package and type js2-closure. If you aren't already using MELPA, see: http://melpa.milkbox.net/#/getting-started

You then need to run a helper script that crawls all your JavaScript sources for goog.provide statements, in addition to your Closure Templates (Soy) for {namespace} declarations (assuming you're using the Soy to JS compiler). You must also download the source code to the Closure Library and pass this script the path of the closure/goog folder.

Here's an example command for regenerating the provides index that you can add to your ~/.bashrc file:

jsi() {
  local github="https://raw.githubusercontent.com"
  local script="js2-closure-provides.sh"
  bash <(wget -qO- ${github}/jart/js2-closure/master/${script}) \
    ~/code/closure-library/closure/goog \
    ~/code/my-project/js \
    ~/code/my-project/soy \
    >~/.emacs.d/js2-closure-provides.el
}

That will generate an index file in your ~/.emacs.d directory. If you want to store it in a different place, then js2-closure-provides-file will need to be customised.

This index file will be loaded into Emacs automatically when the timestamp on the file changes. You need to re-run the script manually whenever new goog.provide statements are added or removed. Automating that part is up to you.

Usage

To use this, you simply run M-x js2-closure-fix inside your js2-mode buffer. This will regenerate the list of goog.require statements by crawling your source code to see which identifiers are being used.

If you want the magic to happen automatically each time you save the buffer, then add the following to your .emacs file:

(eval-after-load 'js2-mode
  '(add-hook 'before-save-hook 'js2-closure-save-hook))

Alternatively, you can use a key binding as follows:

(eval-after-load 'js2-mode
  '(define-key js2-mode-map (kbd "C-c C-c") 'js2-closure-fix))

This tool was written under the assumption that you're following Google's JavaScript style guide: http://goo.gl/Ny5WxZ

You can customize the behavior of js2-closure with the following settings:

  • js2-closure-remove-unused
  • js2-closure-whitelist

See the source code for more information.

Customization Documentation

js2-closure-remove-unused

Determines if unused goog.require statements should be auto-removed. You might want to consider using js2-closure-whitelist rather than disabling this feature. Or you can add a @suppress {extraRequire} JSDoc before before the require.

js2-closure-whitelist

List of goog.require namespaces that should never be removed.

js2-closure-provides-file

Filename of generated elisp file listing all provided namespaces.

Function and Macro Documentation

(js2-closure-fix)

Fix the goog.require statements in the current buffer. This function assumes that all the requires are in one place and sorted, without indentation or blank lines. If you don't have any requires, they'll be added after your provide statements. If you don't have those, then this routine will fail. Effort was also made to avoid needlessly modifying the buffer, since syntax coloring might take some time to kick back in. This will automatically load js2-closure-provides-file into memory if it was modified or not yet loaded.

(js2-closure-save-hook)

Global save hook to invoke js2-closure-fix if in js2-mode. To use this feature, add it to before-save-hook.


Markdown README file generated by make-readme-markdown.el