A demo to show you how you can deploy your first TypeScript registry to jsrepo.com.
Within is an example of an over-engineered calculator to help demonstrate how jsrepo works.
- Have an account on jsrepo.com
In this tutorial we will cover how to build and publish a simple TypeScript registry to jsrepo.com.
Start by initializing a TypeScript project (I will use pnpm for this)
pnpm init
pnpm install typescript -D
pnpm tsc --initNow lets create some components that we want to share.
Lets create a ./src directory and within it we can create a /utils folder.
Your project should now look something like this:
root
├── /src
│ └── /utils
├── package.json
└── tsconfig.json
Now let's add our components.
calculator.ts:
import { Logger } from "./logger";
export class Calculator {
add(a: number, b: number): ArithmeticResult {
return new ArithmeticResult(a + b);
}
subtract(a: number, b: number): ArithmeticResult {
return new ArithmeticResult(a - b);
}
}
export class ArithmeticResult {
private val: number;
private logger = new Logger();
constructor(result: number) {
this.val = result;
}
print() {
this.logger.success(`The answer is ${this.val}!`);
}
get value() {
return this.val;
}
}logger.ts:
import color from "chalk";
export class Logger {
private logger: typeof console.log;
constructor(logger = console.log) {
this.logger = logger;
}
success(msg: string) {
this.logger(`${color.cyan("[success]")} ${msg}`);
}
failure(msg: string) {
this.logger(`${color.cyan("[failure]")} ${msg}`);
}
}Now that we have our components let's configure jsrepo to publish our registry to jsrepo.com.
Start by running the init command:
pnpm dlx jsrepo init --registryWhen asked "Where are your blocks located?" answer ./src because that is where our categories are.
Answer yes to "Configure to publish to jsrepo.com?" and then input the name of your registry.
The name of the registry should be in the format of
@<scope>/<name>. If you don't already have a scope you can claim one here.
┌ jsrepo v2.0.0
│
◇ Where are your blocks located?
│ ./src
│
◇ Add another blocks directory?
│ No
│
◇ Configure to publish to jsrepo.com?
│ Yes
│
◇ What's the name of your registry?
│ @example/typescript
│
◇ Added script to package.json
│
◇ Wrote config to `jsrepo-build-config.json`
│
├ Next Steps ─────────────────────────────────────────────────────┐
│ │
│ 1. Add categories to `./src`. │
│ 2. Run `pnpm run release:registry` to publish the registry. │
│ │
├─────────────────────────────────────────────────────────────────┘
│
└ All done!
Now your registry should be ready to publish!
Now that your registry has been configured to publish to jsrepo.com let's authenticate to the jsrepo CLI.
jsrepo auth
# or
jsrepo auth --token <...>Once you are authenticated let's do a dry run to make sure we got everything right:
jsrepo publish --dry-runIf all went well you should see:
◆ [jsrepo.com] Completed dry run!
See it? Great! Now let's do it for real!
jsrepo publishAnd there you go you published your first registry to jsrepo.com.
Now you can access your components through the jsrepo CLI.
jsrepo init @example/typescript
jsrepo add # list components
jsrepo add utils/calculator # add individualand from the jsrepo.com page for your registry located at https://jsrepo.com/@<scope>/<name>.
Now let's do a few things to improve our registry.
First of all when we run the jsrepo add command right now to list our components we see calculator and logger. Since logger is just an internal helper for calculator why don't we prevent it from coming up on this list.
We can do this with the doNotListBlocks key in our jsrepo-build-config.json file:
Now when we list our blocks only calculator will appear.
Alternatively if we had more internal utils we could use
listBlocksand only includecalculatorto prevent others from showing up here.
jsrepo.com uses metadata you provide in your jsrepo-build-config.json to display on your registries homepage.
{
// -- snip --
"meta": {
"authors": ["Aidan Bleser"],
"bugs": "https://github.com/jsrepojs/example-typescript",
"description": "A demo to show you can you can deploy your first typescript registry to jsrepo.com",
"homepage": "https://github.com/jsrepojs/example-typescript",
"repository": "https://github.com/jsrepojs/example-typescript",
"tags": ["registry", "typescript", "example", "jsrepo"]
},
// -- snip --
}Another thing you may want to setup if you are publishing a registry to jsrepo.com is changesets.
Changesets are an awesome way to manage the versioning of your registry let's set them up here.
pnpm install @changesets/cli -D
pnpm changeset initNow that you have changesets initialized let's make a small modification to the .changeset/config.json file:
{
// -- snip --
+ "privatePackages": {
+ "tag": true,
+ "version": true
+ }
}Let's also modify our package.json so that our release get's tagged when we publish a new version:
{
// -- snip --
"scripts": {
+ "release:registry": "jsrepo publish && changeset tag"
}
// -- snip --
}And finally let's modify our jsrepo-build-config.json file to use the version from our package.json:
You'll want to make sure that the version in your
package.jsonmatches the version in yourjsrepo-build-config.jsonbefore continuing.
{
// -- snip --
+ "version": "package",
// -- snip --
}Finally let's create a workflow so that we can publish a new version of our registry whenever there are changesets.
If you are publishing from a workflow make sure to create a token here and add it with the name
JSREPO_TOKENunderSettings / Secrets and variables / Actions
.github/workflows/publish.yml
name: Publish
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Build & Publish Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@v1
with:
commit: "chore(release): version package"
title: "chore(release): version package"
publish: pnpm release:registry
env:
JSREPO_TOKEN: ${{ secrets.JSREPO_TOKEN }} # !! DON'T FORGET THIS !!
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_ENV: productionNow lets create a changeset:
pnpm changesetNow once we commit our changeset to main changesets will automatically open a PR and version our package for us to create a release.
{ // -- snip -- "doNotListBlocks": ["logger"] // -- snip -- }