Making npm packages, typedoc, storybook

Posted on October 2, 2021
Tags: javascript

Just look at the github repos:

1 Setup

This will install the tools globally

npm install -g @microsoft/api-documenter
npm install -g @microsoft/api-extractor

2 Instruction

Go to your folder’s tsconfig.json and add the three

{
  "$schema": "http://json.schemastore.org/tsconfig",
  "compilerOptions": {
    ...
    "declaration": true,
    "sourceMap": true,
    "declarationMap": true,
api-extractor init

This will generate our api-extractor.json

FIND PATH OF THE index.d.ts YOU WANT TO EXTRACT

In our example we found 1 of many index.d.ts’s in ./packages/next/index.d.ts

Add "typings" : "{PATH TO index.d.ts}" to your package.json (Shown below)
BUT if you’re documenting a repo that already pregenerated it’s typings you dont have to modify package.json.

{
  "name": "Bleh",
  "version": "1.0.0",

  "typings": "./packages/next/index.d.ts"
}

Run npm run tsc to generate the typings.

The path of our chosen index.d.ts is in ./packages/next/index.d.ts

  "mainEntryPointFilePath": "<projectFolder>/packages/next/index.d.ts",

Note some repos can have multiple index.d.ts which is the case in nextjs so we just choose one of them in the folders as the path.

2.1 mkdir

mkdir etc

2.2 running

api-extractor run --local --verbose

API extractor generates a temp folder with *.api.json and *.md files

mkdir mydocs
mkdir mydocs/input 
mkdir mydocs/markdown
cp temp/*.api.json mydocs/input/
cp temp/*.md mydocs/markdown/

cd mydocs
api-documenter markdown
  • drag temp/*.api.json files into mydocs/input
  • drag temp/*.md files into mydocs/markdown

Alternatively you can just run this command below in project folder

rm -r etc && rm -r mydocs && rm -r temp && mkdir etc && api-extractor run --local --verbose && mkdir mydocs && mkdir mydocs/input && mkdir mydocs/markdown && cp temp/*.api.json mydocs/input/ && cp temp/*.md mydocs/markdown/ && api-documenter markdown -i mydocs/markdown
rm -r etc && rm -r mydocs && rm -r temp

3 Typedoc

typedoc --entryPoints ./dist/uPlot.d.ts

4 next

npm install typedoc --save-dev
npx typedoc --version

4.1 using typedoc on nextjs

pnpm install @vercel/cc -w
pnpm install -D microbundle -w

5 typedoc

Example file structure

  "scripts": {
    "build": "npm run clean && tsc",
    "clean": "tsc --build --clean",
    "cleandoc": "rm -r docs",
    "doc": "typedoc --entryPointStrategy resolve .",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
npm install --save-dev typedoc-plugin-missing-exports
npm install --save-dev typedoc-umlclass
npm install typedoc
typedoc .
// is the same as the line below; default strategy is `resolve`
typedoc --entryPointStrategy resolve --entryPoints .

This will document basically exactly what you ened * Your index.ts generated index.d.ts (REMEMBER: if you dont export the variable the types wont be generated)

Right now there is no way to generate EXACTLY the types of your files and it’s dependencies WITHOUT documenting all of the node_modules.


Document your 1 main file generated index.d.ts

typedoc .
// is the same as the line below; default strategy is `resolve`
typedoc --entryPointStrategy resolve --entryPoints .

Document our generated index.d.ts and our manually created customtypes.d.ts without documenting the other node_modules.

In tsconfig.json, Compiler options can be anything since our --exclude option will override it. (this means we can do "skipLibCheck": true, with "typeRoots" : [ "node_modules/@types"] in tsconfig which will be ignored by typedoc due to exclude option)

typedoc --exclude 'node_modules/**/*.ts' --entryPointStrategy expand --entryPoints .

Alternatively

"skipLibCheck": true,
"typeRoots" : [],
// DO NOT SET typeRoots as --> // "typeRoots" : [ "node_modules/@types"]
typedoc --expand --entryPoints .

Document including types from node_modules

In tsconfig.json, Compiler options

// "skipLibCheck": true or false doesnt really matter
"typeRoots" : [ "node_modules/@types"]
typedoc --entryPointStrategy expand --entryPoints .

This may be useful if you use use types from node_modules dependencies but the downside is you cant force it to only choose dependencies that your code uses, so it documents types from all dependencies.

6 Webpack npm package

https://github.com/userJY/npmFrontendTemplateWebpack

npm install --save-dev typedoc-plugin-missing-exports
npm install --save-dev typedoc-umlclass
npm install typedoc
* repo
  * package.json
  * tsconfig.json
  * webpack.config.js
  * lib    <---- `path: path.resolve(__dirname, 'lib'),` output used for publishing
    * demo
      * index.html   <--- `filename: path.resolve('lib', 'demo','index.html'),` HTMLWebpackPlugin input (3)
    * @types    <----`{ from: "src/@types", to: "@types" },` CopyPlugin output (5)
      * custom.d.ts  
    * index.d.ts <--- Generated from typescript declarations
    * index.js  <---- `filename: 'index.js',` (2)
  * src
    * @types   <----`{ from: "src/@types", to: "@types" },` CopyPlugin input (5)
      * custom.d.ts  
    * template.html <---- ` template: path.resolve('src','template.html') ` HTMLWebpackPlugin input (4)
    * index.ts  <-- `index: path.resolve(__dirname, 'src', 'index.ts'),`  (1)

{.js webpack.config.js} module.exports = { mode: 'development', entry: { index: path.resolve(__dirname, 'src', 'index.ts'), // (1) }, output: { path: path.resolve(__dirname, 'lib'), filename: 'index.js', // (2) clean: true, assetModuleFilename: '[name][ext]' }, ..., plugins : [ new HTMLWebpackPlugin({ bleh: "Webpack App", filename: path.resolve('lib', 'demo','index.html'), // (3) template: path.resolve('src','template.html') // (4) }), new CopyPlugin({ patterns: [ { from: "src/@types", to: "@types" }, // (5) ], }), ], devServer: { static: { directory: path.resolve(__dirname,'lib', 'demo') }, ... }, }

package.json

  "main": "./lib/index.js",
  "types": "./lib/index.d.ts",
  "files": [
    "lib/**/*"
  ],
  "scripts": {
    "build": "webpack",
    "dclean": "rm -rf docs",
    "doc": "rm -rf docs && typedoc --entryPointStrategy resolve ./src/index.ts",
    "dev": "npm run clean && webpack && webpack serve --https",
    "clean": "tsc --build --clean",
    "publish" : "npm run build && rm -rf lib/demo && npm run doc && npm publish",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
{
  "compilerOptions": {
        /* Basics */
    "outDir": "./lib", /* output dir of emitted js files */
    "declaration": true, /*Generate *.d.ts files*/
    ...
    "skipLibCheck": true, /* skips checking *.d.ts of ALL node_modules/@types BUT type-checks if app depends on the module */
    "typeRoots": ["src/@types","node_modules/@types"], /*List of folder to include type definition, default is `node_modules/@types/ */
  },

  //Generally, include source directory; exclude distribution directory
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"], /* Specifies an array of filenames or patterns to include in the program. */
  "exclude": ["lib","node_modules", "doc", "jest.config.ts", "**/*.spec.ts"]  /* Specifies an array of filenames or patterns that should be skipped when resolving "include":[..] above */

}
{
    "$schema": "https://typedoc.org/schema.json",
    "entryPoints": ["./pages/*.tsx"],
    "out": "docs"
}

7 View typedoc

npm install browser-sync --save-dev
"viewdocs": "browser-sync start --server 'docs'",