@weaponsforge/math
v1.0.4
Published
Simple math operations for testing publishing to the NPM registry.
Readme
math
Simple math operations for testing publishing to the NPM registry from totaltypescript.
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 correcttsup, which compiles your TypeScript code to JavaScriptvitest, 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.
1. Git
- Initialize the repo
- Setup a .gitignore
- Create a new repository on GitHub
- Push to GitHub
2. package.json
- Create a package.json file
- Add the license field
- Add a LICENSE file
- Add a README file
3. TypeScript
Install TypeScript
npm install --save-dev typescriptSetup a
tsconfig.jsonfileConfigure your
tsconfig.jsonfor the DOM- If your code runs in the DOM (i.e. requires access to
document,window, orlocalStorageetc), 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):
{ "compilerOptions": { /* other options */ "lib": ["es2022"] } }- If your code runs in the DOM (i.e. requires access to
Create a source file
/src/utils.ts
Create an index file
/src/index.ts
Set up a
buildscript"build": "tsc"
Add
distto.gitignoreSet up a
CIscript"ci": "npm run build"
4. Prettier
Install Prettier
npm install --save-dev prettier
Set up a
.prettierrc{ "semi": true, "singleQuote": true, "trailingComma": "all", "printWidth": 80, "tabWidth": 2 }Set up a
formatscript"format": "prettier --write ."
Set up a
check-formatscript"check-format": "prettier --check ."
Adding to our
CIscript"ci": "npm run build && npm run check-format"
5. exports, main and @arethetypeswrong/cli
@arethetypeswrong/cli is a tool that checks if your package exports are correct
Install
@arethetypeswrong/clinpm install --save-dev @arethetypeswrong/cli
Set up a
check-exportsscript"check-exports": "attw --pack ."
Setting
mainAdd amainfield to your package.json with the following content:"main": "dist/index.js"
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.Adding to our
CIscript"ci": "npm run build && npm run check-format && npm run check-exports"
6. Using tsup to Dual Publish
"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". - totaltypescript
- Install
tsupnpm install --save-dev tsup
- Create a
tsup.config.tsfile - Change the
buildscript"build": "tsup"
- Add an
exportsfield in the package.json{ "exports": { "./package.json": "./package.json", ".": { "import": "./dist/index.js", "default": "./dist/index.cjs" } } } - Run `npm run check-exports'
6.1. Turn TypeScript into a linter
"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
Add
noEmittotsconfig.json"compilerOptions": { "noEmit": true }Remove unused fields from
tsconfig.jsonThese are no longer needed in our new 'linting' setup.outDir rootDir sourceMap declaration declarationMapChange
moduletoPreserveChangemoduletoPreservein the tsconfig.json."compilerOptions": { "module": "Preserve" }We can start importing TS files without
.jsextensions with this setting, e.g.:import { addition } from './utils'Add a
lintscript"lint": "tsc"
Add
lintto yourciscriptnpm run build && npm run check-format && npm run check-exports && npm run lint
7. Testing with Vitest
vitest is a modern test runner for ESM and TypeScript.
Install
vitestnpm install --save-dev vitest
Create a test
- Create a
src/utils.test.tsfile with the following content:import { add } from "./utils.js"; import { test, expect } from "vitest"; test("add", () => { expect(add(1, 2)).toBe(3); });
- Create a
Set up a
testscript- Add a
testscript in the package.json file"test": "vitest run"
- Add a
Run the test script
npm test
Set up
devscript- This step runs tests in watch mode while developing. Add the following the package.json file.
"dev": "vitest"
- This step runs tests in watch mode while developing. Add the following the package.json file.
Adding to our
CIscript.- Add the
testscript to yourciscript"ci": "npm run build && npm run check-format && npm run check-exports && npm run lint && npm run test"
- Add the
8. Set up CI with GitHub Actions
- Create a
.github/workflows/ci.ymlfile- Refer to the file in the code repository.
- Testing our workflow
- Push the file to the repository.
- Workflow should run on push
9. Publishing with Changesets
"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
Install
@changesets/clinpm install --save-dev @changesets/cli
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
Make changesets releases public
- Edit the
.changeset/config.jsonfile - Change the
accessfield topublic. Setting it to public allows publishing your package to npm."access": "public"
- Edit the
Set
committotrue- In
.changeset/config.json, change thecommitfield totrue - This will commit the changeset to your repository after versioning.
"commit": true
- In
Set up a
local-releasescript- 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-releasescript to your package.json with the following content:"local-release": "changeset version && changeset publish"
Run
CIinprepublishOnly- This runs the CI process before publishing the package to NPM
- Add a prepublishOnly script to your package.json:
"prepublishOnly": "npm run ci"
Add a changeset
- Run the command to add a changeset:
npx changeset
- Mark the release as a
patch,minorormajorrelease - Give it a description e.g., "Initial release"
- This will create a new file in the
.changesetfolder with the changeset.
- Run the command to add a changeset:
Commit your changes
- Commit your changes to your repository
git add . git commit -m "Prepare for initial release"
- Commit your changes to your repository
Run the
local-releasescript- 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
See your package on npm
- Go to
http://npmjs.com/package/<your package name>
- Further reading about Changesets
References
@weaponsforge 20250212
