npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jsdoccer

v2.0.2

Published

A Node.js tool to auto document your ECMAScript (Java Script) in JSDoc 3 using Esprima.

Downloads

16

Readme

Goals:

  • [x] generate stubbed YAML documentation template
  • [x] build document webpages from JSDoc
  • [ ] lint existing documents

**There have been some major changes between 1.0, 1.1, 1.2 and 1.3. This is a pure Node.js tool. If you are looking for a Grunt task you can find it at grunt-jsdoccer.

A collaboration with @jasonLaster

JsDoccer

(OK a tool that documents your code should have some REALLY good docs right?. But I'm working on getting that live so, imagine that icon with the man shoveling stuff)

A collection of Node.js tasks to:

  • Auto-document your ECMAScript (Java Script) using Esprima It converts your code into YAML templates that allows you to fill in stubbed examples and descriptions using JSDoc 3 sintax.
  • Convert the those YAML files to HTML docs.
  • Lint those docs to keep them up to date.

Basic Usage

Setup

$ npm install jsdoccer
  1. Create stubbed YAML document templates.
$ node node_modules/jsdoccer/stub [<path/to/files/you/want/to/doc/globaway/**/*.js>]

This will generate 'ast', 'json-pre', and 'yaml-stubbed' files in the intermediate directory under the the dest argument in your .jsdoccerrc config file. At the moment you will want to copy your YAML stubs to a different directory before you add examples and descriptions so you don't overwrite your files if you rerun the stub task. You will want to place them in the directory configured in the .jsdoccerrc file under the documentedYaml arg. The default is yaml-documented. I am working on removing this step and auto augmenting existing documentation in a non-destructive fashion.

  1. Generate documents.
$ node node_modules/jsdoccer/doc [<path/to/yaml/you/want/to/doc>]

Generated documents can be found in the doccer/docs folder (or where ever you configured the destination). At the moment the default styles are messed up so you will get naked HTML.

Configuration

The ./jsdoccerrc file contains configuration for the tool. If no files are provided on the command line the tool will glob the files listed in the js directory for target files. In the generate documentation phase the tool will look for your augmented YAML in the globs configured under the documentedYaml argument. All intermediate files are saved under the dest path. These are useful for debug.

Syntax targets are specific types of code you would like to document like functions or properties. JsDoccer comes with the following targets that you include or ignore based on a boolean under the targets/defaut in your .jsdoccerrc file. They are:

  • name
  • class
  • constructors
  • events
  • functions
  • properties

Extention

JsDoccer uses a collection of templates and functions designed to find syntax targets and render them to both YAML stubbed templates and HTML documents. You can use what ever templating library you are comfortable with, however with nested templates I recomend Handelbars for it's support of partials.

Each syntax target requires a YAML template for creating the document stubs and an HTML template for creating the documentation as well as functions to render them. You will also need to provide a matcher function that can parse an AST node looking for the target. You may optionally provide a linter function if you would like to use the linter. All of the default target code can be found under scr/syntax-targets for examples. This is also where the documentation website index template docs-index.hbs lives.

There are 2 ways to extend the doccer with custom targets. 1) Add arguments and a path to your .jsdoccerrc file under targets/custom and targets/customTargetsPath. To choose this route you will need to set up a folder with an identical name to the target argument in your .jsdoccerrc file. in that folder you will need to provide the following 6 files and they must be named as follows

  • linter.js a lint function that will be passed old and new verison you your YAML
  • matcher.js a matching fuction that will search an AST and return the pertinate information about that target.
  • templateYaml.js a function that will populate a template with the YAML stub of your syntax target.
  • templateHtml.js a function that will populate a template with the HTML documentation of your syntax target.
  1. Add the functions to the jsdoccer object.
jsdoccer.addSyntaxTargets({
    target: name,
    linter: aLinterFunction,
    matcher: aMatcherFunction,
    yamlTemplater: aYamlTemplaterFunction,
    htmlTemplater: aHtmlTemplaterFunction
});

You can pass several targets in an array as well.

What You Need To Know About ASTs

An AST or Abstract Syntax Tree is a typed representation of valid code. Esprima will parse valid ECMAScript and generate an AST. ESCodeGen provides an "inverse" operation that will generate valid ECMAScript from Esprima ASTs.

Esprima will parse this Javascript:

var answer = 42;

and generate this AST:

{
  "type": "Program",
  "body": [
    {
      "type": "VariableDeclaration",
      "declarations": [
        {
          "type": "VariableDeclarator",
          "id": {
            "type": "Identifier",
            "name": "answer"
          },
          "init": {
            "type": "Literal",
            "value": 42,
            "raw": "42"
          }
        }
      ],
      "kind": "var"
    }
  ]
}

AST types are defined by the Spider Monkey Parser API.

Target Syntax Matchers

In order to find syntax targets you can create a custom document "type" by adding a type attribute and associated matching function to the jsdoccer/syntax-matchers.js hash for example:

module.exports = {
    functions: function(ast) {
      var json = [ast].
        filter(function (ast) {
          return ast.type === 'Property' &&
            ast.value.type === 'FunctionExpression' &&
            ast.key.type === 'Identifier' &&
            ast.key.name !== 'constructor'; // filter named constructors
        }).
        map(function(property) {
          return {
            name: property.key.name,
            tags: [property.key.name.indexOf('_') === 0 ? ['@api private'] : ['@api public'],
              property.value.params.
              filter(function (param) {
                return param.type === 'Identifier';
              }).
              map(function (param) {
                return '@param {<type>} ' + param.name + ' - ';
              }),
              _hasReturn(property.value.body.body) ? ['@returns {<type>} -'] : []
            ].mergeAll()
          };
        });
        
      if (json.length > 0) {
        return json.pop();
      }
      
      return false;
    }
  };

Note: I am using map/reduce to produce exactly the JSON I need here. You could just as easily use regex or even string matching to identify a target case and return the current unfiltered AST node containing all the data your template requires.

The script will recursively walk the ASTs of each file passing every node to each match function. Each match function should return false or a valid JSON object containing all of the data the associated YAML template requires. While you can certainly return the raw AST node, I recommend you filter and organize your JSON here rather than in the template.

To find out the AST conditions that match the code you would like to document compare your code with the ASTs saved in the ast directory. Then you will have a predictable AST JSON structure to query in an associated template for each document type.

Parse JSON like a champ

Map/Reduce is your friend when you need to pull deeply nested targets out of a large amount of JSON. I use a modified Array with the 5 magic RX methods attached. I highly recommend you spend a little time with this excellent tutorial from Jafar Husain of Netflix Note: Do it in Chrome. It doesn't work in Firefox. Then you will be able to inspect the generated AST files in the ast directory and write your own custom matchers in the syntax-matchers.js file.

Example:

functions.tpl referenced in the syntax-matchers.js hash above will search for this template in the jsdoccer/templates/yaml dir specified in the .jsdoccerrc file above. Note the indentation of the loop to populate the template with param values.

<%- id %>
  description: | <% params.forEach(function(param) {%>
    @param {type} <%= param %> - <param description> <%}); %>
  
  examples:
    -
      name: Function Body
      example: |

Here is a sample of the yaml produced:

unbindFromStrings
  description: | 
    @param {type} target - <param description> 
    @param {type} entity - <param description> 
    @param {type} evt - <param description> 
    @param {type} methods - <param description> 
  
  examples:
    -
      name: 
      example: |