├── .gitignore ├── library-starter ├── .gitignore ├── src │ ├── index.ts │ └── hello-world.ts ├── tsconfig.json ├── package-lock.json └── package.json ├── example-consumer ├── .gitignore ├── somefile.ts ├── package.json └── package-lock.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /library-starter/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | /dist 4 | -------------------------------------------------------------------------------- /example-consumer/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | /dist 4 | -------------------------------------------------------------------------------- /example-consumer/somefile.ts: -------------------------------------------------------------------------------- 1 | import {sayHello} from 'hwrld' 2 | sayHello(); -------------------------------------------------------------------------------- /library-starter/src/index.ts: -------------------------------------------------------------------------------- 1 | export {sayHello, sayGoodbye} from './hello-world' 2 | 3 | -------------------------------------------------------------------------------- /library-starter/src/hello-world.ts: -------------------------------------------------------------------------------- 1 | export function sayHello() { 2 | console.log('hi') 3 | } 4 | export function sayGoodbye() { 5 | console.log('goodbye') 6 | } -------------------------------------------------------------------------------- /library-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2019", 5 | "declaration": true, 6 | "outDir": "./dist" 7 | }, 8 | "include": [ 9 | "src/**/*" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /library-starter/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hwrld", 3 | "version": "2.2.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "typescript": { 8 | "version": "5.2.2", 9 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 10 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 11 | "dev": true 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example-consumer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libconsumer", 3 | "version": "2.1.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "npx ts-node somefile", 8 | "linklib": "npm run --prefix ../library-starter build && npm link ../library-starter", 9 | "install-beta": "npm install hwrld@beta", 10 | "install-lib": "npm install hwrld" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "hwrld": "2.2.1" 16 | }, 17 | "devDependencies": { 18 | "ts-node": "10.9.1", 19 | "typescript": "5.2.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /library-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hwrld", 3 | "version": "2.2.1", 4 | "description": "Can log \"hello world\" and \"goodbye world\" to the console!", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "files": [ 8 | "/dist" 9 | ], 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1", 12 | "build": "tsc", 13 | "publish-lib": "npm run build && npm publish", 14 | "publish-beta": "npm run build && npm publish --tag beta", 15 | "publish-dryrun": "npm run build && npm publish --dry-run" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/bersling/typescript-library-starter.git" 20 | }, 21 | "keywords": [ 22 | "demo", 23 | "typescript", 24 | "library", 25 | "hello world" 26 | ], 27 | "author": "Daniel Niederberger ", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/bersling/typescript-library-starter/issues" 31 | }, 32 | "homepage": "https://github.com/bersling/typescript-library-starter#readme", 33 | "devDependencies": { 34 | "typescript": "5.2.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Example Typescript 5.x Library 2 | 3 | Simple starter library updated in 2023. 4 | 5 | Tutorial can be found at 6 | [https://www.tsmean.com/articles/how-to-write-a-typescript-library/](https://www.tsmean.com/articles/how-to-write-a-typescript-library/). 7 | 8 | # Usage 9 | 10 | First you should get the repo 11 | ``` 12 | git clone https://github.com/bersling/typescript-library-starter.git 13 | ``` 14 | 15 | Then you can apply any changes you'd like to the `library-starter`. 16 | 17 | ## Give it a name 18 | 19 | Adjust the `name` in `library-starter/package.json`. Check with `npm` to see which names are still free. 20 | 21 | You can also adjust the version back to `1.0.0` or `0.0.1`. 22 | 23 | ## Testing your module locally with npm link 24 | 25 | Using [npm link](https://www.tsmean.com/articles/how-to-write-a-typescript-library/local-consumer) you can easily test whether your changes are working correctly. 26 | 27 | ``` 28 | cd example-consumer 29 | npm run linklib 30 | npm test 31 | ``` 32 | 33 | Here `npm run linklib` is just an alias for `npm run --prefix ../library-starter build && npm link ../library-starter`. 34 | 35 | ## Publishing a beta aka. "next" version 36 | 37 | In order not to break things for the users of your library it is a best practice to first publish it with a `beta` or `next` tag. That way early adopters or yourself can test some more by using `npm install mylib@beta` and once you're ready you can publish the actual version `npm publish mylib`. 38 | 39 | Change the `version` property in `library-starter/package.json` for example to `2.1.1-beta.1`. 40 | 41 | ``` 42 | cd library-starter 43 | npm run publish-beta 44 | ``` 45 | 46 | Here `npm run publish-beta` is an alias for `npm run build && npm publish --tag beta`. 47 | 48 | Then test it through 49 | 50 | ``` 51 | cd example-consumer 52 | npm run install-beta 53 | npm test 54 | ``` 55 | 56 | `npm run install-beta` is an alias for `npm install hwrld@beta`. 57 | 58 | ## Dry run of publish 59 | 60 | It is also a good idea to do a dry run before you publish. That way you can check once more whether the version is correctly specified and you include the correct files. 61 | 62 | ``` 63 | cd library-starter 64 | npm run publish-dryrun 65 | ``` 66 | 67 | `npm run publish-dryrun` is an alias for `npm run build && npm publish --dry-run`. 68 | 69 | ## Publish a new version 70 | 71 | First adjust the `version` in `library-starter/package.json`. 72 | 73 | Once you are ready to publish an actual version you can run 74 | 75 | ``` 76 | cd library-starter 77 | npm run publish-lib 78 | ``` 79 | 80 | `npm run publish-lib` is an alias for `npm run build && npm publish` 81 | 82 | You can consume it like this: 83 | ``` 84 | cd example-consumer 85 | npm run install-lib 86 | npm test 87 | ``` 88 | 89 | `npm run install-lib` is equal to `npm install hwrld` or `npm install hwrld@latest`. 90 | 91 | # Further reading 92 | 93 | You can write a test like this: 94 | https://www.tsmean.com/articles/how-to-write-a-typescript-library/unit-testing 95 | -------------------------------------------------------------------------------- /example-consumer/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libconsumer", 3 | "version": "2.1.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@cspotcode/source-map-support": { 8 | "version": "0.8.1", 9 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 10 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 11 | "dev": true, 12 | "requires": { 13 | "@jridgewell/trace-mapping": "0.3.9" 14 | } 15 | }, 16 | "@jridgewell/resolve-uri": { 17 | "version": "3.1.1", 18 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", 19 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", 20 | "dev": true 21 | }, 22 | "@jridgewell/sourcemap-codec": { 23 | "version": "1.4.15", 24 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 25 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 26 | "dev": true 27 | }, 28 | "@jridgewell/trace-mapping": { 29 | "version": "0.3.9", 30 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 31 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 32 | "dev": true, 33 | "requires": { 34 | "@jridgewell/resolve-uri": "^3.0.3", 35 | "@jridgewell/sourcemap-codec": "^1.4.10" 36 | } 37 | }, 38 | "@tsconfig/node10": { 39 | "version": "1.0.9", 40 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", 41 | "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", 42 | "dev": true 43 | }, 44 | "@tsconfig/node12": { 45 | "version": "1.0.11", 46 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", 47 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", 48 | "dev": true 49 | }, 50 | "@tsconfig/node14": { 51 | "version": "1.0.3", 52 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", 53 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", 54 | "dev": true 55 | }, 56 | "@tsconfig/node16": { 57 | "version": "1.0.4", 58 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", 59 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", 60 | "dev": true 61 | }, 62 | "acorn": { 63 | "version": "8.10.0", 64 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", 65 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", 66 | "dev": true 67 | }, 68 | "acorn-walk": { 69 | "version": "8.2.0", 70 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", 71 | "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", 72 | "dev": true 73 | }, 74 | "arg": { 75 | "version": "4.1.3", 76 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 77 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 78 | "dev": true 79 | }, 80 | "create-require": { 81 | "version": "1.1.1", 82 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 83 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", 84 | "dev": true 85 | }, 86 | "diff": { 87 | "version": "4.0.2", 88 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 89 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 90 | "dev": true 91 | }, 92 | "hwrld": { 93 | "version": "2.2.1", 94 | "resolved": "https://registry.npmjs.org/hwrld/-/hwrld-2.2.1.tgz", 95 | "integrity": "sha512-eaWYFooXx1wXvnZdCY2EbQkHt8QfzenwrqNw7PXrFSPIc3Sk42NaSu1c6BHfhC0MESZSgrBdudgd8NeOAc9MfA==" 96 | }, 97 | "make-error": { 98 | "version": "1.3.6", 99 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 100 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 101 | "dev": true 102 | }, 103 | "ts-node": { 104 | "version": "10.9.1", 105 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", 106 | "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", 107 | "dev": true, 108 | "requires": { 109 | "@cspotcode/source-map-support": "^0.8.0", 110 | "@tsconfig/node10": "^1.0.7", 111 | "@tsconfig/node12": "^1.0.7", 112 | "@tsconfig/node14": "^1.0.0", 113 | "@tsconfig/node16": "^1.0.2", 114 | "acorn": "^8.4.1", 115 | "acorn-walk": "^8.1.1", 116 | "arg": "^4.1.0", 117 | "create-require": "^1.1.0", 118 | "diff": "^4.0.1", 119 | "make-error": "^1.1.1", 120 | "v8-compile-cache-lib": "^3.0.1", 121 | "yn": "3.1.1" 122 | } 123 | }, 124 | "typescript": { 125 | "version": "5.2.2", 126 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 127 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 128 | "dev": true 129 | }, 130 | "v8-compile-cache-lib": { 131 | "version": "3.0.1", 132 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", 133 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", 134 | "dev": true 135 | }, 136 | "yn": { 137 | "version": "3.1.1", 138 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 139 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 140 | "dev": true 141 | } 142 | } 143 | } 144 | --------------------------------------------------------------------------------