Skip to content

Commit

Permalink
feat: add ts cmd (#671)
Browse files Browse the repository at this point in the history
This PR adds support for TS type check, .d.ts generations and docs from .d.ts
  • Loading branch information
hugomrdias authored Nov 18, 2020
1 parent bff4c44 commit f332803
Show file tree
Hide file tree
Showing 15 changed files with 523 additions and 128 deletions.
56 changes: 42 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
# AEgir
# AEgir <!-- omit in toc -->

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) [![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/ipfs/aegir/ci/master?style=flat-square)
[![Dependency Status](https://david-dm.org/ipfs/aegir.svg?style=flat-square)](https://david-dm.org/ipfs/aegir)

> Automated JavaScript project management.
## Lead Maintainer
## Lead Maintainer <!-- omit in toc -->

[Hugo Dias](https:/hugomrdias)

## ToC <!-- omit in toc -->
- [Project Structure](#project-structure)
- [CI](#ci)
- [Travis Setup](#travis-setup)
- [Github Action Setup](#github-action-setup)
- [Stack Requirements](#stack-requirements)
- [Testing helpers](#testing-helpers)
- [Fixtures](#fixtures)
- [Echo Server](#echo-server)
- [Get Port](#get-port)
- [Tasks](#tasks)
- [Linting](#linting)
- [Testing](#testing)
- [Coverage](#coverage)
- [Node](#node)
- [Browser](#browser)
- [Building](#building)
- [Generating Webpack stats.json](#generating-webpack-statsjson)
- [Typescript](#typescript)
- [JSDoc Typescript support](#jsdoc-typescript-support)
- [Releasing](#releasing)
- [Scoped Github Token](#scoped-github-token)
- [Documentation](#documentation)
- [License](#license)

## Project Structure

Expand Down Expand Up @@ -39,10 +62,12 @@ Your `package.json` should have the following entries and should pass `aegir lin
"test:browser": "aegir test --target browser"
}
```
## Travis Setup

## CI
### Travis Setup
Check this tutorial https:/ipfs/aegir/wiki/Travis-Setup

## Github Action Setup
### Github Action Setup
Check this tutorial https:/ipfs/aegir/wiki/Github-Actions-Setup

## Stack Requirements
Expand Down Expand Up @@ -200,18 +225,15 @@ after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codeco
```
### Building
You can run it using
The build command builds a browser bundle and TS type declarations from the `src` folder.

```bash
$ aegir build
$ aegir build --help
```
This will build a browser ready version into `dist`, so after publishing the results will be available under

```
https://unpkg.com/<module-name>/dist/index.js
https://unpkg.com/<module-name>/dist/index.min.js
```
**Specifying a custom entry file for Webpack**
Expand All @@ -235,6 +257,14 @@ Pass the `--analyze` option to have Webpack generate a `stats.json` file for the
```bash
aegir build --analyze
```
### Typescript

#### JSDoc Typescript support
```bash
aegir ts --help
```
The `ts` command provides type checking (via typescript) in javascript files with [JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html) annotations.


### Releasing

Expand Down Expand Up @@ -290,12 +320,10 @@ Be aware that by storing it in `~/.profile` or similar you will make it availabl

### Documentation

You can use `aegir docs` to generate documentation. This uses [documentation.js](http://documentation.js.org/) with the theme [clean-documentation-theme](https:/dignifiedquire/clean-documentation-theme).

To publish the documentation automatically to the `gh-pages` branch you can run
You can use `aegir docs` to generate documentation, this command uses `aegir ts --preset docs` internally.

```bash
$ aegir docs --publish
$ aegir docs --help
```

## License
Expand Down
4 changes: 2 additions & 2 deletions cmds/build.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict'
const EPILOG = `
This command outputs two bundles, one in development mode (index.js) and another in production mode (index.min.js) plus respective source-maps, files are written to ./dist folder.
Output files will go into a "./dist" folder.
Supports options forwarding with '--' for more info check https://webpack.js.org/api/cli/
`
module.exports = {
command: 'build',
desc: 'Builds browser bundles with Webpack.',
desc: 'Builds a browser bundle and TS type declarations from the `src` folder.',
builder: (yargs) => {
yargs
.epilog(EPILOG)
Expand Down
10 changes: 5 additions & 5 deletions cmds/docs.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
'use strict'

const EPILOG = `
Supports options forwarding with '--' for more info check https:/documentationjs/documentation/blob/master/docs/USAGE.md
Typescript config file is required to generated docs. Try \`aegir ts --preset config > tsconfig.json\`
`

module.exports = {
command: 'docs',
desc: 'Generate documentation from JSDoc.',
desc: 'Generate documentation from TS type declarations.',
builder: yargs => {
yargs
.epilog(EPILOG)
.example('aegir docs -- --format md -o docs.md', 'Build markdown documentation.')
.example('aegir docs', 'Build HTML documentation.')
.example('aegir docs -p', 'Build HTML documentation and publish to Github Pages.')
.options(
{
publish: {
Expand All @@ -24,7 +25,6 @@ module.exports = {
},
handler (argv) {
const docs = require('../src/docs')
const onError = require('../src/error-handler')
docs.run(argv).catch(onError)
return docs.run(argv)
}
}
46 changes: 46 additions & 0 deletions cmds/ts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict'

const EPILOG = `
Presets:
\`check\` Runs the type checker with your local config (without writing any files). .
\`types\` Emits type declarations for \`['src/**/*', 'package.json']\` to \`dist\` folder.
\`docs\` Generates documentation based on type declarations to the \`docs\` folder.
\`config\` Prints base config to stdout.
Note:
To provide users types declarations with 0-configuration add following to package.json:
\`\`\`json
"typesVersions": {
"*": { "src/*": ["dist/src/*", "dist/src/*/index"] }
},
\`\`\`
Supports options forwarding with '--' for more info check https://www.typescriptlang.org/docs/handbook/compiler-options.html
`
module.exports = {
command: 'ts',
desc: 'Typescript command with presets for specific tasks.',
builder: (yargs) => {
yargs
.epilog(EPILOG)
.example('aegir ts --preset config > tsconfig.json', 'Add a base tsconfig.json to the current repo.')
.options({
preset: {
type: 'string',
choices: ['config', 'check', 'types', 'docs'],
describe: 'Preset to run',
alias: 'p'
},
include: {
type: 'array',
describe: 'Values are merged into the local TS config include property.',
default: []
}
})
},
handler (argv) {
const ts = require('../src/ts')
return ts(argv)
}
}
105 changes: 105 additions & 0 deletions md/ts-jsdoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Documentation for JSDoc based TS types

## Getting Started

Add a `tsconfig.json` to your repo:
```bash
aegir ts -p config > tsconfig.json
```

Add types configuration to your package.json:
```json
"typesVersions": {
"*": { "src/*": ["dist/src/*", "dist/src/*/index"] }
},
```
`types` will tell `tsc` where to look for the entry point type declarations and `typeVersions` for every other files inside the `src` folder.

> The `ts` command follows aegir folder conventions, source code inside `./src`, test inside `./test` and documentation inside `./docs`.

## CLI `ts` command

Run `aegir ts --help` and check the help text. There's presets for common TS use cases.

```md
Presets:
`check` Runs the type checker with your local config and doesn't not emit output.
`types` Emits type declarations for `['src/**/*', 'package.json']` to `dist` folder.
`docs` Generates documentation based on type declarations to the `docs` folder.
`config` Prints base config to stdout.
```


## Adding types with JSDoc

Typescript can infere lots of the types without any help, but you can improve your code types by using just JSDoc for that follow the official TS documentation https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html.

### Rules for optimal type declarations and documentation

This list is a WIP, more rules will be added as we identify them.

#### 1. Commonjs default exports
When using `commonjs` modules, only use default exports when exporting a single `class`.

```js
// GOOD

class IPFS {}

module.exports = IPFS

// GOOD
IPFS.hash = ()=>{}

module.exports = IPFS

// BAD
function hash() {}

module.exports = hash

// REALLY BAD

function hash() {}
function hash2() {}

module.exports = hash
exports.hash2 = hash2


```

#### 2. Commons js named exports
When using `commonjs` modules, always use named exports if you want to export multiple references.
```js
// GOOD
function hash() {}
function hash2() {}
class IPFS {}
module.exports = {
IPFS
hash,
hash2,
...
}

// BAD
exports.hash2 = hash2() {}
exports.hash = hash() {}
exports.IPFS = IPFS
```

#### 3. Use a `types.ts` file
When writing types sometimes JSDoc can be cumbersome, impossible, it can output weird type declarations or even broken documentation. Most of these problems can be solved by defining some complex types in typescript in a `types.ts` file.

```ts
// types.ts
export type IntersectionType = Type1 & Type2
```
```js
// index.js
/** @type { import('./types').IntersectionType } */
const list
```
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
"@commitlint/travis-cli": "^11.0.0",
"@electron/get": "^1.10.0",
"@polka/send-type": "^0.5.2",
"@types/mocha": "^8.0.4",
"@types/node": "^14.14.7",
"aegir-typedoc-theme": "^0.1.0",
"babel-loader": "^8.0.5",
"buffer": "^5.6.0",
"bytes": "^3.1.0",
Expand Down Expand Up @@ -106,13 +109,17 @@
"pascalcase": "^1.0.0",
"pify": "^5.0.0",
"polka": "^0.5.2",
"premove": "^3.0.1",
"prompt-promise": "^1.0.3",
"read-pkg-up": "^7.0.1",
"rimraf": "^3.0.1",
"semver": "^7.3.2",
"simple-git": "^2.7.0",
"strip-bom": "^4.0.0",
"strip-json-comments": "^3.1.1",
"terser-webpack-plugin": "^3.0.5",
"typescript": "^4.0.3",
"typedoc": "^0.19.2",
"typescript": "^4.0.5",
"update-notifier": "^5.0.0",
"webpack": "^4.43.0",
"webpack-bundle-analyzer": "^3.7.0",
Expand Down
14 changes: 4 additions & 10 deletions src/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ const fs = require('fs')
const bytes = require('bytes')
const execa = require('execa')
const rimraf = require('rimraf')
const { fromAegir, gzipSize, pkg } = require('./../utils')
const { fromAegir, gzipSize, pkg, hasTsconfig } = require('./../utils')
const userConfig = require('../config/user')
const tsCmd = require('../ts')

const config = userConfig()

Expand Down Expand Up @@ -41,15 +42,8 @@ module.exports = async (argv) => {
stdio: 'inherit'
})

if (argv.ts) {
await execa('tsc', [
'--outDir', './dist/src',
'--declaration'
], {
localDir: path.join(__dirname, '../..'),
preferLocal: true,
stdio: 'inherit'
})
if (hasTsconfig) {
await tsCmd({ preset: 'types' })
}

if (argv.bundlesize) {
Expand Down
17 changes: 0 additions & 17 deletions src/clean.js

This file was deleted.

Loading

0 comments on commit f332803

Please sign in to comment.