├── .husky ├── .gitignore ├── pre-push └── pre-commit ├── example ├── .env.environment ├── package.json ├── src │ └── index.js ├── README.md └── package-lock.json ├── config ├── .syncpackrc ├── .prettierrc ├── typedoc.json ├── tsup.config.ts ├── .eslintrc.cjs └── jest.config.ts ├── arts ├── generate-access-token-npmjs.png ├── create-secret-variable-for-individual.png ├── create-secret-variable-for-organization.png └── grant-github-actions-read-and-write-permissions.png ├── tests ├── add.test.ts ├── mul.test.ts ├── dummy.test.ts └── setup │ └── setup-jest-mock-3rds.ts ├── src └── index.ts ├── .gitignore ├── tsconfig.json ├── CONFIG.md ├── LICENSE ├── .github └── workflows │ ├── gendoc.yml │ ├── ci.yml │ └── publish.yml ├── package.json └── README.md /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /example/.env.environment: -------------------------------------------------------------------------------- 1 | CUSTOM_NAME=Example -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run test 5 | -------------------------------------------------------------------------------- /config/.syncpackrc: -------------------------------------------------------------------------------- 1 | { 2 | "source": ["package.json", "packages/*/package.json"] 3 | } -------------------------------------------------------------------------------- /arts/generate-access-token-npmjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playground/npm-template-typescript/main/arts/generate-access-token-npmjs.png -------------------------------------------------------------------------------- /arts/create-secret-variable-for-individual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playground/npm-template-typescript/main/arts/create-secret-variable-for-individual.png -------------------------------------------------------------------------------- /config/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true, 6 | "useTabs": false 7 | } 8 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | # Fix lint with prettier 5 | npx lint-staged 6 | # Verify lint again with eslint 7 | npm run lint -------------------------------------------------------------------------------- /arts/create-secret-variable-for-organization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playground/npm-template-typescript/main/arts/create-secret-variable-for-organization.png -------------------------------------------------------------------------------- /config/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": ["../src/index.ts"], 3 | "out": "../docs", 4 | "exclude": ["**/*.test.ts"], 5 | "includeVersion": true 6 | } 7 | -------------------------------------------------------------------------------- /tests/add.test.ts: -------------------------------------------------------------------------------- 1 | import { add } from '../src'; 2 | 3 | test('adds two numbers correctly', () => { 4 | const result = add(2, 3); 5 | expect(result).toBe(5); 6 | }); 7 | -------------------------------------------------------------------------------- /arts/grant-github-actions-read-and-write-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/playground/npm-template-typescript/main/arts/grant-github-actions-read-and-write-permissions.png -------------------------------------------------------------------------------- /tests/mul.test.ts: -------------------------------------------------------------------------------- 1 | import { mul } from '../src'; 2 | 3 | test('multiply two numbers correctly', () => { 4 | const result = mul(2, 3); 5 | expect(result).toBe(6); 6 | }); 7 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export function add(a: number, b: number): number { 2 | return a + b; 3 | } 4 | 5 | export function mul(a: number, b: number): number { 6 | return a * b; 7 | } 8 | -------------------------------------------------------------------------------- /tests/dummy.test.ts: -------------------------------------------------------------------------------- 1 | // Dummy test as placeholder to comply with npm run test 2 | // We can keep this file if you are not go with TDD approach first 3 | 4 | test('Dummy test multiply two numbers correctly', () => { 5 | const result = 2 * 3; 6 | expect(result).toBe(6); 7 | }); 8 | -------------------------------------------------------------------------------- /config/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.ts'], 5 | format: ['cjs', 'esm'], // Build for commonJS and ESmodules 6 | dts: true, // Generate declaration file (.d.ts) 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | }); 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Dependency directory 7 | node_modules 8 | 9 | # Optional npm cache directory 10 | .npm 11 | 12 | # History of installed package 13 | *.lock 14 | 15 | build/ 16 | .DS_Store 17 | .nvmrc # this breaks circleci builds 18 | .idea/ 19 | .env 20 | .nvmrc 21 | 22 | # coverage 23 | artifacts/ 24 | .nyc_output 25 | 26 | # Ignore test-related files 27 | /coverage.data 28 | /coverage/ 29 | 30 | # Build files 31 | /dist 32 | /docs 33 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node18/tsconfig.json", 3 | "compilerOptions": { 4 | "preserveConstEnums": true, 5 | "lib": ["DOM", "ESNext"], 6 | "baseUrl": "./", 7 | "rootDir": "./src", 8 | "module": "ESNext", 9 | "moduleResolution": "bundler", 10 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"], 14 | } 15 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.1.0", 4 | "description": "example use the npm package", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo 'example testing a customized npm package on local'", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "Le Ngoc Duy", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@askbills/npm-template-typescript": "file:..", 14 | "dotenv": "^16.4.5" 15 | }, 16 | "type": "module" 17 | } 18 | -------------------------------------------------------------------------------- /example/src/index.js: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { add } from '@askbills/npm-template-typescript'; 3 | 4 | function showResultSumOf(a, b) { 5 | return `@askbills/npm-template-typescript: Sum of ${a} + ${b} = ${add(a, b)} `; 6 | } 7 | 8 | console.log(showResultSumOf(7, 3)); 9 | if (process.env.CUSTOM_NAME) { 10 | console.log(`[Dotenv] CUSTOM_NAME = ${process.env.CUSTOM_NAME}`); 11 | } else { 12 | console.log( 13 | "[Dotenv] Clone '.env.environment' to '.env' and replace the variables values accordingly to configure your variables", 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /CONFIG.md: -------------------------------------------------------------------------------- 1 | # Configure necessary credentials once you are ready for release 2 | 3 | 1. Generate a Granular Access Token on [npmjs.com](https://www.npmjs.com/) ![NPM_TOKEN](./arts/generate-access-token-npmjs.png) 4 | 2. Configure in your repository's secret variables 5 | 1. Individual level ![Individual](./arts/create-secret-variable-for-individual.png) 6 | 2. Organization level to share across repositories on-demand ![Organization](./arts/create-secret-variable-for-organization.png) 7 | 3. Grant `Read and write permissions` to allow Github Actions publish | update github package ![Grant](./arts/grant-github-actions-read-and-write-permissions.png) 8 | -------------------------------------------------------------------------------- /config/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | tsconfigRootDir: __dirname, 5 | sourceType: 'module', 6 | }, 7 | plugins: ['@typescript-eslint/eslint-plugin', 'import'], 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:prettier/recommended', 11 | ], 12 | root: true, 13 | env: { 14 | node: true, 15 | jest: true, 16 | }, 17 | ignorePatterns: ['.eslintrc.js', '**/*.test.ts'], 18 | rules: { 19 | '@typescript-eslint/interface-name-prefix': 'off', 20 | '@typescript-eslint/explicit-function-return-type': 'error', 21 | '@typescript-eslint/explicit-module-boundary-types': 'warn', 22 | '@typescript-eslint/no-explicit-any': 'error', 23 | '@typescript-eslint/no-non-null-assertion': 'error', 24 | 'prettier/prettier': [ 25 | 'error', 26 | { 27 | tabWidth: 4, 28 | }, 29 | ], 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /config/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'jest'; 2 | 3 | const config: Config = { 4 | rootDir: '../', 5 | moduleFileExtensions: ['ts', 'json', 'js'], 6 | setupFiles: ['./tests/setup/setup-jest-mock-3rds.ts'], 7 | testTimeout: 3000, 8 | verbose: true, 9 | preset: 'ts-jest', 10 | testEnvironment: 'node', 11 | bail: 1, 12 | testRegex: '.*\\.test\\.ts$', 13 | notify: true, 14 | collectCoverage: true, 15 | coverageDirectory: './coverage', 16 | collectCoverageFrom: ['./src/*.{ts,js,jsx}'], 17 | coverageThreshold: { 18 | global: { 19 | branches: 80, // The number of the branches of the control structures, like if-then, that have been executed. 20 | functions: 80, // The number of functions that have been called. 21 | lines: 80, // The number of lines of source code that have been tested. a Line can have multiply statements e.g. const a = 1; b = 2; 22 | statements: 80, // The number of statements that have been executed. 23 | }, 24 | }, 25 | }; 26 | 27 | export default config; 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 make-everything-simple 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/gendoc.yml: -------------------------------------------------------------------------------- 1 | # Generate and deploy documentation to branch `gh-pages` on-demand. We can switch to auto trigger after each release if needed. Please configure your Github Page point to branch `gh-pages` 2 | name: Generate Doc 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | branch: 8 | description: 'Branch to generate Doc for' 9 | required: true 10 | default: 'main' # Default to main branch 11 | 12 | jobs: 13 | gen-doc: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: write 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v4 21 | 22 | - name: Install dependencies 23 | run: npm install # Or yarn install 24 | 25 | - name: Generate TypeDoc 26 | run: npm run docs:build 27 | 28 | - name: Deploy to GitHub Pages 29 | uses: peaceiris/actions-gh-pages@v3 30 | with: 31 | github_token: ${{ secrets.GITHUB_TOKEN }} 32 | publish_dir: ./docs # Or the directory specified in your typeDoc config 33 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | As a best-practice, we always verify our package before publishing your package to the NPM registry it is important to publish it and test it on your local machine to ensure its correctness, functionality, and compatibility with other modules or dependencies. Local testing allows you to catch any issues or bugs early on and make necessary improvements before releasing your package to the public. That's why example come in to let us can verify our customized package 4 | 5 | ## How to verify your customized package on your local machine 6 | 7 | ### Reuse the `example` in our case 8 | 9 | Trigger start to install the local package and run your logic inside `index.js` 10 | 11 | ```bash 12 | npm run start 13 | ``` 14 | 15 | ### To verify a new testing_project 16 | 17 | 1. First, create a new testing project e.g `testing_project` 18 | 2. Run `$ cd testing_project` 19 | 3. Run `$ npm init` and initialize your package with default entry file `index.ts | index.js` 20 | 4. Link the dir of your dependency `$ npm link path_to_local_package` 21 | 5. Install the local npm package in development mode `$ npm install path_to_local_package` 22 | 6. Implement your code logic that reuse functionalities of your npm local package 23 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Enforce your MR | commit must follow best-practices: lint -> build -> test 2 | name: Verify-Commit 3 | run-name: Verify PR merge to ${{ github.base_ref }} by @${{ github.actor }} 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | pull_request: 9 | branches: 10 | - main 11 | - 'releases/**' 12 | push: 13 | branches: 14 | - main 15 | - 'releases/**' 16 | 17 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 18 | jobs: 19 | # This workflow contains a single job called "verify" 20 | verify: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | # Setup .npmrc file to publish to npm 25 | - uses: actions/setup-node@v4 26 | with: 27 | node-version: 18 28 | - name: Install dependencies 29 | run: npm ci 30 | - name: Verify Lint 31 | run: npm run lint 32 | - name: Build package 33 | run: npm run build 34 | - name: Verify Unit test 35 | run: npm run test 36 | -------------------------------------------------------------------------------- /tests/setup/setup-jest-mock-3rds.ts: -------------------------------------------------------------------------------- 1 | // mock you implementation module. e.g. 2 | /* 3 | jest.mock('newrelic'); 4 | jest.mock('@aws-sdk/client-ssm', () => { 5 | const originalModule = jest.requireActual('@aws-sdk/client-ssm'); 6 | return { 7 | ...originalModule, 8 | SSMClient: function () { 9 | return { 10 | send: function ({ parameter }) { 11 | { 12 | return { 13 | promise: function () { 14 | return { 15 | Parameter: { 16 | Name: parameter, 17 | Type: 'String', 18 | Value: '100', 19 | Version: 1, 20 | LastModifiedDate: 21 | '2023-03-06T07:09:53.758Z', 22 | ARN: 'arn:aws:ssm:us-east-1:xxxx:parameter/npm-template-typescript/dev/NPM_TOKEN', 23 | DataType: 'text', 24 | }, 25 | }; 26 | }, 27 | }; 28 | } 29 | }, 30 | }; 31 | }, 32 | }; 33 | }); 34 | */ 35 | -------------------------------------------------------------------------------- /example/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "example", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@askbills/npm-template-typescript": "file:..", 13 | "dotenv": "^16.4.5" 14 | } 15 | }, 16 | "..": { 17 | "name": "@make-everything-simple/npm-template-typescript", 18 | "version": "1.0.3", 19 | "license": "MIT", 20 | "devDependencies": { 21 | "@tsconfig/node18": "^18.2.2", 22 | "@types/jest": "^29.5.11", 23 | "@typescript-eslint/eslint-plugin": "^6.20.0", 24 | "eslint": "^8.56.0", 25 | "eslint-config-prettier": "^9.1.0", 26 | "eslint-plugin-import": "^2.29.1", 27 | "eslint-plugin-prettier": "^5.1.3", 28 | "husky": "^9.0.10", 29 | "jest": "^29.7.0", 30 | "lint-staged": "^15.2.1", 31 | "node-notifier": "^10.0.1", 32 | "prettier": "3.2.4", 33 | "rimraf": "^5.0.5", 34 | "ts-jest": "^29.1.2", 35 | "ts-node": "^10.9.2", 36 | "tsup": "^8.0.1", 37 | "typescript": "^5.3.3" 38 | }, 39 | "engines": { 40 | "node": ">=18.0.0" 41 | } 42 | }, 43 | "../../../../../../../Users/duylengoc/.nvm/versions/node/v18.19.0/lib/node_modules/example": { 44 | "version": "0.0.0", 45 | "extraneous": true, 46 | "license": "jetaime_mk108@yahoo.com" 47 | }, 48 | "node_modules/@askbills/npm-template-typescript": { 49 | "resolved": "..", 50 | "link": true 51 | }, 52 | "node_modules/dotenv": { 53 | "version": "16.4.5", 54 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", 55 | "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", 56 | "engines": { 57 | "node": ">=12" 58 | }, 59 | "funding": { 60 | "url": "https://dotenvx.com" 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Release & Publish 2 | 3 | on: 4 | push: 5 | # Sequence of patterns matched against refs/tags 6 | tags: 7 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 8 | permissions: write-all 9 | 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | with: 17 | # Number of commits to fetch. 0 indicates all history for all branches and tags. 18 | fetch-depth: 0 19 | - name: Changelog 20 | uses: Bullrich/generate-release-changelog@master 21 | id: Changelog 22 | env: 23 | REPO: ${{ github.repository }} 24 | - name: Create Release 25 | id: create_release 26 | uses: actions/create-release@latest 27 | env: 28 | # https://docs.github.com/en/actions/security-guides/automatic-token-authentication 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | with: 31 | tag_name: ${{ github.ref }} 32 | release_name: Release ${{ github.ref }} 33 | body: | 34 | ${{ steps.Changelog.outputs.changelog }} 35 | draft: false 36 | prerelease: false 37 | 38 | publish: 39 | strategy: 40 | matrix: 41 | os: [ubuntu-latest] 42 | version: [18] 43 | runs-on: ${{ matrix.os }} 44 | steps: 45 | - uses: actions/checkout@v4 46 | # Setup .npmrc file to publish to npm 47 | - uses: actions/setup-node@v4 48 | with: 49 | node-version: ${{ matrix.version }} 50 | registry-url: 'https://registry.npmjs.org' 51 | scope: '@make-everything-simple' 52 | always-auth: 'true' 53 | env: 54 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} 55 | - name: show npm config 56 | run: cat $NPM_CONFIG_USERCONFIG 57 | - name: verify npm cache 58 | run: npm cache verify 59 | - name: Install dependencies 60 | run: npm ci 61 | - name: Build package 62 | run: npm run build 63 | - name: Publish package to NPM registry 64 | run: npm publish --access public 65 | - uses: actions/setup-node@v4 66 | with: 67 | node-version: ${{ matrix.version }} 68 | registry-url: 'https://npm.pkg.github.com' 69 | scope: '@make-everything-simple' 70 | - name: Publish package to NPM registry 71 | run: npm publish --access public 72 | env: 73 | NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@make-everything-simple/npm-template-typescript", 3 | "description": "Typescript template to build npm package", 4 | "version": "1.0.4", 5 | "author": "make-everything-simple", 6 | "bugs": "https://github.com/make-everything-simple/npm-template-typescript/issues", 7 | "devDependencies": { 8 | "@tsconfig/node18": "^18.2.2", 9 | "@types/jest": "^29.5.11", 10 | "@typescript-eslint/eslint-plugin": "^6.20.0", 11 | "eslint": "^8.56.0", 12 | "eslint-config-prettier": "^9.1.0", 13 | "eslint-plugin-import": "^2.29.1", 14 | "eslint-plugin-prettier": "^5.1.3", 15 | "http-server": "^14.1.1", 16 | "husky": "^9.0.10", 17 | "jest": "^29.7.0", 18 | "lint-staged": "^15.2.1", 19 | "node-notifier": "^10.0.1", 20 | "prettier": "3.2.4", 21 | "rimraf": "^5.0.5", 22 | "syncpack": "^13.0.0", 23 | "ts-jest": "^29.1.2", 24 | "ts-node": "^10.9.2", 25 | "tsup": "^8.0.1", 26 | "typedoc": "^0.26.6", 27 | "typescript": "^5.3.3" 28 | }, 29 | "engines": { 30 | "node": ">=18.0.0" 31 | }, 32 | "files": [ 33 | "dist" 34 | ], 35 | "homepage": "https://github.com/make-everything-simple/npm-template-typescript#readme", 36 | "keywords": [ 37 | "npm", 38 | "npm-typescript", 39 | "package-template", 40 | "template" 41 | ], 42 | "license": "MIT", 43 | "lint-staged": { 44 | "**/*": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"config/**/*\" --config config/.prettierrc --ignore-unknown" 45 | }, 46 | "main": "./dist/index.js", 47 | "module": "./dist/index.mjs", 48 | "repository": "make-everything-simple/npm-template-typescript.git", 49 | "scripts": { 50 | "build": "tsup --config ./config/tsup.config.ts", 51 | "docs:build": "typedoc --options ./config/typedoc.json", 52 | "docs:serve": "npm run docs:build && http-server ./docs --cors -p 8080 -c-1", 53 | "lint": "eslint \"{src,tests}/**/*.ts\" --config ./config/.eslintrc.cjs", 54 | "lint:fix": "npm run lint -- --fix", 55 | "prebuild": "rimraf dist", 56 | "prepare": "husky install", 57 | "pretest": "rimraf coverage", 58 | "prettier:format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"config/**/*\" --config config/.prettierrc", 59 | "start": "npm run build && node dist/index.js", 60 | "start:watch": "tsup src/index.ts --config ./config/tsup.config.ts --watch --onSuccess 'node dist/index.js'", 61 | "syncpack:check": "yarn syncpack list-mismatches --config ./config/.syncpackrc", 62 | "syncpack:fix": "yarn syncpack fix-mismatches --config ./config/.syncpackrc", 63 | "syncpack:format": "yarn syncpack format --config ./config/.syncpackrc", 64 | "test": "jest --config ./config/jest.config.ts" 65 | }, 66 | "type": "module", 67 | "types": "./dist/index.d.ts" 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # npm-template-typescript 2 | 3 | [![Build Status](https://github.com/make-everything-simple/npm-template-typescript/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/make-everything-simple/npm-template-typescript//actions/workflows/ci.yml?query=branch%3Amain) 4 | [![Release Status](https://github.com/make-everything-simple/npm-template-typescript/actions/workflows/publish.yml/badge.svg)](https://github.com/make-everything-simple/npm-template-typescript//actions/workflows/publish.yml) 5 | [![NPM Version](https://badgen.net/npm/v/@make-everything-simple/npm-template-typescript)](https://npmjs.org/package/@make-everything-simple/npm-template-typescript) 6 | [![NPM Install Size](https://badgen.net/packagephobia/install/@make-everything-simple/npm-template-typescript)](https://packagephobia.com/result?p=@make-everything-simple%2Fnpm-template-typescript) 7 | [![NPM Downloads](https://badgen.net/npm/dm/@make-everything-simple/npm-template-typescript)](https://npmcharts.com/compare/@make-everything-simple/npm-template-typescript?minimal=true) 8 | 9 | Let developers who publish libraries via npm share with the team or community quicker. Less time to set up utility tools to follow best practices, and more time on the core features of the package 10 | 11 | ## This package template supports us 12 | 13 | 1. **Customize configuration**: eslint, prettier, jest, typescript 14 | 2. **Git hook**: ensure your code is qualified with lint when committing and test when pushing from your early stage on your local machine 15 | 3. **CI jobs**: trigger on `each PR` or `Push event` to ensure jobs `Lint -> Build -> Test` are verified 16 | 4. **CD (publish) jobs**: trigger when a `new tag` is pushed 17 | 1. Create a new release based on your commit messages like [this](https://github.com/make-everything-simple/npm-template-typescript/releases) 18 | 2. Publish the npm package to npmjs like [this](https://www.npmjs.com/package/@make-everything-simple/npm-template-typescript) 19 | 3. Create | Update the Github page like [this](https://github.com/make-everything-simple/npm-template-typescript/pkgs/npm/npm-template-typescript) 20 | 5. Documentation Generator for Typescript. 21 | 22 | ## Prerequisites 23 | 24 | The following tools need to be installed: 25 | 26 | 1. [Git](http://git-scm.com/) 27 | 2. [Node.js 18+](http://nodejs.org/) 28 | 29 | ## Capabilities and Frameworks 30 | 31 | | Capability | Module | 32 | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 33 | | Dependence Framework | [`@tsconfig/node18`](https://www.npmjs.com/package/@tsconfig/node18) extend ts config node18+, [typescript](https://www.npmjs.com/package/typescript) adds optional types to JavaScript that support tools for large-scale JavaScript applications | 34 | | Build Tools | [`tsup`](https://tsup.egoist.dev) Bundle your TypeScript library with no config, powered by esbuild | 35 | | Coding Standard | [eslint](https://eslint.org/) statically analyzes your code to quickly find and fix problems based on opt-in [rules](https://eslint.org/docs/latest/rules/), [prettier](https://prettier.io/docs/en/) an opinionated code formatter to build and enforce a style guide on save, [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) to turns off all rules that are unnecessary or might conflict with Prettier. | 36 | | Testing Framework | [Jest](https://jestjs.io/) a delightful JavaScript Testing Framework with a focus on simplicity. | 37 | | Documentation Generator | [TypeDoc](https://typedoc.org/guides/overview/) is a documentation generator for TypeScript, [http-server](https://www.npmjs.com/package/http-server) is a simple, zero-configuration command-line static HTTP server | 38 | | Useful Links | [npmtrends](https://npmtrends.com/) Compare package download counts over time, [act](https://nektosact.com/introduction.html) run your GitHub Actions locally, [Actionlint](https://marketplace.visualstudio.com/items?itemName=arahata.linter-actionlint) static checker for GitHub Actions workflow files, [share-dev-environments](https://github.com/make-everything-simple/share-dev-environments) quick setup by running some commands to align development environment among machines or developers | 39 | 40 | ## How to use 41 | 42 | ### Clone repository and rename it 43 | 44 | ```bash 45 | git clone git@github.com:make-everything-simple/npm-template-typescript.git 46 | # rename to desire name folder 47 | mv npm-template-typescript $desire_name 48 | cd $desire_name 49 | ``` 50 | 51 | ### Update necessary fields e.g. name, author, version, repository, etc in package.json file 52 | 53 | we can manage our package.json via [npm-pkg](https://docs.npmjs.com/cli/v10/commands/npm-pkg) 54 | 55 | ```bash 56 | npm pkg set = [= ...] 57 | npm pkg get [ [ ...]] 58 | npm pkg delete [ ...] 59 | npm pkg set [[].= ...] 60 | npm pkg set [[].= ...] 61 | npm pkg fix 62 | ``` 63 | 64 | ### Install dependencies and build it 65 | 66 | ```bash 67 | # reinitialize existing Git repository 68 | git init 69 | # install dependencies 70 | npm install | yarn install 71 | # run build 72 | npm run build | yarn build 73 | ``` 74 | 75 | ### Implement your production code, and write unit tests 76 | 77 | ### Verify or fix lint 78 | 79 | ```bash 80 | # check lint's rules 81 | npm run lint | yarn lint 82 | # check lint's rules and try to fix 83 | npm run lint:fix | yarn lint:fix 84 | # format your code 85 | npm run prettier:format | yarn prettier:format 86 | ``` 87 | 88 | ### Verify unit test 89 | 90 | ```bash 91 | npm test | yarn test 92 | ``` 93 | 94 | ### Review docs in your local machine 95 | 96 | ```bash 97 | // Port: 8080 as default 98 | npm run docs:serve 99 | ``` 100 | 101 | ### [Configure Publishing's Credentials](./CONFIG.md) 102 | 103 | ## Collaboration 104 | 105 | 1. We use the git rebase strategy to keep tracking meaningful commit message. Help to enable rebase when pull `$ git config --local pull.rebase true` 106 | 2. Follow TypeScript Style Guide [Google](https://google.github.io/styleguide/tsguide.html) 107 | 3. Follow Best-Practices in coding: 108 | 1. [Clean code](https://github.com/labs42io/clean-code-typescript) make team happy 109 | 2. [Return early](https://szymonkrajewski.pl/why-should-you-return-early/) make code safer and use resource Efficiency 110 | 3. [Truthy & Falsy](https://frontend.turing.edu/lessons/module-1/js-truthy-falsy-expressions.html) make code shorter 111 | 4. [SOLID Principles](https://javascript.plainenglish.io/solid-principles-with-type-script-d0f9a0589ec5) make clean code 112 | 5. [DRY & KISS](https://dzone.com/articles/software-design-principles-dry-and-kiss) avoid redundancy and make your code as simple as possible 113 | 4. Make buildable commit and pull latest code from `main` branch frequently 114 | 5. Follow the [Semantic Versioning](https://semver.org/) once we are ready for release 115 | 6. Use readable commit message [karma](http://karma-runner.github.io/6.3/dev/git-commit-msg.html) to let us use it in the release notes 116 | 117 | ```bash 118 | /‾‾‾‾‾‾‾‾ 119 | 🔔 < Ring! Please use semantic commit messages 120 | \________ 121 | 122 | 123 | (): ([issue number]) 124 | │ │ | │ 125 | | | | └─> subject in present tense. Not capitalized. No period at the end. 126 | | | | 127 | │ │ └─> Issue number (optional): Jira Ticket or Issue number 128 | │ │ 129 | │ └─> Scope (optional): eg. Articles, Profile, Core 130 | │ 131 | └─> Type: chore, docs, feat, fix, refactor, style, ci, perf, build, or test. 132 | ``` 133 | --------------------------------------------------------------------------------