Skip to content

Commit

Permalink
feat: update build and release commands (#946)
Browse files Browse the repository at this point in the history
* Release command now runs `semantic-release`
* Build command runs `tsc`
* Dual ESM/CJS support is dropped - ESM is now ESM and CJS is CJS
* Adds `clean` command
* Updates all deps
* `aegir.js` config files can now be ESM
* ts tests are now loaded by default
* Adds `check-project` command to ensure correct config for aegir projects
* Converts project to esm
* Exports chai at `aegir/utils/chai`

BREAKING CHANGE: ESM modules are now published as ESM and not dual-ESM/CJS
  • Loading branch information
achingbrain committed Apr 7, 2022
1 parent 585b004 commit e3a4b45
Show file tree
Hide file tree
Showing 102 changed files with 2,149 additions and 1,695 deletions.
2 changes: 1 addition & 1 deletion .aegir.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @type {import("./src/types").PartialOptions} */
module.exports = {
export default {
docs: {
entryPoint: 'utils'
}
Expand Down
19 changes: 8 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
# AEgir
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://ipfs.io/)
# AEgir
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](https://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)

> Automated JavaScript project management.
## Lead Maintainer
## Lead Maintainer

[Hugo Dias](https://github.com/hugomrdias)

## Project Structure

The project structure when using this is quite strict, to ease
replication and configuration overhead.
The project structure when using this is quite strict, to ease replication and configuration overhead.

All source code should be placed under `src`, with the main entry
point being `src/index.js`.
All source code should be placed under `src`, with the main entry point being `src/index.js` or `src/index.ts`.

All test files should be placed under `test`. Individual test files should end in `.spec.js` and will be ran in all environments (node, browser, webworker, electron-main and electron-renderer). To run node specific tests a file named `test/node.js` should be used to require all node test files and the same thing for the other environments with a file named `test/browser.js`.
All test files should be placed under `test`. Individual test files should end in `.spec.js` or `.spec.ts` and will be ran in all environments (node, browser, webworker, electron-main and electron-renderer). To run node specific tests a file named `test/node.js` or `test/node.ts` should be used to require all node test files and the same thing for the other environments with a file named `test/browser.js` or `test/browser.ts`.

Your `package.json` should have the following entries and should pass `aegir lint-package-json`.


```json
"main": "src/index.js",
"files": [
Expand Down Expand Up @@ -80,7 +77,7 @@ Aegir can be fully configured using a config file named `.aegir.js` or the packa
```js
// file: .aegir.js

'use strict'


/** @type {import('aegir').PartialOptions} */
module.exports = {
Expand Down
20 changes: 4 additions & 16 deletions md/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,14 @@

## Setup

`aegir` leverages [ipjs](https://github.com/mikeal/ipjs) to output a build with `cjs` and `esm` for maximum compatibility. The general guidelines for writing a module in `esm` are detailed on the `ipjs` README. `aegir` will automatically identify a `esm` repo by the `module` property in `package.json`.
`aegir` will automatically identify a `esm` repo by the `module` property in `package.json`.

## Electron testing

Electron does [not support ESM](https://github.com/electron/electron/issues/21457) at the time of writing. When writing a module using ESM, we need to compile the tests to `cjs` and rely on them. For generating the build including the tests:
Electron supports ESM but [electron-mocha does not](https://github.com/jprichardson/electron-mocha/pull/187). It's capable of supporting it in the main thread but since Chrome does not provide any way to intercept calls to `import` it's unlikely to work with the renderer thread for the foreseeable future.

```bash
aegir build --esm-tests
```

## Lerna Monorepo

When using a lerna monorepo, local dependencies are symlinked by lerna on install. This means that an `esm` module will not use the resulting `dist` folder as symlink. This can become a problem if we are testing the `cjs` build of a module.

To work around the above problem, we can use `publishConfig.directory = "dist"` in `package.json` to notice lerna about the symlink path. After running the `aegir build` command, it is necessary to run `lerna link` to update the symlinks.

## Release

When releasing an `esm` module, the published content will be the generated `dist` folder content, as indicated by [ipjs](https://github.com/mikeal/ipjs).
We currently use a [fork of electron-mocha](https://www.npmjs.com/package/electron-mocha-main) that allows running ESM tests on the main thread but we have no support for running them on the renderer thread until the issues with Chrome and intercepting `import` above are resolved.

## Examples

TODO: List examples when merged (`ipfs-unixfs`, `uint8arrays`)
TODO: List examples when merged (`ipfs-unixfs`, `uint8arrays`)
46 changes: 23 additions & 23 deletions md/ts-jsdoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ Add types configuration to your package.json:
When a packages needs to allow type imports other than the entry point, you can use this workaround:
```json
"typesVersions": {
"*": {
"*": {
"src/*": [
"dist/src/*",
"dist/src/*",
"dist/src/*/index"
],
"src/": [
Expand All @@ -47,7 +47,7 @@ When a packages needs to allow type imports other than the entry point, you can
}
}
```
`typeVersions` will tell `tsc` where to look for every other files inside the `src` folder. Note: This might get smaller when this [issue](https://github.com/microsoft/TypeScript/issues/41284) is resolved or a proper way is introduced.
`typeVersions` will tell `tsc` where to look for every other files inside the `src` folder. Note: This might get smaller when this [issue](https://github.com/microsoft/TypeScript/issues/41284) is resolved or a proper way is introduced.

> Use this hack only if you really need it, this might change from the TS side at any time and break type checks.
Expand All @@ -67,9 +67,9 @@ Presets:
```
## Github Action

To run the typechecker in the CI you can use this action https://github.com/Gozala/typescript-error-reporter-action and you will get the errors reported inline with the code.
To run the typechecker in the CI you can use this action https://github.com/Gozala/typescript-error-reporter-action and you will get the errors reported inline with the code.

## Installing package from a git url
## Installing package from a git url
When installing a dependency from a git url (ie. PRs depending on other PRs) the types won't be packed in. To fix this you need to add a npm script called `prepare` to run `aegir build`.

```json
Expand All @@ -83,7 +83,7 @@ When installing a dependency from a git url (ie. PRs depending on other PRs) the

## 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.
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.

## Manage dependencies types
When dependencies don't publish types you have two options.
Expand All @@ -94,7 +94,7 @@ npm install @types/tape
```

### 2. Vendor type declarations
Create a `types` folder at the root of your project to keep all your vendored types. Inside create one folder per dependency using the dependency name as the folder name and inside a create `index.d.ts` file with the types.
Create a `types` folder at the root of your project to keep all your vendored types. Inside create one folder per dependency using the dependency name as the folder name and inside a create `index.d.ts` file with the types.

Tell TS where to look for types when a package doesn't publish them.
```json
Expand All @@ -110,9 +110,9 @@ Tell TS where to look for types when a package doesn't publish them.
]
```

> Scoped packages folder name need to use `__` instead of `/`, ie. the folder for `@pre-bundle/tape` would be `pre-bundle__tape`.
> Scoped packages folder name need to use `__` instead of `/`, ie. the folder for `@pre-bundle/tape` would be `pre-bundle__tape`.
Aegir will copy the types folder to the `dist` folder (ie. `dist/types`) when you build or run the types typescript preset. This way all your types, vendored and from source, will be published without broken imports.
Aegir will copy the types folder to the `dist` folder (ie. `dist/types`) when you build or run the types typescript preset. This way all your types, vendored and from source, will be published without broken imports.

Reference: https://github.com/voxpelli/types-in-js/discussions/7#discussion-58634

Expand All @@ -125,7 +125,7 @@ This list is a WIP, more rules will be added as we identify them.
When using `commonjs` modules, only use default exports when exporting a single `class`.

```js
// GOOD
// GOOD

class IPFS {}

Expand Down Expand Up @@ -166,14 +166,14 @@ module.exports = {
...
}

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

### 3. Use a `types.d.ts` file
When writing types JSDoc can sometimes 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.d.ts` file.
When writing types JSDoc can sometimes 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.d.ts` file.

```ts
// types.d.ts
Expand All @@ -185,7 +185,7 @@ export type IntersectionType = Type1 & Type2
/** @type { import('./types').IntersectionType } */
const list
```
You can also organise your source types in the same way as [vendored types](#vendor-type-declarations).
You can also organise your source types in the same way as [vendored types](#vendor-type-declarations).

Create a folder inside the `types` folder called `self` or the package name. Then you can import like you would a third party type.

Expand All @@ -203,14 +203,14 @@ Some TS tooling may have problems parsing comments if they are not very well div
// BAD - the base typedef can be parsed as a comment for Square
/**
*
* @typedef {import('./index') Base} Base
*
* @typedef {import('./index') Base} Base
*/

class Square {}


// GOOD
// GOOD
/** @typedef {import('./index') Base} Base */

/**
Expand All @@ -226,7 +226,7 @@ class Square {}
Check https://github.com/ipfs/community/pull/474

```js
'use strict'


const { Adapter, utils } = require('interface-datastore')
const fs = require('fs')
Expand All @@ -242,13 +242,13 @@ const fs = require('fs')
```

## Must read references
[10 Insights from Adopting TypeScript at Scale](https://www.techatbloomberg.com/blog/10-insights-adopting-typescript-at-scale/)
[Typescript official performance notes](https://github.com/microsoft/TypeScript/wiki/Performance)
[TypeScript: Don’t Export const enums](https://ncjamieson.com/dont-export-const-enums/)
[10 Insights from Adopting TypeScript at Scale](https://www.techatbloomberg.com/blog/10-insights-adopting-typescript-at-scale/)
[Typescript official performance notes](https://github.com/microsoft/TypeScript/wiki/Performance)
[TypeScript: Don’t Export const enums](https://ncjamieson.com/dont-export-const-enums/)
[TypeScript: Prefer Interfaces](https://ncjamieson.com/prefer-interfaces/)
[Typescript Narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html)

## Resources
[TS with JSDoc Discussions](https://github.com/voxpelli/types-in-js)
[Tackling Typescript](https://exploringjs.com/tackling-ts/toc.html)
[Effective Typescript](https://effectivetypescript.com/)
[TS with JSDoc Discussions](https://github.com/voxpelli/types-in-js)
[Tackling Typescript](https://exploringjs.com/tackling-ts/toc.html)
[Effective Typescript](https://effectivetypescript.com/)

0 comments on commit e3a4b45

Please sign in to comment.