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.