repository template for Node.js & TypeScript projects
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: next version of repo template (#358)

authored by samanthanguyen.me and committed by

GitHub cd6c1550 551b5dec

+140 -177
+2
.github/dependabot.yml
··· 15 15 # TEMP: ignore eslint major version (v9) until typescript-eslint releases v8 16 16 - dependency-name: "eslint" 17 17 update-types: ["version-update:semver-major"] 18 + - dependency-name: "@eslint/js" 19 + update-types: ["version-update:semver-major"] 18 20 groups: 19 21 typescript: 20 22 patterns:
+32 -56
README.md
··· 14 14 15 15 ## Getting started 16 16 17 - ### Creating a new repository 18 - 19 - #### GitHub UI 20 - 21 - You can create a new repository based on this template by clicking the "Use this template" button in the top-right corner of this page. 22 - 23 - #### Terminal 24 - 25 - You can run the following command below with the [GitHub CLI](https://cli.github.com/). Some notes: 26 - 27 - - Replace placeholder with name of your extension in upper CamelCase 28 - - Configure your repository's visibility with `--public`, `--private`, or `--internal` 29 - 30 - ```shell 31 - gh repo create {{package}} --public --clone --template neoncitylights/typescript 32 - ``` 33 - 34 - ### Cookiecutter stuff 35 - 36 - Using your favorite text editor or IDE, find-and-replace the following placeholders: 37 - 38 - - `@author/package`: Replace this with the name of your package. This can be scoped under a user/organization (e.g `@samantha/my-really-cool-package`). **Note**: This placeholder is different than the others to avoid warnings from the NPM client. 39 - - `{{author}}`: Replace this with your GitHub/npm username, or the name of your organization. 40 - - `{{package}}`: Replace this with the name of your library. 41 - - `{{desc}}`: Replace this with a short description of your library. 42 - 43 - ## Publishing a package 44 - 45 - if you haven't authenticated with the NPM CLI already, you'll need to do that first by running [`npm adduser`](https://docs.npmjs.com/cli/v9/commands/npm-adduser) in the terminal. 46 - 47 - - To publish a non-scoped package (e.g `my-cool-package`), run `npm publish` 48 - - To publish a [scoped package](https://docs.npmjs.com/cli/v9/using-npm/scope) (e.g `@namespace/my-cool-package`), pass the `--access` flag, which must be either `public` or `private`. For example: 17 + ### Create a new repository 49 18 19 + Choose a method: 20 + - **GitHub UI**: Press the "Use this template" button in the top-right corner of this page. 21 + - **GitHub CLI**: Install [GitHub CLI](https://cli.github.com). Then run one of the following: 50 22 ```shell 51 - npm publish --access public 23 + gh repo create --template neoncitylights/typescript --public --clone {{package}} # clone as public 24 + gh repo create --template neoncitylights/typescript --private --clone {{package}} # clone as private 52 25 ``` 53 26 54 - > [!NOTE] 55 - > To publish a private package on NPM, you must have [npm Pro](https://www.npmjs.com/products/pro). 27 + ### Replace placeholders 56 28 57 - ### GitHub Actions 29 + Using your text editor or IDE, find-and-replace the following placeholders: 58 30 59 - For your CI environment (when using GitHub Actions), you'll need to set the `NPM_TOKEN` environment variable to the value of your NPM token. You can find this by running `npm token list` in the terminal, and create a token by running `npm token create`. 31 + - `@author/package`: Replace this with the author's name (e.g a user or organization) and package's name. 32 + - **Note**: This placeholder is different than the others to avoid warnings from the NPM client. 33 + - `{{author}}`: Replace this with the author's name (e.g real name, GitHub username, or organization). 34 + - `{{package}}`: Replace this with the name of the package. 35 + - `{{desc}}`: Replace this with a short description of the package. 60 36 61 - To add your token to your repository: 37 + ## Publishing a package 38 + ```shell 39 + # Enter the root directory of the package you want to publish 40 + cd packages/pkg1 62 41 63 - 1. Go to Settings > Security (Secrets and Variables) > Actions 64 - 2. Press "New repository secret" button 65 - 3. Enter `NPM_TOKEN` as the name of the secret 66 - 4. Copy and paste the token value 67 - 5. Press "Add secret" button 42 + # if package is scoped, e.g "hello-world" 43 + npm publish 44 + 45 + # if package is non-scoped, e.g "@user123/hello-world", 46 + # can also be published privately via `--access private` (requires npm pro plan) 47 + npm publish --access public 48 + ``` 68 49 69 50 ## Configure 70 51 71 52 ### NPM scripts 72 53 73 - NPM has core commands that can be overriden by package authors. I've tried to make this as zero-config as possible, so its likely you won't need to change them any further. These commands are: 74 - 75 - - [`prepare`](https://docs.npmjs.com/cli/v8/using-npm/scripts#life-cycle-scripts) 76 - - [`prepublishOnly`](https://docs.npmjs.com/cli/v8/using-npm/scripts#life-cycle-scripts) 77 - 78 - These are the most relevant commands that you'll likely use: 79 - 80 54 | Command | Description | 81 55 | ------- | ----------- | 82 56 | `npm run build` | Build the library for distributing | 83 57 | `npm run docs` | Generate documentation | 84 58 | `npm run docs-watch` | Generate documentation in watch mode| 85 59 | `npm run clean` | Remove all generated files | 86 - | `npm run reinstall` | Cleans and reinstalls dependencies | 87 - | `npm run lint` | Check for linting errors | 88 - | `npm run lint-fix` | Fix linting errors | 89 60 | `npm run test` | Run unit tests | 90 61 | `npm run test-ci` | Run unit tests in CI mode | 91 62 | `npm run test-ui` | Run unit tests in UI/browser mode | 92 63 | `npm run test-watch` | Run unit tests in watch mode | 64 + | `npm run lint` | Check for ESLint/publint errors | 65 + | `npm run lint-fix` | Fix ESLint errors (publint errors must be fixed manually) | 66 + | `npm run eslint` | Check for ESLint errors | 67 + | `npm run eslint-fix` | Fix ESLint errors | 68 + | `npm run publint` | Check for NPM packaging errors | 93 69 94 70 ### Developer tools 95 71 96 72 | Tool | File | Documentation | 97 73 | ---- | ---- | ------------- | 98 74 | NPM package | [`package.json`](package.json) | [docs](https://docs.npmjs.com/cli/v10/configuring-npm/package-json), [website](https://docs.npmjs.com/) | 99 - | TypeDoc (documentation generator) | [`package.json`](package.json) (`typedocOptions`) | [docs](https://typedoc.org/options/configuration/), [website](https://typedoc.org/) | 100 - | TypeScript | [`packages/tsconfig.json`](packages/tsconfig.json) | [docs](https://www.typescriptlang.org/tsconfig), [website](https://www.typescriptlang.org/) | 75 + | TypeScript | [`tsconfig.json`](./tsconfig.json), [`packages/*/tsconfig.json`](packages/pkg1/tsconfig.json) | [docs](https://www.typescriptlang.org/tsconfig), [website](https://www.typescriptlang.org/) | 76 + | TypeDoc (documentation generator) | [`tsconfig.json`](tsconfig.json) (`typedocOptions`) | [docs](https://typedoc.org/options/configuration/), [website](https://typedoc.org/) | 101 77 | ESLint (code formatter + linter) | [`eslint.config.js`](./eslint.config.js) | [docs](https://eslint.org/docs/latest/use/configure/), [website](https://eslint.org/) | 102 78 | Vite (bundler) | [`vite.config.ts`](packages/pkg1/vite.config.ts) | [docs](https://vitejs.dev/config/), [website](https://vitejs.dev/) | 103 - | Vitest (testing framework) | [`vite.config.ts`](packages/pkg1/vite.config.ts) (`test`) | [docs](https://vitest.dev/config/), [website](https://vitest.dev/) | 79 + | Vitest (testing framework) | [`packages/*/vite.config.ts`](packages/pkg1/vite.config.ts) (`test`) | [docs](https://vitest.dev/config/), [website](https://vitest.dev/) | 104 80 | Vitest workspace | [`vitest.workspace.ts`](./vitest.workspace.ts) | [docs](https://vitest.dev/guide/workspace.html#workspace) | 105 81 | Dependabot | [`.github/dependabot.yml`](./.github/dependabot.yml) | [docs](https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file), [website](https://github.com/dependabot) | 106 82
+10 -4
eslint.config.js
··· 3 3 import stylistic from '@stylistic/eslint-plugin' 4 4 5 5 export default tsEslint.config( 6 + { 7 + ignores: [ 8 + '**/dist/', 9 + 'docs/typedoc', 10 + ], 11 + }, 6 12 stylistic.configs.customize({ 7 13 indent: 'tab', 8 14 quote: 'single', ··· 10 16 jsx: true, 11 17 }), 12 18 eslint.configs.recommended, 13 - ...tsEslint.configs.recommendedTypeChecked, 14 - ...tsEslint.configs.stylisticTypeChecked, 19 + ...tsEslint.configs.recommended, 20 + ...tsEslint.configs.stylistic, 15 21 { 16 22 languageOptions: { 17 23 parserOptions: { 18 24 project: [ 19 25 './tsconfig.eslint.json', 20 - 'packages/*/tsconfig.json' 26 + './packages/**/tsconfig.eslint.json', 21 27 ], 22 28 tsconfigRootDir: import.meta.dirname, 23 29 }, 24 - } 30 + }, 25 31 }, 26 32 )
+7 -16
package-lock.json
··· 9 9 "packages/**" 10 10 ], 11 11 "devDependencies": { 12 - "@eslint/js": "^9.7.0", 12 + "@eslint/js": "^8.57.0", 13 13 "@stylistic/eslint-plugin": "^2.3.0", 14 14 "@types/eslint__js": "^8.42.3", 15 15 "@types/node": "^20.14.11", ··· 540 540 } 541 541 }, 542 542 "node_modules/@eslint/js": { 543 - "version": "9.7.0", 544 - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", 545 - "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", 543 + "version": "8.57.0", 544 + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", 545 + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", 546 546 "dev": true, 547 + "license": "MIT", 547 548 "engines": { 548 - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 549 + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 549 550 } 550 551 }, 551 552 "node_modules/@humanwhocodes/config-array": { ··· 2352 2353 }, 2353 2354 "funding": { 2354 2355 "url": "https://opencollective.com/eslint" 2355 - } 2356 - }, 2357 - "node_modules/eslint/node_modules/@eslint/js": { 2358 - "version": "8.57.0", 2359 - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", 2360 - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", 2361 - "dev": true, 2362 - "license": "MIT", 2363 - "engines": { 2364 - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 2365 2356 } 2366 2357 }, 2367 2358 "node_modules/espree": { ··· 4985 4976 "license": "MIT", 4986 4977 "funding": { 4987 4978 "type": "individual", 4988 - "url": "https://github.com/sponsors/something" 4979 + "url": "https://github.com/sponsors/{{author}}" 4989 4980 } 4990 4981 } 4991 4982 }
+3 -13
package.json
··· 7 7 ], 8 8 "scripts": { 9 9 "build": "npm run build -ws --if-present", 10 - "build-all": "npm run build && npm run docs", 11 10 "docs": "typedoc", 12 11 "docs-watch": "npm run docs -- --watch", 13 12 "clean": "rm -rf ./docs/typedoc/ ./node_modules && rm -rf ./package-lock.json", 14 - "reinstall": "npm run clean && npm install", 15 13 "test": "vitest --coverage", 16 14 "test-ci": "npm run test -- run", 17 15 "test-ui": "npm run test -- --ui", 18 16 "test-watch": "npm run test -- --watch", 19 - "test-all": "npm run test-ci && npm run lint", 20 17 "lint": "npm run eslint && npm run publint", 21 18 "lint-fix": "npm run eslint-fix", 22 - "eslint": "eslint packages/*/src/** --cache", 19 + "eslint": "eslint . --cache", 23 20 "eslint-fix": "npm run eslint -- --fix", 21 + "eslint-debug": "eslint --print-config eslint.config.js", 24 22 "publint": "npm run publint -ws" 25 23 }, 26 24 "devDependencies": { 27 - "@eslint/js": "^9.7.0", 25 + "@eslint/js": "^8.57.0", 28 26 "@stylistic/eslint-plugin": "^2.3.0", 29 27 "@types/eslint__js": "^8.42.3", 30 28 "@types/node": "^20.14.11", ··· 38 36 "vite": "^5.3.4", 39 37 "vite-plugin-dts": "^3.9.1", 40 38 "vitest": "^2.0.3" 41 - }, 42 - "typedocOptions": { 43 - "out": "docs/typedoc", 44 - "entryPoints": ["packages/*"], 45 - "entryPointStrategy": "packages", 46 - "includeVersion": false, 47 - "lightHighlightTheme": "github-light", 48 - "darkHighlightTheme": "github-dark" 49 39 } 50 40 }
+4 -5
packages/pkg1/tests/basic.test.ts
··· 1 - import { expect, test } from 'vitest'; 2 - 3 - import { greet } from '../src/index'; 1 + import { expect, test } from 'vitest' 2 + import { greet } from '../src' 4 3 5 4 test('greet runs correctly', () => { 6 - expect(greet('John')).toBe('Hello, John!'); 7 - }); 5 + expect(greet('John')).toBe('Hello, John!') 6 + })
+15
packages/pkg1/tsconfig.eslint.json
··· 1 + { 2 + "extends": "./tsconfig.json", 3 + "compilerOptions": { 4 + "noEmit": true 5 + }, 6 + "exclude": [ 7 + "dist", 8 + "docs" 9 + ], 10 + "include": [ 11 + "src", 12 + "tests", 13 + "vite.config.ts" 14 + ] 15 + }
+39 -7
packages/pkg1/tsconfig.json
··· 1 1 { 2 - "extends": "../tsconfig.base.json", 3 2 "include": [ 4 - "src" 3 + "./src" 5 4 ], 6 - "exclude": [ 7 - "node_modules", 8 - "**/tests/*", 9 - "**/__tests__/*" 10 - ], 5 + "compilerOptions": { 6 + /* base options */ 7 + "esModuleInterop": true, 8 + "skipLibCheck": true, 9 + "allowJs": true, 10 + "resolveJsonModule": true, 11 + "verbatimModuleSyntax": true, 12 + "moduleDetection": "force", 13 + "rootDir": "./src", 14 + 15 + /* transpilation */ 16 + "lib": [ "ES2022" ], 17 + "target": "ES2022", 18 + "module": "ESNext", 19 + "moduleResolution": "Bundler", 20 + "isolatedModules": true, 21 + "sourceMap": true, 22 + "declaration": true, 23 + "declarationMap": true, 24 + "composite": true, 25 + 26 + /* strictness */ 27 + "strict": true, 28 + "forceConsistentCasingInFileNames": true, 29 + "allowUnusedLabels": false, 30 + "allowUnreachableCode": false, 31 + "exactOptionalPropertyTypes": true, 32 + "noFallthroughCasesInSwitch": true, 33 + "noImplicitOverride": true, 34 + "noImplicitReturns": true, 35 + "noPropertyAccessFromIndexSignature": true, 36 + "noUncheckedIndexedAccess": true, 37 + "noUnusedLocals": true, 38 + "noUnusedParameters": true, 39 + 40 + /** ES support */ 41 + "useDefineForClassFields": true, 42 + }, 11 43 "typedocOptions": { 12 44 "entryPoints": [ 13 45 "src/index.ts"
+6 -6
packages/pkg1/vite.config.ts
··· 1 - import dts from 'vite-plugin-dts'; 2 - import { defineProject } from 'vitest/config'; 1 + import dts from 'vite-plugin-dts' 2 + import { defineProject } from 'vitest/config' 3 3 4 4 export default defineProject({ 5 5 build: { ··· 9 9 fileName: () => '{{package}}.mjs', 10 10 }, 11 11 }, 12 - define: { 13 - 'import.meta.vitest': 'undefined', 12 + define: { 13 + 'import.meta.vitest': 'undefined', 14 14 }, 15 15 plugins: [ 16 16 dts({ ··· 22 22 coverage: { 23 23 include: ['src/**/*.{js,ts}'], 24 24 provider: 'v8', 25 - reporter: [ 'text', 'json', 'html' ], 25 + reporter: ['text', 'json', 'html'], 26 26 }, 27 27 }, 28 - }); 28 + })
-45
packages/tsconfig.base.json
··· 1 - // Handbook: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html 2 - // Reference: https://www.typescriptlang.org/tsconfig 3 - { 4 - "compilerOptions": { 5 - "composite": true, 6 - /* base options */ 7 - "esModuleInterop": true, 8 - "skipLibCheck": true, 9 - "allowJs": true, 10 - "resolveJsonModule": true, 11 - "verbatimModuleSyntax": true, 12 - "moduleDetection": "force", 13 - 14 - /* strictness */ 15 - "strict": true, 16 - "forceConsistentCasingInFileNames": true, 17 - "allowUnusedLabels": false, 18 - "allowUnreachableCode": false, 19 - "exactOptionalPropertyTypes": true, 20 - "noFallthroughCasesInSwitch": true, 21 - "noImplicitOverride": true, 22 - "noImplicitReturns": true, 23 - "noPropertyAccessFromIndexSignature": true, 24 - "noUncheckedIndexedAccess": true, 25 - "noUnusedLocals": true, 26 - "noUnusedParameters": true, 27 - 28 - /** ES support */ 29 - "useDefineForClassFields": true, 30 - 31 - /* transpilation */ 32 - "lib": [ "ES2022" ], 33 - "target": "ES2022", 34 - "module": "ESNext", 35 - "moduleResolution": "Bundler", 36 - "isolatedModules": true, 37 - "baseUrl": "./src", 38 - "sourceMap": true, 39 - "declaration": true, 40 - "declarationMap": true, 41 - "types": [ 42 - "vitest/importMeta" 43 - ] 44 - } 45 - }
-18
packages/tsconfig.json
··· 1 - // Handbook: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html 2 - // Reference: https://www.typescriptlang.org/tsconfig 3 - { 4 - "compilerOptions": { 5 - // monorepo setup 6 - // - composite: cache builds with a .tsbuildinfo 7 - // - sourceMap/declarationMap: enable to ensure go-to definitions 8 - // will work properly 9 - "declaration": true, 10 - "composite": true, 11 - "sourceMap": true, 12 - "declarationMap": true, 13 - "esModuleInterop": true 14 - }, 15 - "references": [ 16 - { "path": "pkg1" } 17 - ] 18 - }
+6 -5
tsconfig.eslint.json
··· 1 1 { 2 + "extends": "./tsconfig.json", 2 3 "compilerOptions": { 3 - "noEmit": true, 4 - "strict": true 4 + "noEmit": true 5 5 }, 6 + "exclude": [], 6 7 "include": [ 7 - "packages/*/src" 8 - ], 9 - "exclude": [] 8 + "eslint.config.js", 9 + "vitest.workspace.ts" 10 + ] 10 11 }
+14
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "module": "ESNext", 4 + "moduleResolution": "Bundler" 5 + }, 6 + "typedocOptions": { 7 + "out": "docs/typedoc", 8 + "entryPoints": ["packages/*"], 9 + "entryPointStrategy": "packages", 10 + "includeVersion": false, 11 + "lightHighlightTheme": "github-light", 12 + "darkHighlightTheme": "github-dark" 13 + } 14 + }
+2 -2
vitest.workspace.ts
··· 1 - import { defineWorkspace } from 'vitest/config'; 1 + import { defineWorkspace } from 'vitest/config' 2 2 3 3 // defineWorkspace provides a nice type hinting DX 4 4 export default defineWorkspace([ 5 5 'packages/*', 6 - ]); 6 + ])