2020-05-14 00:47:15 +02:00
< p align = "center" >
2021-02-26 22:07:23 +01:00
< img src = "https://user-images.githubusercontent.com/6702424/109354825-ab4b8e00-787e-11eb-8336-6009415ecaf6.png" >
2020-05-14 00:47:15 +02:00
< / p >
< p align = "center" >
2021-02-27 01:16:11 +01:00
< i > A template to assist you in creating and publishing TypeScript modules on NPM< / i >
2020-05-14 00:47:15 +02:00
< br >
< br >
< / p >
---
2021-02-27 22:38:43 +01:00
✅ NEW: `yarn` support You are now free to use `yarn` instead of `npm` if you'd like to.
2021-02-27 22:38:20 +01:00
✅ NEW: React ready ( `tsconfig.json` configured to transpile `.tsx` files).
2021-02-20 11:59:12 +01:00
2020-11-04 19:06:48 +01:00
# Presentation
2020-05-14 00:47:15 +02:00
2020-05-16 19:07:19 +02:00
This template automates the boring and tedious tasks of:
2020-05-15 22:51:31 +02:00
- Filling up the ``package.json` `
- Setting up Typescript.
2020-05-21 13:29:28 -05:00
- Writing a [README.md ](https://github.com/garronej/ts_ci/blob/master/README.template.md ) with decent presentation and instructions on how to install/import your module.
2020-10-23 02:53:24 +02:00
- Testing on multiple Node version running on Ubuntu and Windows before publishing.
2020-05-15 22:51:31 +02:00
- Maintaining a CHANGELOG.
2020-05-15 22:57:11 +02:00
- Publishing on NPM and creating corresponding GitHub releases.
2020-05-15 22:51:31 +02:00
2020-05-16 19:07:19 +02:00
Besides, good stuff that comes with using this template:
2020-05-22 16:39:33 +02:00
- No dist files are tracked on the ``master` ` branch.
2020-05-15 22:51:31 +02:00
- Shorter specific file import path.
``import {...} from "my_module/theFile"` ` instead of the usual
``import {...} from "my_module/dist/theFile"` `
- CDN distribution for importing from an ``.html`` file with a ``<script>` ` tag.
2020-05-15 22:57:11 +02:00
- A branch ``latest` ` always in sync with the latest release.
2020-05-26 14:16:26 +02:00
- When your users hit *"Go to Definition"* they get redirected to the actual ``.ts`` source file instead of the ``.d.ts` `.
( Feature disabled by default, refer to [instructions ](#enabling-go-to-definition-to-redirect-to-the-source-ts-file ) on how to enable it ).
2020-05-28 10:53:38 +02:00
- ESlint and Prettier are automatically run against files staged for commit. ( You can [disable ](#disable-linting-and-formatting ) this feature. )
2020-05-27 22:02:44 +02:00
2020-05-20 06:28:37 +02:00
If you want your module to support Deno as well checkout [denoify_ci ](https://github.com/garronej/denoify_ci ).
2020-05-17 20:02:43 +02:00
2020-05-26 14:21:55 +02:00
# Table of content
2020-10-23 00:09:59 +02:00
- [Presentation ](#presentation )
- [Table of content ](#table-of-content )
2020-05-26 14:21:55 +02:00
- [How to use ](#how-to-use )
- [Fork it ( click use the template ) ](#fork-it--click-use-the-template- )
- [Enable automatic publishing ](#enable-automatic-publishing )
- [Few things you need to be aware of before getting started ](#few-things-you-need-to-be-aware-of-before-getting-started )
- [Customization: ](#customization )
- [Changing the directories structure ](#changing-the-directories-structure )
- [Enabling "Go to Definition" to redirect to the source ``.ts`` file ](#enabling-go-to-definition-to-redirect-to-the-source-ts-file )
- [Swipe the image in the ``README.md`` ](#swipe-the-image-in-the-readmemd )
2020-05-27 22:02:44 +02:00
- [Disable linting and formatting ](#disable-linting-and-formatting )
- [Disable Prettier ](#disable-prettier )
- [Disable Eslint and Prettier altogether ](#disable-eslint-and-prettier-altogether )
2020-05-26 14:21:55 +02:00
- [Disable CDN build ](#disable-cdn-build )
- [Completely disable ](#completely-disable )
- [Only disable ES Module build ( ``dist/zz_esm/*`` ) ](#only-disable-es-module-build--distzz_esm- )
- [Remove unwanted dev dependencies ](#remove-unwanted-dev-dependencies )
- [Customizing the Badges ](#customizing-the-badges )
- [Accessing files outside the ``dist/`` directory ](#accessing-files-outside-the-dist-directory )
- [The automatically updated ``CHANGELOG.md`` ](#the-automatically-updated-changelogmd )
- [Video demo ](#video-demo )
- [Examples of auto-generated readme ](#examples-of-auto-generated-readme )
- [Creating a documentation website for your project ](#creating-a-documentation-website-for-your-project )
- [Creating a landing page for your project ](#creating-a-landing-page-for-your-project )
2020-05-15 22:51:31 +02:00
# How to use
## Fork it ( click use the template )
2020-11-04 19:48:07 +01:00
- Click on 
2020-05-16 19:07:19 +02:00
- The repo name you will choose will be used as a module name for NPM so:
2020-05-16 18:56:31 +02:00
- Be sure it makes for a valid NPM module name.
- Check if there is not already a NPM module named like that.
2021-02-20 11:45:22 +01:00
- The description you provide will be the one used on NPM and in ``package.json` ` ( you can change it later )
2020-05-15 22:51:31 +02:00
2020-10-23 00:09:59 +02:00
Once you've done that a GitHub action workflow will set up the ``README.md`` and the ``package.json` `
for you, wait a couple of minutes for it to complete ( a bot will push ). You can follow the job advancement in the "Action" tab.
2020-05-15 22:51:31 +02:00
2020-05-17 20:02:43 +02:00
Each time you will push changes ``npm test`` will be run on remote docker containers against multiple node versions if everything passes you will get a green ``ci` ` badges in your readme.
2020-05-15 22:51:31 +02:00
2020-05-17 20:02:43 +02:00
## Enable automatic publishing
2020-05-15 22:51:31 +02:00
2020-05-16 18:56:31 +02:00
Once you are ready to make your package available on NPM you
will need to provide two tokens so that the workflow can publish on your behalf:
2020-05-15 22:51:31 +02:00
Go to repository ``Settings`` tab, then ``Secrets` ` you will need to add two new secrets:
- ``NPM_TOKEN` `, you NPM authorization token.
- ``PAT` `, GitHub **P**ersonal **A**ccess **T**oken with the **repo** authorization. [link ](https://github.com/settings/tokens )
To trigger publishing edit the ``package.json`` ``version`` field ( ``0.0.0``-> ``0.0.1` ` for example) then push changes... that's all !
2020-05-16 18:56:31 +02:00
The publishing will actually be performed only if ``npm test` ` passes.
2020-05-15 22:51:31 +02:00
2020-05-19 04:52:25 +02:00
# Few things you need to be aware of before getting started
- The files to include in the NPM bundle are cherry-picked using the ``package.json`` ``files` ` field.
2020-08-18 17:06:44 +02:00
If you don't want to bother and includes everything just remove the ``files`` field from the ``package.json` `.
2021-02-27 22:36:28 +01:00
- If you are going to programmatically load files outside of the ``dist/`` directory ( like the ``package.json`` or files inside ``res/` ` ) be mindful that the paths might not be the one you expect. [Details ](#accessing-files-outside-the-dist-directory ).
2020-05-19 04:52:25 +02:00
- The template does not support ``.npmignore`` ( it use the safer ``package.json`` ``files` ` instead ).
- The template does not support ``.npmrc` `.
2020-05-16 19:07:19 +02:00
# Customization:
2020-05-15 22:51:31 +02:00
2020-05-26 14:16:26 +02:00
## Changing the directories structure
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-26 14:16:26 +02:00
All your source files must remain inside the ``src` ` dir, you can change how things are organized inside the source directory
but don't forget to update your ``package.json`` ``main``, ``type`` and ``files`` fields and ``tsconfig.esm.json`` ``include` ` field when appropriate.
2020-08-18 17:06:44 +02:00
< / details >
2020-05-26 14:16:26 +02:00
## Enabling "Go to Definition" to redirect to the source ``.ts`` file
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-26 14:16:26 +02:00
There is no denying that it is more convenient when clicking "Go To Definition" to get redirected to
a file ``.ts`` file rather than to a ``.d.ts` `.
To enable this feature simply point to the ``package.json``'s ``types`` filed to the ``main` `'s source
file instead the type definition file ``.d.ts` `.
For example you would replace:
```json
{
2020-08-25 02:53:10 +02:00
"main": "dist/index.js",
"types": "dist/index.d.ts",
2020-05-26 14:16:26 +02:00
}
```
by:
```json
{
2020-08-25 02:53:10 +02:00
"main": "dist/index.js",
"types": "src/index.ts",
2020-05-26 14:16:26 +02:00
}
```
Enabling this feature comes at a cost though. Be aware that if you use [optional chaining ](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining ) or [nullish coalescing ](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing ) for example, your module will only be importable
in projects using typescript 3.7 or newer ( version that introduces theses features ).
It is important to keep your project compatible with older TS version because
- You don't want to force your users to update the typescript version they use in their project,
updating typescript might break some other things in their code.
- In certain environments updating TypeScript is not an option. Take [Stackblitz ](https://stackblitz.com )
for example.
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< / details >
2020-05-16 19:07:19 +02:00
## Swipe the image in the ``README.md``
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-16 19:07:19 +02:00
A good way to host your repo image is to open an issue named ASSET in your project, close it, create a comment, drag and drop the picture you want to use and that's it. You have a link that you can replace in the ``README.md` `.
2020-05-15 22:51:31 +02:00
While you are at it submit this image as *social preview* in your repos github page's settings so that when you share on
2020-05-17 20:02:43 +02:00
Twitter or Reddit you don't get your GitHub profile picture to show up.
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< / details >
2020-05-27 22:02:44 +02:00
## Disable linting and formatting
### Disable Prettier
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-27 22:02:44 +02:00
[Prettier ](https://prettier.io ) is opinionated, it is OK to want to break free from it.
2021-02-27 22:36:28 +01:00
Remove these ``scripts`` from ``package.json` `:
2020-05-27 22:02:44 +02:00
- ``_format` `
- ``format` `
- ``format:check` `
Remove these ``package.json``'s ``devDependencies` `:
- ``prettier` `
- ``eslint-config-prettier` `
In the ``package.json``'s ``lint-staged`` field remove ``"*.{` s,json,md}": [ "prettier --write" ]``
From ``.eslintrc.js``, remove the line: ``"prettier/@typescript-eslint",` `.
Delete these files:
- ``.prettierignore` `
- ``.prettierrc.json` `
2020-05-27 22:20:34 +02:00
In ``.github/workflows/ci.yaml`` remove the line ``npm run format:check`` from the ``test_lint` ` job.
2020-05-27 22:02:44 +02:00
2020-08-18 17:06:44 +02:00
< / details >
2020-05-27 22:02:44 +02:00
### Disable Eslint and Prettier altogether
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-27 22:02:44 +02:00
Remove these ``package.json``'s ``scripts` `:
- ``_format` `
- ``format` `
- ``format:check` `
- ``lint:check` `
- ``lint` `
Remove these ``package.j` on``'s ``devDependencies` `:
- ``prettier` `
- ``eslint-config-prettier` `
- ``eslint` `
- ``@typescript-eslint/parser` `
- ``@typescript-eslint/eslint-plugin` `
- ``husky` `
2020-05-27 22:20:34 +02:00
Remove the ``lint-staged`` and ``husky`` fields from the ``package.json` `.
2020-05-27 22:02:44 +02:00
Delete these files:
- ``.prettierignore` `
- ``.prettierrc.json` `
- ``.eslintignore` `
- ``.eslintrc.js` `
2020-05-27 22:20:34 +02:00
In ``.github/workflows/ci.yaml`` remove the ``test_lint`` job and the line ``needs: test_lint` `.
2020-05-27 22:02:44 +02:00
2020-08-18 17:06:44 +02:00
< / details >
2020-05-26 14:09:15 +02:00
## Disable CDN build
### Completely disable
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-15 22:51:31 +02:00
If your project does not target the browser or if you are not interested in offering CDN distribution:
- Remove all ``cdn:*`` npm scripts and ``npm run cdn`` from the ` build` script ( in ``package.json` ` ).
- Remove ``./tsconfig.esm.json` `
- Remove ``simplifyify`` and ``terser` ` from dev dependencies.
2020-08-18 17:06:44 +02:00
< / details >
2020-05-26 14:09:15 +02:00
### Only disable ES Module build ( ``dist/zz_esm/*`` )
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-26 14:09:15 +02:00
If ``npm run build`` fail because ``tsc -p tsconfig.esm.json` ` gives errors you may want to remove the ESM
build but keep the ``bundle.js`` and ``bundle.min.js` `. To do that:
In ``package.json`` replace theses ``scripts` `:
```json
{
"cdn:bundle:.js": "simplifyify dist/index.js -s #{REPO_NAME}# -o dist/bundle.js --debug --bundle",
"cdn:bundle:.min.js": "terser dist/bundle.js -cmo dist/bundle.min.js",
"cdn:bundle": "npm run cdn:bundle:.js & & npm run cdn:bundle:.min.js",
"cdn:esm": "tsc -p tsconfig.esm.json",
"cdn": "npm run cdn:bundle & & npm run cdn:esm",
}
```
By theses ones:
```json
{
"cdn:.js": "simplifyify dist/index.js -s #{REPO_NAME}# -o dist/bundle.js --debug --bundle",
"cdn:.min.js": "terser dist/bundle.js -cmo dist/bundle.min.js",
"cdn": "npm run cdn:.js & & npm run cdn:.min.js",
}
```
Remove ``tsconfig.esm.json` `. ( file at the root of the project )
Edit the ``README.md` ` to remove instructions about how to
import as ES module.
2020-08-18 17:06:44 +02:00
< / details >
2020-05-17 20:02:43 +02:00
## Remove unwanted dev dependencies
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-16 19:07:19 +02:00
Dev dependencies that are not required by the template ( you can safely remove them if you don't use them ):
2020-05-15 22:51:31 +02:00
- ``evt` `
- ``@types/node` `
2020-05-17 20:02:43 +02:00
Must keep:
2020-05-15 22:51:31 +02:00
- ``typescript` `
- ``denoify` ` ( for the script that moves dist files to the root before publishing )
- ``simplifyify` ` ( for CDN build )
- ``terser` ` ( for CDN build )
2020-08-18 17:06:44 +02:00
< / details >
2020-05-15 23:06:13 +02:00
## Customizing the Badges
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-17 20:02:43 +02:00
You can use [shields.io ](https://shields.io ) to create badges on metrics you would like to showcase.
2020-08-18 17:06:44 +02:00
< / details >
2020-05-17 20:02:43 +02:00
# Accessing files outside the ``dist/`` directory
2020-05-15 22:51:31 +02:00
2020-08-18 17:06:44 +02:00
< details >
< summary > Click to expand< / summary >
2020-05-15 22:51:31 +02:00
The drawback of having short import path is that the dir structure
is not exactly the same in production ( in the npm bundle ) and in development.
The files and directories in ``dist/` ` will be moved to the root of the project.
As a result this won't work in production:
``src/index.ts` `
2020-05-14 00:47:15 +02:00
```typescript
2020-05-15 22:51:31 +02:00
import * as fs from "fs";
import * as path from "path";
const str = fs.readFileSync(
2020-05-18 04:57:35 +02:00
path.join(__dirname,"..", "package.json")
2020-05-15 22:51:31 +02:00
).toString("utf8");
2020-05-14 00:47:15 +02:00
```
2020-05-15 22:51:31 +02:00
Because ``/dist/index.js`` will be moved to ``/index.js` `
2020-05-14 00:47:15 +02:00
2020-05-15 22:51:31 +02:00
You'll have to do:
2020-05-14 00:47:15 +02:00
2020-05-15 22:51:31 +02:00
``src/index.ts` `
```typescript
import * as fs from "fs";
import * as path from "path";
import { getProjectRoot } from "./tools/getProjectRoot";
2020-05-14 00:47:15 +02:00
2020-05-15 22:51:31 +02:00
const str = fs.readFileSync(
path.join(getProjectRoot(),"package.json")
).toString("utf8");
```
2020-05-14 00:47:15 +02:00
2020-08-18 17:06:44 +02:00
< / details >
2020-05-26 14:21:55 +02:00
# The automatically updated ``CHANGELOG.md``
2020-05-24 09:56:06 +02:00
Starting from the second release, a ``CHANGELOG.md` ` will be created at the root of the repo.
*Example:*

The ``CHANGELOG.md` ` is built from the commits messages since last release.
Are NOT included in the ``CHANGELOG.md` `:
- The commit messages that includes the word "changelog" ( non-case sensitive ).
- The commit messages that start with "Merge branch ".
- The commit messages that with "GitBook: "
*The GitHub release will point to a freezed version of the ``CHANGELOG.md` `*:

2020-05-16 12:27:26 +02:00
# Video demo
[](https://youtu.be/Q5t-yP2PvPA)
2020-05-26 14:21:55 +02:00
# Examples of auto-generated readme
2020-05-16 13:53:39 +02:00
2020-05-20 05:49:45 +02:00

2020-05-15 22:51:31 +02:00
2020-05-26 14:21:55 +02:00
# Creating a documentation website for your project
2020-05-17 20:04:08 +02:00
I recommend [GitBook ](https://www.gitbook.com ), It enables you to write your documentation in markdown from their
2020-05-19 04:52:25 +02:00
website and get the markdown files synchronized with your repo.
2020-05-17 20:04:08 +02:00
They will provide you with a nice website for which you can customize the domain name.
All this is covered by their free tier.
Example:
- [repo ](https://github.com/garronej/evt )
- [GitBook documentation website ](https://docs.evt.land )
I advise you to have a special directory at the root of your project where the markdown documentation files
2020-05-19 15:48:02 +02:00
are stored. It is configured by placing a ``.gitbook.yaml` ` file at the root of the repo containing, for example:
2020-11-04 19:24:20 +01:00
``root: ./docs/` `
Do not hesitate to request free access to premium features. Open source projects are eligible!
2020-05-17 20:04:08 +02:00
PS: I am not affiliated with GitBook in any way.
2020-05-15 22:51:31 +02:00
2020-05-26 14:21:55 +02:00
# Creating a landing page for your project
2020-05-17 20:04:08 +02:00
Beside the documentation website, you might want to have a catchy landing page to share on social networks.
You can use [GitHub pages ](https://pages.github.com ) to host it.
If you like the landing page of EVT, [evt.land ](http://evt.land ), you can fork the [repo ](https://github.com/garronej/evt.land ) and adapt it for your module.
2020-05-24 07:27:38 +02:00
To produce high quality GIF from screen recording that remain relatively small checkout the wonderful [Gifski ](https://gif.ski ) from [Sindre Sorhus ](https://github.com/sindresorhus ).
Once your page is ready you'll just have to go to settings and enable Pages yo put it online.
2020-05-17 20:04:08 +02:00

And update your DNS:

I personally use [Hurricane Electric ](https://dns.he.net ) free DNS servers because they support a lot of record types.
2020-05-19 19:43:16 +02:00
However, if your DNS provider does not support ``ALIAS``, you can use ``A` ` records and manually enter the IP of GitHub servers.
2020-05-17 20:04:08 +02:00
I let you consult the [GitHub Pages Documentation ](https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site#configuring-an-apex-domain ).