https://github.com/weaponsforge/math
Simple math operations for testing publishing to the NPM registry
https://github.com/weaponsforge/math
Last synced: 2 months ago
JSON representation
Simple math operations for testing publishing to the NPM registry
- Host: GitHub
- URL: https://github.com/weaponsforge/math
- Owner: weaponsforge
- License: mit
- Created: 2025-02-11T18:23:15.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-11T20:17:10.000Z (about 1 year ago)
- Last Synced: 2025-02-11T20:26:47.442Z (about 1 year ago)
- Language: TypeScript
- Size: 11.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## math
Simple math operations for testing publishing to the NPM registry from [totaltypescript](https://www.totaltypescript.com/how-to-create-an-npm-package).
This repository contains hands-on practice set up for:
- A TypeScript project with the latest settings
- Prettier, which both formats your code and checks that it's formatted correctly
- `@arethetypeswrong/cli`, which checks that your package exports are correct
- `tsup`, which compiles your TypeScript code to JavaScript
- `vitest`, which runs your tests
- GitHub Actions, which runs your CI process
- Changesets, which versions and publishes your package
## Steps
Summary of creating the code repository and other setup from [totaltypescript](https://www.totaltypescript.com/how-to-create-an-npm-package).
### 1. Git
Expand to view details
1. Initialize the repo
2. Setup a .gitignore
3. Create a new repository on GitHub
4. Push to GitHub
### 2. **`package.json`**
Expand to view details
1. Create a package.json file
2. Add the license field
3. Add a LICENSE file
4. Add a README file
### 3. TypeScript
Expand to view details
1. Install TypeScript
`npm install --save-dev typescript`
2. Setup a `tsconfig.json` file
3. Configure your `tsconfig.json` for the DOM
- If your code runs in the DOM (i.e. requires access to `document`, `window`, or `localStorage` etc), skip this step.
- If your code doesn't require access to DOM API's, add the following to your tsconfig.json (This prevents the DOM typings from being available in your code):
```json
{
"compilerOptions": {
/* other options */
"lib": ["es2022"]
}
}
```
4. Create a source file
- `/src/utils.ts`
5. Create an index file
- `/src/index.ts`
6. Set up a `build` script
- `"build": "tsc"`
7. Add `dist` to `.gitignore`
8. Set up a `CI` script
- `"ci": "npm run build"`
### 4. Prettier
Expand to view details
1. Install Prettier
- `npm install --save-dev prettier`
2. Set up a `.prettierrc`
```json
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"tabWidth": 2
}
```
3. Set up a `format` script
- `"format": "prettier --write ."`
4. Set up a `check-format` script
- `"check-format": "prettier --check ."`
5. Adding to our `CI` script
- `"ci": "npm run build && npm run check-format"`
### 5. `exports`, `main` and `@arethetypeswrong/cli`
Expand to view details
**@arethetypeswrong/cli** is a tool that checks if your package exports are correct
1. Install `@arethetypeswrong/cli`
- `npm install --save-dev @arethetypeswrong/cli`
2. Set up a `check-exports` script
- `"check-exports": "attw --pack ."`
3. Setting `main`
Add a `main` field to your package.json with the following content:
- `"main": "dist/index.js"`
4. Fix the CJS warning
> If you don't want to support CJS (which I recommend), change the check-exports script to:
`"check-exports": "attw --pack . --ignore-rules=cjs-resolves-to-esm"`
> If you prefer to dual publish CJS and ESM, skip this step.
5. Adding to our `CI` script
- `"ci": "npm run build && npm run check-format && npm run check-exports"`
### 6. Using `tsup` to Dual Publish
Expand to view details
> "If you want to publish both CJS and ESM code, you can use tsup. This is a tool built on top of esbuild that compiles your TypeScript code into both formats.
>
> My personal recommendation would be to skip this step, and only ship ES Modules. This makes your setup significantly simpler, and avoids many of the pitfalls of dual publishing, like [Dual Package Hazard](https://github.com/GeoffreyBooth/dual-package-hazard)". - totaltypescript
1. Install `tsup`
- `npm install --save-dev tsup`
2. Create a `tsup.config.ts` file
3. Change the `build` script
- `"build": "tsup"`
4. Add an `exports` field in the package.json
```json
{
"exports": {
"./package.json": "./package.json",
".": {
"import": "./dist/index.js",
"default": "./dist/index.cjs"
}
}
}
```
5. Run `npm run check-exports'
### 6.1. Turn TypeScript into a linter
Expand to view details
> "We're no longer running tsc to compile our code. And tsup doesn't actually check our code for errors - it just turns it into JavaScript.This means that our ci script won't error if we have TypeScript errors in our code. Eek. Let's fix this." - totaltypescript
1. Add `noEmit` to `tsconfig.json`
```json
"compilerOptions": {
"noEmit": true
}
```
2. Remove unused fields from `tsconfig.json`
These are no longer needed in our new 'linting' setup.
```text
outDir
rootDir
sourceMap
declaration
declarationMap
```
3. Change `module` to `Preserve`
Change `module` to `Preserve` in the tsconfig.json.
```json
"compilerOptions": {
"module": "Preserve"
}
```
We can start importing TS files without `.js` extensions with this setting, e.g.:
`import { addition } from './utils'`
4. Add a `lint` script
- `"lint": "tsc"`
5. Add `lint` to your `ci` script
- `npm run build && npm run check-format && npm run check-exports && npm run lint`
### 7. Testing with Vitest
Expand to view details
**vitest** is a modern test runner for ESM and TypeScript.
1. Install `vitest`
- `npm install --save-dev vitest`
2. Create a test
- Create a `src/utils.test.ts` file with the following content:
```typescript
import { add } from "./utils.js";
import { test, expect } from "vitest";
test("add", () => {
expect(add(1, 2)).toBe(3);
});
```
3. Set up a `test` script
- Add a `test` script in the package.json file
`"test": "vitest run"`
4. Run the test script
- `npm test`
5. Set up `dev` script
- This step runs tests in watch mode while developing. Add the following the package.json file.
`"dev": "vitest"`
6. Adding to our `CI` script.
- Add the `test` script to your `ci` script
`"ci": "npm run build && npm run check-format && npm run check-exports && npm run lint && npm run test"`
### 8. Set up CI with GitHub Actions
Expand to view details
1. Create a `.github/workflows/ci.yml` file
- Refer to the file in the code repository.
2. Testing our workflow
- Push the file to the repository.
- Workflow should run on push
### 9. Publishing with Changesets
Expand to view details
> "Changesets is a tool that helps you version and publish your package. It's an incredible tool that I recommend to anyone publishing packages to npm." - totaltypescript
1. Install `@changesets/cli`
- `npm install --save-dev @changesets/cli`
2. Initialize Changesets
- This will create a .changeset folder in your project, containing a config.json file. This is also where your changesets will live.
- `npx changeset init`
3. Make changesets releases public
- Edit the `.changeset/config.json` file
- Change the `access` field to `public`. Setting it to public allows publishing your package to npm.
- `"access": "public"`
4. Set `commit` to `true`
- In `.changeset/config.json`, change the `commit` field to `true`
- This will commit the changeset to your repository after versioning.
- `"commit": true`
5. Set up a `local-release` script
- This script will run your CI process and then publish your package to npm. This will be the command you run when you want to release a new version of your package from your local machine.
- Add a `local-release` script to your package.json with the following content:
- `"local-release": "changeset version && changeset publish"`
6. Run `CI` in `prepublishOnly`
- This runs the CI process before publishing the package to NPM
- Add a prepublishOnly script to your package.json:
- `"prepublishOnly": "npm run ci"`
7. Add a changeset
- Run the command to add a changeset:
- `npx changeset`
- Mark the release as a `patch`, `minor` or `major` release
- Give it a description e.g., "Initial release"
- This will create a new file in the `.changeset` folder with the changeset.
8. Commit your changes
- Commit your changes to your repository
```
git add .
git commit -m "Prepare for initial release"
```
9. Run the `local-release` script
- Run the command to release your package
- This will run your CI process, version your package, and publish it to npm.
- `npm run local-release`
10. See your package on npm
- Go to `http://npmjs.com/package/`
11. Further reading about Changesets
- [Changesets GitHub Action](https://github.com/changesets/action)
- [PR Bot](https://github.com/changesets/bot)
## References
- TSConfig Cheat Sheet [[1]](https://www.totaltypescript.com/tsconfig-cheat-sheet)
- Changesets GitHub Action [[2]](https://github.com/changesets/action)
- PR Bot [[3]](https://github.com/changesets/bot)
- Dual Package Hazard [[4]](https://github.com/GeoffreyBooth/dual-package-hazard)
@weaponsforge
20250212