An open API service indexing awesome lists of open source software.

https://github.com/blameitonyourisp/submodule

A jsdoc plugin for automatically creating nested submodules according to file path.
https://github.com/blameitonyourisp/submodule

Last synced: 3 months ago
JSON representation

A jsdoc plugin for automatically creating nested submodules according to file path.

Awesome Lists containing this project

README

        



# Submodule

A jsdoc plugin for quickly creating nested modules or modules declared over many files without explicitly having to write a module name such as `path/to/file` reflective of the location of the module in the src directory, and without causing duplicate doclets as a result of having multiple files tagged with the same module name. This repository is hosted on [github](https://github.com), if you're already reading this there, then great! Otherwise browse the repository [here](https://github.com/blameitonyourisp/submodule).

![](https://img.shields.io/github/license/blameitonyourisp/submodule?style=for-the-badge&labelColor=181b1a&color=779966) ![](https://img.shields.io/github/package-json/v/blameitonyourisp/submodule/master?style=for-the-badge&labelColor=181b1a&color=779966)

### Table of Contents

- [Description](#description)
- [Installation](#installation)
- [Usage](#usage)
- [Submodule Tag](#submodule-tag)
- [Leafmodule Tag](#leafmodule-tag)
- [Configuration](#configuration)
- [Template Scripts](#template-scripts)
- [Documentation](#documentation)
- [Testing](#testing)
- [Scripts](#scripts)
- [Roadmap](#roadmap)
- [Attributions](#attributions)
- [License](#license)

### Size

Approximate download size of repository, code files within repository, compressed main file, and (just for fun) lines written by the developer including comments etc. Please note that due to file compression, and post download installs/builds such as node module dependencies, the following badges may not exactly reflect download size or space on disk.

![](https://img.shields.io/github/repo-size/blameitonyourisp/submodule?style=for-the-badge&labelColor=181b1a&color=779966) ![](https://img.shields.io/github/languages/code-size/blameitonyourisp/submodule?style=for-the-badge&labelColor=181b1a&color=779966) ![](https://img.shields.io/bundlephobia/minzip/@13ms/submodule?style=for-the-badge&labelColor=181b1a&color=779966) ![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/blameitonyourisp/submodule/master/dist/tokei.json)

## Description

Submodule is a simple jsdoc plugin which adds the `@submodule` tag which will later resolve to a tag equivalent to `@module path/to/file` when jsdoc parses the tag. Submodule also provides scripts for some jsdoc templates which may be added in order re-render the nav section of the auto-generated documentation, turning slash separated module paths into a nested folder structure.

```javascript
/**
* Submodule is as simple as including the tag at the top of a file you wish to
* be turned into a module. As with the regular jsdoc module tag, all doclets
* within that file will then be members of the submodule by default unless
* specified otherwise.
*
* @submodule
*/
```

## Installation

If you are not already using jsdoc in your project(s) then go ahead and checkout the [github repository for jsdoc](https://github.com/jsdoc/jsdoc), otherwise continue with installing this plugin in a package that already has jsdoc installed and configured. This plugin is available from [npm](https://www.npmjs.com), to view there please see the [package page](https://www.npmjs.com/package/@13ms/submodule).

```bash
# install the submodule plugin (recommended as a dev dependency)
npm install --save-dev @13ms/submodule
```

As with any plugin, you must also point jsdoc to the submodule repository in the node_modules folder. This must be done using a jsdoc config file (as of creating this plugin, there is no way to use plugins through the jsdoc cli). If you are not currently using a config file with jsdoc, please refer to [this page](https://jsdoc.app/about-configuring-jsdoc.html) for information on writing a config file, otherwise ensure that your jsdoc config file includes submodule as a plugin (please note that the following is only a fragment of a config file).

```json
{
"plugins": [
"node_modules/@13ms/submodule/"
]
}
```

For further jsdoc configuration options related to submodule, see [here](#configuration), and for installing/using template modification scripts bundled with the submodule plugin, please see [here](#template-scripts).

## Usage

Funky syntax is as simple as `@submodule` included at the top of the file where you might include other jsdoc tags such as `@file` and `@author` etc.

### Submodule Tag

Following jsdoc tag syntax, the `@submodule` tag may accept a name, will ignore any types, and should not be given any description. If the `@submodule` tag is included at the top of a file, and if no name is provided, then the `@submodule` tag will turn the file into a jsdoc module named based on the pathname of the file (i.e. the relative dirname to the base of the src directory within the repository/specified by jsdoc config together with the basename of a file). All doclets/symbols in that file will then be considered members of that module unless otherwise stated as described in the [jsdoc documentation](https://jsdoc.app/tags-module.html) for the `@module` tag.

```javascript
/**
* If no name is provided, submodule automatically calculates file path. For
* example, the following two tags may be considered equivalent in a file with
* path "src/path/to/file.js" where the jsdoc config takes "src" as an include
* directory.
*
* @submodule
* @module path/to/file
*/
```

If a name is provided, then the `@submodule` behaviour of calculating a module path will be overridden, and the custom provided path will be the name of the module (i.e. the tag will behave identically to the vanilla jsdoc `@module` tag).

```javascript
/**
* When a name is provided, submodule is overridden, and therefore the following
* two tags may be considered equivalent.
*
* @submodule custom/module/name
* @module custom/module/name
*/
```

### Leafmodule Tag

The `@leafmodule` tag offers a way to split modules over multiple files with reduced nesting by adding `@memberof` tags to all jsdoc comments in a file based on the module name calculated by submodule. The `@leafmodule` tag will ignore single line jsdoc comments such as type annotations, and jsdoc comments with an existing memberof tag, allowing you to use override module membership with an explicit comment `@memberof` tag as is already possible with the vanilla jsdoc `@module` tag. The `@leafmodule` tag can be used in exactly the same manner as the standard `@submodule` tag; the tag may be used with or without a custom name, however when using `@leafmodule` without a name, the calculated module name will ignore the basename of the file. This may be useful if you wish to create modules that are declared over multiple files with less nesting, and with no duplication of methods in the generated documentation due to using the same `@module` tag at the top of two or more files as discussed in [jsdoc issue #515](https://github.com/jsdoc/jsdoc/issues/515) and [jsdoc issue #1002](https://github.com/jsdoc/jsdoc/issues/1002).

```javascript
/**
* The leafmodule tag causes submodule to ignore the basename of the file when
* calculating the module name. Calculated module name is then added as jsdoc
* memberof tag to every jsdoc comment in the file, excluding single line jsdoc
* comments such as type annotations, and jsdoc comments with an existing
* memberof tag (i.e. as with the vanilla jsdoc module tag, it is possible to
* override the set module with a memberof tag on the desired comment). For
* example, in a file with path "src/path/to/file.js" where the jsdoc config
* takes "src" as an include directory, the leafmodule tag would be equivalent
* to adding the following memberof tag to all jsdoc comments in that file.
*
* @leafmodule
* @memberof module:path/to
*/

/**
* Or, the name field of the leafmodule tag allows you to specify which module
* name is used to tag each doclet with the memberof tag, therefore the following
* leafmodule tag is equivalent to adding the following memberof tag to every
* jsdoc comment in a given file.
*
* @leafmodule custom/name
* @memberof module:custom/name
*/
```

### Configuration

You may configure the submodule plugin in your jsdoc config file. Please consult the table below for the available config options and their uses. See [default](#default-configuration) and [sample](#sample-configuration) configuration snippets for more information.

| Option | Default | Description |
| ------------------ | ----------- | ------------------------------------------------------------ |
| `submodule.ignore` | `["index"]` | `submodule.ignore` is a string array of file basenames to be ignored by the submodule plugin (i.e. the `@submodule` tag behaves identically to the `@leafmodule` tag in files with names listed in this array) . For example with the default ignore array, a tagged file with path `path/to/folder/index.js` will be mapped to `path/to/folder` as the calculated module name instead of `path/to/folder/index`. |
| `submodule.roots` | `{}` | `submodule.roots` is an object of string key-value pairs which allow you to rename certain paths within your included src folder(s). This will usually be used to shorten a path either for the purpose of reducing time to navigate to that submodule, or with the purpose of making that submodule a top-level module (for example important business logic nested within multiple folders which should be displayed at top level). |

#### Default Configuration

Please see below for the the default configuration of the submodule plugin (please note that the following is only a fragment of a config file). Obviously if the default configuration matches your requirements, it is not necessary to add this object fragment to your config file.

```json
{
"submodule": {
"ignore": ["index"],
"roots": {}
}
}
```

#### Sample Configuration

Please see below for the a sample configuration of the submodule plugin (please note that the following is only a fragment of a config file).

```json
{
"submodule": {
"ignore": ["file", "basenames", "to", "ignore"],
"roots": {
"this/path": "turns/into/this/path",
"normally/long/paths/mapped/to": "shorter/paths"
}
}
}
```

### Template Scripts

Having installed submodule as a dev dependency in your project, you now have access to some template modification scripts which update existing jsdoc templates by re-rendering the module section of the nav in the generated documentation into a nested tree structure reflective of how the modules appear in the src directory. The bundled file for a given template will be at `dist/submodule-.min.js` or browse [dist directory here](https://github.com/blameitonyourisp/submodule/tree/master/dist) on github. Please see the following list for currently supported jsdoc templates and instructions on how to configure each one:

- [Docdash](#docdash)

#### Docdash

The [docdash](https://github.com/clenemt/docdash) configuration offers an easy way to inject 3rd party scripts (js and or css files) into the generated html from local file copied into the generated documentation output using the `templates.default.staticFiles.include` array in jsdoc config. Please see below for the appropriate fragment of the jsdoc config file required to inject the submodule docdash re-render script into the generated output. Please note that the sourcemap file is not required, although may be included for the purposes of debugging etc.

```json
{
"docdash": {
"scripts": [ "submodule-docdash.min.js" ]
},
"templates": {
"default": {
"staticFiles": {
"include": [
"node_modules/@13ms/submodule/dist/submodule-docdash.min.js",
"node_modules/@13ms/submodule/dist/submodule-docdash.min.js.map"
]
}
}
}
}
```

## Documentation

Please see [docs folder](https://github.com/blameitonyourisp/submodule/tree/master/docs) in root of repository for author generated documentation specific to certain features and functions of this package. All markdown files in that folder are also included in the tutorials section of the auto-generated jsdoc documentation. For viewing the auto-generated jsdoc documentation for this repository, please clone the repository and use the appropriate npm script(s) and view the docs in the browser on [localhost](http://localhost:8080).

```bash
# auto-generate jsdoc documentation
git https://github.com/blameitonyourisp/submodule.git
cd submodule
npm install
npm serve-docs # will also automatically run script to generate docs and serve docs on http://localhost:8080
```

## Testing

Submodule uses Jest for testing, and a sample directory containing jsdoc comments and empty functions as methods for testing generated output in the browser, please clone the repository and use the appropriate npm script(s) to run the available tests or view sample output in the browser on [localhost](http://localhost:8080).

```bash
# run tests
git https://github.com/blameitonyourisp/submodule.git
cd submodule
npm install
npm test # run available tests
npm serve-docs-sample # serves sample generated docs on http://localhost:8080
```

## Scripts

Please see below for a table of scripts declared in the package.json file. All scripts are listed in alphabetical order, not listed in order of any significance or importance. As with any npm script, they may be run from anywhere in the repository using the command `npm run `. Any relevant bash scripts, node scripts etc. which are used independently by one of the following npm scripts may be found in the scripts directory in the root of the repository.

| Name | Usage |
| :------------------------ | :----------------------------------------------------------- |
| `build` | Runs Jest test suite, counts lines of code, and builds package (should the test suite fail, the script will not continue to build the package). |
| `build-dev` | Builds package, and puts bundled, minified result in dist directory. |
| `docs` | Builds auto-generated docs using jsdoc, and puts generated files in jsdoc directory. |
| `docs-sample` | Builds auto-generated docs for the sample code using jsdoc, and puts generated files in jsdoc-sample directory. |
| `serve-docs` | Builds and serves auto-generated on [localhost](http://localhost:8080). |
| `serve-docs-sample` | Builds and serves auto-generated for the sample code on [localhost](http://localhost:8080). |
| `test` | Runs Jest test suite. |
| `tokei` [^1] | Counts approximate lines of code written by the author, and generates a json endpoint for a line count [shields](https://shields.io/) badge. Please note that this script relies on `tokei`, a CLI application written in Rust. If `tokei` is not installed on the system, then this script will not run. |
| `watch-docs` | Serves docs on [localhost](http://localhost:8080/jsdoc) and watches src directory using [nodemon](https://www.npmjs.com/package/nodemon), and reloads server upon changes. |
| `watch-docs-sample` | Serves sample docs on [localhost](http://localhost:8080) and watches src directory using [nodemon](https://www.npmjs.com/package/nodemon), and reloads server upon changes. |

[^1]: At the time of writing, the tokei endpoint for dynamic badges/shields is intermittent and unreliable, showing a 502 bad gateway error. This error also prevents the [shields](https://shields.io/category/size) lines of code badge from rendering correctly, causing all repos to show as having 0 lines of code. The format for the tokei badge URL may be found [here](https://github.com/XAMPPRocky/tokei#badges). To circumvent this, lines of code are being counted "manually" using the tokei [rust CLI](https://github.com/XAMPPRocky/tokei) and a json endpoint to generate the badge. As such the lines of code badge may be out of sync with the latest commit, although given that this is a "just for fun" metric, it is not of importance.

## Roadmap

Submodule currently does not support a large number of jsdoc templates, however beyond that submodule is a simple, feature complete, jsdoc plugin. If you find a bug or think there is a specific feature that should be added or changed, please file a bug report or feature request using this repository's issue tracker. This is a small and privately maintained repository, as such pull requests may or may not be reviewed subject to availability. Please see below for proposed new features which may be added in later updates:

- Support for nested module re-rendering in more 3rd party jsdoc template plugins
- Allow submodule plugin to observe type of tag in order to determine if basename should be ignored or not (i.e. replace the `@leafmodule` tag with a boolean flag in the type field of the `@submodule` tag)
- Add script for injecting bundled template modification scripts into the html file outputted by jsdoc when using templates that do not support 3rd party script/stylesheet injection out of the box

## Attributions

Submodule uses 3rd party assets for the icons used to re-render the nested module nav, using the svg path and an svg to image data url encoder to store the svg paths directly in the stylesheets. Please find below links for these attributions:

- Path to image data url encoder [github repository](https://github.com/yoksel/url-encoder/) and [web util](https://yoksel.github.io/url-encoder/)
- Icon svg assets [github repository](https://github.com/Esri/calcite-ui-icons) or alternatively [browse here](https://www.svgrepo.com/collection/calcite-sharp-line-icons)

## License

------

**DISCLAIMER** The author(s) of this repository are in no way legally qualified, and are not providing the end user(s) of this repository with *any* form of legal advice or directions.

------

Copyright (c) 2022 James Reid. All rights reserved.

This software is licensed under the terms of the MIT license, a copy which may be found in the LICENSE.md file in the root of this repository, or please refer to the text below. For a template copy of the license see one of the following 3rd party sites:

- [opensource](https://opensource.org/license/mit/)
- [choosealicense](https://choosealicense.com/licenses/mit/)
- [spdx](https://spdx.org/licenses/MIT)

#### License Text

Copyright 2022 James Reid

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.