{"id":25508242,"url":"https://github.com/weaponsforge/math","last_synced_at":"2026-02-22T09:03:05.557Z","repository":{"id":277039180,"uuid":"931109191","full_name":"weaponsforge/math","owner":"weaponsforge","description":"Simple math operations for testing publishing to the NPM registry","archived":false,"fork":false,"pushed_at":"2025-02-11T20:17:10.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-11T20:26:47.442Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/weaponsforge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-11T18:23:15.000Z","updated_at":"2025-02-11T20:17:13.000Z","dependencies_parsed_at":"2025-02-11T20:37:13.873Z","dependency_job_id":null,"html_url":"https://github.com/weaponsforge/math","commit_stats":null,"previous_names":["weaponsforge/math"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weaponsforge%2Fmath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weaponsforge%2Fmath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weaponsforge%2Fmath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/weaponsforge%2Fmath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/weaponsforge","download_url":"https://codeload.github.com/weaponsforge/math/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239619489,"owners_count":19669447,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-19T07:57:37.347Z","updated_at":"2025-11-20T09:30:18.429Z","avatar_url":"https://github.com/weaponsforge.png","language":"TypeScript","readme":"## math\n\nSimple math operations for testing publishing to the NPM registry from [totaltypescript](https://www.totaltypescript.com/how-to-create-an-npm-package).\n\nThis repository contains hands-on practice set up for:\n\n- A TypeScript project with the latest settings\n- Prettier, which both formats your code and checks that it's formatted correctly\n- `@arethetypeswrong/cli`, which checks that your package exports are correct\n- `tsup`, which compiles your TypeScript code to JavaScript\n- `vitest`, which runs your tests\n- GitHub Actions, which runs your CI process\n- Changesets, which versions and publishes your package\n\n## Steps\n\nSummary of creating the code repository and other setup from [totaltypescript](https://www.totaltypescript.com/how-to-create-an-npm-package).\n\n### 1. Git\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n1. Initialize the repo\n2. Setup a .gitignore\n3. Create a new repository on GitHub\n4. Push to GitHub\n\u003c/details\u003e\n\n### 2. **`package.json`**\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n1. Create a package.json file\n2. Add the license field\n3. Add a LICENSE file\n4. Add a README file\n\u003c/details\u003e\n\n### 3. TypeScript\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n1. Install TypeScript\u003cbr\u003e\n`npm install --save-dev typescript`\n\n2. Setup a `tsconfig.json` file\n\n3. Configure your `tsconfig.json` for the DOM\n   - If your code runs in the DOM (i.e. requires access to `document`, `window`, or `localStorage` etc), skip this step.\n   - 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):\n   ```json\n   {\n     \"compilerOptions\": {\n       /* other options */\n       \"lib\": [\"es2022\"]\n     }\n   }\n   ```\n\n4. Create a source file\n   - `/src/utils.ts`\n\n5. Create an index file\n   - `/src/index.ts`\n\n6. Set up a `build` script\n   - `\"build\": \"tsc\"`\n\n7. Add `dist` to `.gitignore`\n\n8. Set up a `CI` script\n   - `\"ci\": \"npm run build\"`\n\u003c/details\u003e\n\n### 4. Prettier\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n1. Install Prettier\n   - `npm install --save-dev prettier`\n\n2. Set up a `.prettierrc`\n   ```json\n   {\n     \"semi\": true,\n     \"singleQuote\": true,\n     \"trailingComma\": \"all\",\n     \"printWidth\": 80,\n     \"tabWidth\": 2\n   }\n   ```\n\n3. Set up a `format` script\n   - `\"format\": \"prettier --write .\"`\n\n4. Set up a `check-format` script\n   - `\"check-format\": \"prettier --check .\"`\n\n5. Adding to our `CI` script\n   - `\"ci\": \"npm run build \u0026\u0026 npm run check-format\"`\n\u003c/details\u003e\n\n### 5. `exports`, `main` and `@arethetypeswrong/cli`\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n**@arethetypeswrong/cli** is a tool that checks if your package exports are correct\n\n1. Install `@arethetypeswrong/cli`\n   - `npm install --save-dev @arethetypeswrong/cli`\n\n2. Set up a `check-exports` script\n   - `\"check-exports\": \"attw --pack .\"`\n\n3. Setting `main`\u003cbr\u003e\n   Add a `main` field to your package.json with the following content:\n   - `\"main\": \"dist/index.js\"`\n\n4. Fix the CJS warning\n   \u003e If you don't want to support CJS (which I recommend), change the check-exports script to:\u003cbr\u003e\n   `\"check-exports\": \"attw --pack . --ignore-rules=cjs-resolves-to-esm\"`\u003cbr\u003e\n   \u003e If you prefer to dual publish CJS and ESM, skip this step.\n\n5. Adding to our `CI` script\n   - `\"ci\": \"npm run build \u0026\u0026 npm run check-format \u0026\u0026 npm run check-exports\"`\n\u003c/details\u003e\n\n### 6. Using `tsup` to Dual Publish\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n\u003e \"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.\n\u003e\n\u003e 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\n\n1. Install `tsup`\n   - `npm install --save-dev tsup`\n2. Create a `tsup.config.ts` file\n3. Change the `build` script\n   - `\"build\": \"tsup\"`\n4. Add an `exports` field in the package.json\n   ```json\n   {\n     \"exports\": {\n       \"./package.json\": \"./package.json\",\n       \".\": {\n         \"import\": \"./dist/index.js\",\n         \"default\": \"./dist/index.cjs\"\n       }\n     }\n   }\n   ```\n5. Run `npm run check-exports'\n\u003c/details\u003e\n\n### 6.1. Turn TypeScript into a linter\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n\u003e \"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\n\n1. Add `noEmit` to `tsconfig.json`\n   ```json\n   \"compilerOptions\": {\n     \"noEmit\": true\n   }\n   ```\n\n2. Remove unused fields from `tsconfig.json`\u003cbr\u003e\n   These are no longer needed in our new 'linting' setup.\n   ```text\n   outDir\n   rootDir\n   sourceMap\n   declaration\n   declarationMap\n   ```\n\n3. Change `module` to `Preserve`\u003cbr\u003e\nChange `module` to `Preserve` in the tsconfig.json.\n   ```json\n   \"compilerOptions\": {\n     \"module\": \"Preserve\"\n   }\n   ```\n   We can start importing TS files without `.js` extensions with this setting, e.g.:\u003cbr\u003e\n   `import { addition } from './utils'`\n\n4. Add a `lint` script\n   - `\"lint\": \"tsc\"`\n\n5. Add `lint` to your `ci` script\n   - `npm run build \u0026\u0026 npm run check-format \u0026\u0026 npm run check-exports \u0026\u0026 npm run lint`\n\u003c/details\u003e\n\n### 7. Testing with Vitest\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n**vitest** is a modern test runner for ESM and TypeScript.\n\n1. Install `vitest`\n   - `npm install --save-dev vitest`\n\n2. Create a test\n   - Create a `src/utils.test.ts` file with the following content:\n      ```typescript\n      import { add } from \"./utils.js\";\n      import { test, expect } from \"vitest\";\n\n      test(\"add\", () =\u003e {\n        expect(add(1, 2)).toBe(3);\n      });\n      ```\n\n3. Set up a `test` script\n   - Add a `test` script in the package.json file\u003cbr\u003e\n     `\"test\": \"vitest run\"`\n\n4. Run the test script\n   - `npm test`\n\n5. Set up `dev` script\n   - This step runs tests in watch mode while developing. Add the following the package.json file.\u003cbr\u003e\n     `\"dev\": \"vitest\"`\n\n6. Adding to our `CI` script.\n   - Add the `test` script to your `ci` script\u003cbr\u003e\n   `\"ci\": \"npm run build \u0026\u0026 npm run check-format \u0026\u0026 npm run check-exports \u0026\u0026 npm run lint \u0026\u0026 npm run test\"`\n\u003c/details\u003e\n\n### 8. Set up CI with GitHub Actions\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n1. Create a `.github/workflows/ci.yml` file\n   - Refer to the file in the code repository.\n2. Testing our workflow\n   - Push the file to the repository.\n   - Workflow should run on push\n\u003c/details\u003e\n\n### 9. Publishing with Changesets\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand to view details\u003c/summary\u003e\n\n\u003e \"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\n\n1. Install `@changesets/cli`\n   - `npm install --save-dev @changesets/cli`\n\n2. Initialize Changesets\n   - This will create a .changeset folder in your project, containing a config.json file. This is also where your changesets will live.\n   - `npx changeset init`\n\n3. Make changesets releases public\n   - Edit the `.changeset/config.json` file\n   - Change the `access` field to `public`. Setting it to public allows publishing your package to npm.\n      - `\"access\": \"public\"`\n\n4. Set `commit` to `true`\n   - In `.changeset/config.json`, change the `commit` field to `true`\n   - This will commit the changeset to your repository after versioning.\n      - `\"commit\": true`\n\n5. Set up a `local-release` script\n   - 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.\n   - Add a `local-release` script to your package.json with the following content:\n      - `\"local-release\": \"changeset version \u0026\u0026 changeset publish\"`\n\n6. Run `CI` in `prepublishOnly`\n   - This runs the CI process before publishing the package to NPM\n   - Add a prepublishOnly script to your package.json:\n      - `\"prepublishOnly\": \"npm run ci\"`\n\n7. Add a changeset\n   - Run the command to add a changeset:\n      - `npx changeset`\n   - Mark the release as a `patch`, `minor` or `major` release\n   - Give it a description e.g., \"Initial release\"\n   - This will create a new file in the `.changeset` folder with the changeset.\n\n8. Commit your changes\n   - Commit your changes to your repository\n      ```\n      git add .\n      git commit -m \"Prepare for initial release\"\n      ```\n\n9. Run the `local-release` script\n   - Run the command to release your package\n   - This will run your CI process, version your package, and publish it to npm.\n   - `npm run local-release`\n\n10. See your package on npm\n   - Go to `http://npmjs.com/package/\u003cyour package name\u003e`\n\n11. Further reading about Changesets\n   - [Changesets GitHub Action](https://github.com/changesets/action)\n   - [PR Bot](https://github.com/changesets/bot)\n\u003c/details\u003e\n\n\n## References\n\n- TSConfig Cheat Sheet \u003csup\u003e[[1]](https://www.totaltypescript.com/tsconfig-cheat-sheet)\u003c/sup\u003e\n- Changesets GitHub Action \u003csup\u003e[[2]](https://github.com/changesets/action)\u003c/sup\u003e\n- PR Bot \u003csup\u003e[[3]](https://github.com/changesets/bot)\u003c/sup\u003e\n- Dual Package Hazard \u003csup\u003e[[4]](https://github.com/GeoffreyBooth/dual-package-hazard)\u003c/sup\u003e\n\n@weaponsforge\u003cbr\u003e\n20250212\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweaponsforge%2Fmath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweaponsforge%2Fmath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweaponsforge%2Fmath/lists"}