Skip to content

Commit

Permalink
feat(compodoc): add watch mode (#21)
Browse files Browse the repository at this point in the history
Adding watch mode with nodemon workaround for JSON format (compodoc/compodoc#862)
  • Loading branch information
twittwer committed Oct 28, 2020
1 parent cbb00b1 commit 174d69d
Show file tree
Hide file tree
Showing 8 changed files with 669 additions and 107 deletions.
38 changes: 36 additions & 2 deletions libs/compodoc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- [Builder](#builder)
- [Recipes](#recipes)
- [Workspace Docs](#workspace-docs)
- [Watch Mode](#watch-mode)

## Installation

Expand All @@ -34,7 +35,7 @@ ng g @twittwer/compodoc:config <project>

## Schematics

Add compodoc target to a project:
Add Compodoc target to a project:

```
ng g @twittwer/compodoc:config <project> [options]
Expand Down Expand Up @@ -100,6 +101,8 @@ Additional options (used by the builder only) are indicated by an italic written
| serve | `false` | Serve generated documentation. |
| port | `8080` | Port for serving of documentation (default: 8080). |
| | | |
| watch | `false` | Watch for source files changes to automatically rebuild documentation. |
| | | |
| silent | `true` | Suppress verbose build output. |

> All paths should be relative to workspace root
Expand Down Expand Up @@ -137,7 +140,7 @@ Additional options (used by the builder only) are indicated by an italic written

### Workspace Docs

This recipe will describe how to create a Compodoc documentation including your whole workspace and listing the Readme files of all projects.
> Compodoc of the whole workspace incl. all project READMEs (apps/libs) as additional documentation.
1. Create a library for shared/workspace wide tooling (e.g. `tools`)
`ng g @nrwl/(workspace|angular):library <project> [--unitTestRunner=none]`
Expand All @@ -149,3 +152,34 @@ This recipe will describe how to create a Compodoc documentation including your
4. Generate your docs:
`ng run <project>:compodoc`
`ng run tools:compodoc`

### Watch Mode

> Rebuild your documentation on file changes during development.
The watch mode can be activated via argument:

```shell script
ng run <project>:compodoc --watch
ng run <project>:compodoc:json --watch
```

or via additional connfiguration:

```json5
configurations: {
"json": {
"exportFormat": "json"
},
"watch": {
"watch": true
},
"json-watch": {
"exportFormat": "json",
"watch": true
}
}
```

> Compodoc doesn't support watch mode while using JSON as export format ([#862](https://github.com/compodoc/compodoc/issues/862)).
> This scenario is handled by the use of [nodemon](https://github.com/remy/nodemon) to watch source files and rerun Compodoc on changes.
3 changes: 3 additions & 0 deletions libs/compodoc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
"main": "src/index.js",
"schematics": "./collection.json",
"builders": "./builders.json",
"dependencies": {
"nodemon": "^2.0.6"
},
"peerDependencies": {
"@nrwl/workspace": "*",
"@compodoc/compodoc": "^1.1.11"
Expand Down
15 changes: 5 additions & 10 deletions libs/compodoc/src/builders/compodoc/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import {
createBuilder,
} from '@angular-devkit/architect';
import { CompodocBuilderSchema } from './schema';
import { spawn } from 'child_process';
import { resolve } from 'path';
import { buildCompodocArgs, buildCompodocCmd } from './compodoc-utils';
import { spawnCompodocProcess } from './compodoc-utils';
import { ProjectType } from '@nrwl/workspace';

async function runBuilder(
Expand All @@ -31,14 +30,10 @@ async function runBuilder(
options.outputPath ?? resolve('dist', 'compodoc', project);

return new Promise<BuilderOutput>(res => {
const childProcess = spawn(
buildCompodocCmd(options, context),
buildCompodocArgs(options, { ...context, projectRoot }),
{
cwd: options.workspaceDocs ? workspaceRoot : projectRoot,
shell: true,
},
);
const childProcess = spawnCompodocProcess(options, {
...context,
projectRoot,
});

process.on('exit', () => childProcess.kill());

Expand Down
105 changes: 91 additions & 14 deletions libs/compodoc/src/builders/compodoc/compodoc-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,32 @@ import { CompodocBuilderSchema } from './schema';
import { readJsonFile, readWorkspaceJson } from '@nrwl/workspace';
import { WorkspaceSchema } from '@angular-devkit/core/src/experimental/workspace';
import { tmpdir } from 'os';
import { copyFileSync, existsSync, mkdtempSync, writeFileSync } from 'fs';
import {
copyFileSync,
existsSync,
mkdirSync,
mkdtempSync,
writeFileSync,
} from 'fs';
import { ChildProcess, spawn } from 'child_process';

export function buildCompodocCmd(
function buildCompodocCmd(
options: CompodocBuilderSchema,
context: BuilderContext,
) {
): string {
const { workspaceRoot } = context;
return resolve(workspaceRoot, 'node_modules', '.bin', 'compodoc');
}

function buildIncludesFolderForWorkspace(
function buildNodemonCmd(
options: CompodocBuilderSchema,
context: BuilderContext,
): string {
const { workspaceRoot } = context;
return resolve(workspaceRoot, 'node_modules', '.bin', 'nodemon');
}

function createIncludesFolderForWorkspace(
options: CompodocBuilderSchema,
context: BuilderContext,
): string {
Expand Down Expand Up @@ -107,7 +122,7 @@ function getRelativePath(
return relative(workspaceDocs ? workspaceRoot : projectRoot, absolutePath);
}

export function buildCompodocArgs(
function buildCompodocArgs(
options: CompodocBuilderSchema,
context: BuilderContext & { projectRoot: string },
): string[] {
Expand Down Expand Up @@ -140,7 +155,7 @@ export function buildCompodocArgs(
}

if (options.workspaceDocs) {
const includesPath = buildIncludesFolderForWorkspace(options, context);
const includesPath = createIncludesFolderForWorkspace(options, context);
args.push(`--includes=${includesPath}`);
args.push(`--includesName=${options.includesName ?? 'Projects'}`);
} else {
Expand Down Expand Up @@ -206,14 +221,6 @@ export function buildCompodocArgs(
args.push(`--assetsFolder=${assetsFolderPath}`);
}

if (options.serve) {
args.push('--serve', `--port=${options.port}`);
}

if (options.silent) {
args.push('--silent');
}

if (options.unitTestCoverage) {
const coveragePath = getRelativePath(options.unitTestCoverage, {
workspaceRoot,
Expand All @@ -223,5 +230,75 @@ export function buildCompodocArgs(
args.push(`--unitTestCoverage=${coveragePath}`);
}

if (options.serve) {
args.push('--serve', `--port=${options.port}`);
}

if (options.watch) {
args.push('--watch');
}

if (options.silent) {
args.push('--silent');
}

return args;
}

function createEmptyCompodocJson(
options: CompodocBuilderSchema,
{ workspaceRoot }: BuilderContext,
) {
mkdirSync(resolve(workspaceRoot, options.outputPath), {
recursive: true,
});
writeFileSync(
resolve(workspaceRoot, join(options.outputPath, 'documentation.json')),
JSON.stringify({
pipes: [],
interfaces: [],
injectables: [],
classes: [],
directives: [],
components: [],
modules: [],
miscellaneous: {
variables: [],
functions: [],
typealiases: [],
enumerations: [],
groupedVariables: {},
groupedFunctions: {},
groupedEnumerations: {},
groupedTypeAliases: {},
},
}),
);
}

export function spawnCompodocProcess(
options: CompodocBuilderSchema,
context: BuilderContext & { projectRoot: string },
): ChildProcess {
const processOptions = {
cwd: options.workspaceDocs ? context.workspaceRoot : context.projectRoot,
shell: true,
};

const compodocCmd = buildCompodocCmd(options, context);
const compodocArgs = buildCompodocArgs(options, context);

if (options.watch && options.exportFormat === 'json') {
createEmptyCompodocJson(options, context);

const nodemonCmd = buildNodemonCmd(options, context);
const nodemonArgs = [
'--ignore dist',
'--ext ts',
`--exec "${compodocCmd} ${compodocArgs.join(' ')}"`,
];
return spawn(nodemonCmd, nodemonArgs, processOptions);
}

return spawn(compodocCmd, compodocArgs, processOptions);
}
2 changes: 2 additions & 0 deletions libs/compodoc/src/builders/compodoc/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,7 @@ export interface CompodocBuilderSchema extends JsonObject {
serve: boolean;
port: number;

watch: boolean;

silent: boolean;
}
6 changes: 6 additions & 0 deletions libs/compodoc/src/builders/compodoc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@
"default": 8080
},

"watch": {
"description": "Watch for source files changes to automatically rebuild documentation.",
"type": "boolean",
"default": false
},

"silent": {
"description": "Suppress verbose build output.",
"type": "boolean",
Expand Down
Loading

0 comments on commit 174d69d

Please sign in to comment.