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

jsdef

v0.2.8

Published

A tool to parse documentation for javascript in a more straight-forward way

Downloads

55

Readme

jsDef

A tool to parse your comment in Javascript to generate documentation in a simpler or/and straight-forward way.

Why this

To answer this question, we need to answer two sub-questions: "Why bother writing comments and docs?" and "Why not using alternative solution?"

Why bother

Javascript is a weakly-typed language. Having that said, types (or data structures) indeed exist in every places in your project. For instance, dealing with data fetched from the backend, you can do nothing, before you know the actual "output" of the REST api.

Types serves as the "contract" between you and other developers, or in an even fancy way, "contract" between "You" from different time (i.e, past, present and future you).

Having types documented can greatly benefit a lot as you will spend less time guessing, and/or finding clue of how a data is constructed. In the real world, we witness someone invoke an actual xhr so that he/she can get some idea of what an REST api returns, and that happens frequently enough that holds us back in development.

Install

$ npm install -g jsdef

Usage

Maintain a config file

$ jsdef init-config

A default config file (jsdef.config.js) will be created under cwd:

module.exports = {
    projectKey: 'myProject-1.0.0',
    projectName: 'myProject',
    version: '1.0.0',
    root: __dirname,
    dist: __dirname + '/jsdef',
    doc: {
        includes: [/^\/doc\//],
        resolves: [/\.md$/],
        excludes: []
    },
    src: {
        includes: [/^\/src\//],
        resolves: [/\.js$/],
        excludes: [/__test/]
    }
};

Parse source files

$ jsdef parse

Generate dist files

$ jsdef release

open the config.dist -> index.html to see the results

Run a watch server

$ jsdef watch-server

Run a prod server

$ jsdef prod-server

Writing

General Writing

Add #@link-key-words or [link-text#@link-key-words] at any places in the files to create smart links:

// could refer to #@api.lib.startParsing for the details...

// resolve the [card-0526#@iteration-1-card-0526] issue...

Doc files writing

Add :key-words after headings to create link anchors:

# Iterations :iteration-top
    ... ...
## Iteration 1 :iteration-1

### Cards  :iteration-1-cards
    ... ...

Src files writing

Use @start-def to create api namespaces

Use @def to create api key path

Use as to create inner key words

// @start-def: Point: {}
var Point = {
    /**
     * @def: .init: x, y => pointInstance
     *   pointInstance: {} as point
     **/
    init: function(x, y) {
        ... ...
    },
    /**
     * @def: .distance: pointX, pointY => distance
     *   pointX: #@point
     *   pointY: #@point
     *   distance: number
     **/
    distance: function(pointX, pointY) {
        ... ...
    }
};

Why not alternatives

JSDoc (and similar options, e.g. documentationjs, ESDoc etc.)

JSDoc is a set of annotation and rules for documenting javascript in the comments. If you come from the Java world, you should be familiar with JavaDoc, which is the origin inspiration of JSDoc. There are quite some generators in the market follows the philosophy of JSDoc:

  • JSDoc
  • ESDoc
  • documentationjs
  • JSDuck
  • dox

Such kind of generators has the following characteristics:

  • It is bound to your actual code, e.g. the function name is not specified by annotation, instead, it comes from the actual function that is annotated.
  • It requires the Javascript to be parsed. Thus, it requires proper transform plugin if the source is not standard, e.g. ES2017.
  • It is annotated in a sense of "per level" and there is no flexible way to define deep data structure in one-go.

Steep learning curve

It has a steep learning curve. Even you are familiar with JavaDoc, JSDoc would still hard to master.

For instance, there are currently 67 block tags and 2 inline tags available for JSDoc 3. Each tag could have some magical syntax to learn, and you also need to learn when and where to use which one.

Besides, according to different pattern, different codebase requires different style of annotating, e.g. CommonJS style, AMD style, OOP style etc.

Due to its complexity, setting up the correct documentation you want, is often time-consuming. If you don't follow the "right way" exactly, you would be surprised by the generated doc very likely.

A bit tedious

It's a bit tedious to document in the JSDoc-style.

First, the way of documenting nested properties is not developer-friendly. Have a read the following code:

/**
 * @param {string} first
 * @param {string} last
 * @param {Object[]} teams
 * @param {string} teams[].name
 * @param {string} teams[].location
 * @param {Object[]} teams[].members
 * @param {string} teams[].members[].name
 * @param {number} teams[].members[].age
 */
function newPerson(first, last, teams) {
    return {first, last, full: first + ' ' + last, teams}
}

Any property is defined in the style of "full path". That's not easy to write and maintain. Imagine that you are refactoring the structure of teams, e.g. renaming "members"

Second, links are very important in documentation. Linking to another "thing " is not easy either. In JSDoc-like generators, a full path is required to describe the target of a link. e.g. MyClass#myInnerMember.getInstance .

Imagine that the structure is changed, how tedious it is to maintain your links?

It affects the way you code

Apparently, adopting JSDoc-like generator could easily affect how you code.

First, it could affect how you structure your code. As it's said, such doc generator is bound to your code. Not writing in the way the generator likes won't give you a proper documentation.

Second, even worst, sometimes you might need to write some "fake code" in order to make the doc generator happy.

And last but not lease, you may be hesitated to adopt some fancy new ES syntax even you like it, as it could break your doc generation.

Less error tolerant

As said in the above sections, the JSDoc-like generators are not that easy to please. And when you are not doing things right, well, you would have the followings:

  • breaking build, nothing generated at all
  • missing definitions
  • some messy documentation, well styled but non-sense to read
  • breaking links

YUIDoc

YUIDoc has a similar set of tags like JSDoc, except for that it's not bound to your code. It only parse the "comment blocks" amongst your source, and thus, it does not require your code to be valid.

Though it's more flexible, it is still tedious to write, see the section of "A bit tedious".

Also, to generate correct doc, you still need to know how to use all kinds of tags (about 30+ tags to learn).

Docco

Docco is another interesting option. It doesn't depend on your code at all. In another word, it's not designed to document the "interface" of your Objects/Classes. It's main task is to parse the inline comments and generate a good-looking document showing the comment & code side-by-side. Underscore's annotated sourcecode is a good example.

Such solution is not ideal as it's lack of organisation. It's good for the reader to understand details of a piece of code, but it does not provide good knowledge for overall purpose.

TypeScripts

TypeScript is believed by quite some people now that it will be the future of Javascript. And it's kinda true, considering the benefit it provides to us!

Though TypeScript itself is not recognised as a kind of doc generator, the code of TypeScript is documented by default. Providing some extra comment, documentation can be generated easily.

However, adopting TypeScript might not suit some situations. Taking into account the history code debt, the current team's tech stack, etc. So it might not be a solution in some circumstances.

By the way, TypeScript is really worth trying if you have not.

The philosophy of jsDef

So here comes jsDef.

The goals of jsDef :

  • Make the doc as easy to write as possible
  • Does not require extra effort to generate your doc
  • Provide dynamic type/link detection so that it can provide suggestion even your link can not be resolved as an exact target

Refer to How jsDef works for detailed information.