In this article I will show you how to create React module on Typescript, create demo page, description for it and publish as node package. We will use Eslint, Jest, Prettier, github pages for demo-page and github-actions to setup automated builds in releases.
Introduction
Why did I decide to write one more article about publishing npm-packages? When I needed to create such a package by myself, I found that most of the instructions on the Internet were either outdated or very short and useless in production.
I will try to describe all the steps as clear as I can, so you can create your own project from the scratch. Let’s get started!
I propose to create a simple react application, which will consist of two buttons that increase or decrease the value of the counter.
This is how our application will look like:
Demo: https://gapon2401.github.io/my-react-typescript-package
Repo: https://github.com/gapon2401/my-react-typescript-package
We have 14 steps to deal with everything:
- Preparing the project
- Create your react application
- Configure git
- Configure ESLint
- Configure Prettier
- Adding tests with Jest
- Configure package.json and prepare for publishing
- Commit and push your code
- Publishing to NPM
- Creating of the example folder
- Setup automated builds
- Demo page
- README.md file and shields.io
- Making release
Step 1. Preparing the project
- In command line of your project execute:
npm init -y
It will create package.json
file with default values, we will change it a bit later.
- Create folder
src
Here we will keep all project files.
- Add React and Typescript to the project (I’m going to use
yarn
, if you don’t mind)
yarn add -D react react-dom typescript @types/react
Now we have node_modules
folder and a yarn.lock
— not bad!
- In order to compile typescript, create a
tsconfig.json
file in the project root with the contents
{
"include": ["src"],
"exclude": [
"dist",
"node_modules"
],
"compilerOptions": {
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"outDir": "./dist/esm",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
}
}
You can take a look at all possible properties here: https://www.typescriptlang.org/tsconfig
From the main:
-- rootDir
— the root folder within your source files,
-- include
— specifies the files to be included in the TypeScript project,
-- exclude
— specifies the files to be excluded in the TypeScript project. We don’t want to include dist folder and all node_modules ,
-- outDir
— this is the location for the compiled output
- Create empty
README.md
andLICENSE
files.
It’s up to you what license to use. I will use MIT, you can check the contents of that file.
Take a look at the structure we should have:
Step 2. Create your react application
Inside src
create the folder components
. There you can keep all the components of your project. We will create here within this article only one file App.tsx
with the contents:
import React, { useState } from 'react'
type Props = {
value?: number
}
const MyCounter = ({ value = 0 }: Props) => {
const [counter, setCounter] = useState(value);
const onMinus = () => {
setCounter((prev) => prev - 1)
};
const onPlus = () => {
setCounter((prev) => prev + 1)
};
return (
<div>
<h1>Counter: {counter}</h1>
<button onClick={onMinus}>-</button>
<button onClick={onPlus}>+</button>
</div>
)
}
export default MyCounter
This is our React application.
Now create file index.ts
inside src
folder. Export our module.
import MyCounter from './components/App'
export { MyCounter }
It’s time to compile the project! 🤗
Let’s change our package.json
and replace scripts
section:
{
"name": "my-react-typescript-package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc"
},
"keywords": [],
"author": "gapon2401",
"license": "ISC",
"devDependencies": {
"@types/react": "^18.0.12",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"typescript": "^4.7.3"
}
}
Run in terminal:
yarn build
Folder dist
should be appeared with all compiled code.
Congratulations! 🎉 We have created the application, which is compiled, a few more steps and we’re done! (no..)
Compare your project structure after step 2:
Step 3. Configure git
We quickly have created the project, now it’s time for the git.
Initialize git
in the root of the project
git init
Create file .gitignore
in project root with contents:
node_modules
.idea
dist
yarn-error.log
I added .idea
, because I’m developing with the help of Jetbrains IDE.
In .gitignore
we list those files, directories that we would like not to include in the repository.
Create git repo on github. Later we will create initial commit and connect remote git with our local git.
Step 4. Configure ESLint
ESLint statically analyzes your code to quickly find problems. We need it only in development.
Add eslint and all necessary components:
yarn add -D eslint eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser
You can configure it as you want, there is a big user guide: https://eslint.org/docs/user-guide/configuring/
I suggest you create an .eslintrc
file at the root of the project:
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"react",
"react-hooks"
],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off"
},
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"node": true
},
"globals": {
"JSX": true
}
}
Add .eslintignore
:
node_modules
dist
We will ignore checking dist
folder with compiled files and node_modules
.
Change package.json
, add to scripts
section:
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\""
Here is my package.json
:
{
"name": "my-react-typescript-package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc",
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\""
},
"keywords": [],
"author": "gapon2401",
"license": "ISC",
"devDependencies": {
"@types/react": "^18.0.12",
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"eslint": "^8.17.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"typescript": "^4.7.3"
}
}
Now, run:
yarn lint
You shouldn’t have any mistakes.
Compare your project structure after step 4:
Step 5. Configure Prettier
Prettier is a code formatter. It is convenient to use it when you work in a team so that everyone’s code meets the same standard.
In terminal run the command:
yarn add -D eslint-config-prettier eslint-plugin-prettier prettier
In project root create .prettierrc.json
:
{
"bracketSpacing": true,
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2,
"semi": false,
"printWidth": 120,
"jsxSingleQuote": true,
"endOfLine": "auto"
}
Read more about all options: https://prettier.io/docs/en/options.html.
Add prettier plugin to .eslintrc
:
{
"root": true,
"extends": [
"prettier",
"plugin:prettier/recommended",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"prettier",
"react",
"react-hooks"
],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off"
},
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"node": true
},
"globals": {
"JSX": true
}
}
We have finished the setup of prettier, now try to run yarn lint
in order to check formatting errors. If you don’t have any, so you didn’t pass the human test 😆
It’s time to fix them! Add to scripts
in package.json
:
"prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\""
Ok, run yarn prettier
and you will get something similar to:
Now after yarn lint
you should not have any errors. Check the files src/components/App.tsx
and src/index.ts
, they have changed.
My scripts
section in package.json
:
"scripts": {
"build": "tsc",
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\"",
"prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\""
}
Compare your project structure after step 5:
Step 6. Adding tests with Jest
For creating tests I’m using Jest library. It’s pretty useful and powerful testing framework. How difficult the tests will be, of course, is up to you.
Add jest
to your project:
yarn add -D jest jest-canvas-mock jest-environment-jsdom ts-jest @types/jest @testing-library/react
Create at the project root file jestconfig.json
:
{
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
},
"testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
"testEnvironment": "jsdom"
}
Create folder tests
.
Time to write our first test. We will write very simple test, which will check, that our render passed successful.
In folder tests
create file common.test.tsx
:
import * as React from 'react'
import { render } from '@testing-library/react'
import 'jest-canvas-mock'
import { MyCounter } from '../src'
describe('Common render', () => {
it('renders without crashing', () => {
render(<MyCounter />)
})
})
Change scripts section in package.json
:
"test": "jest --config jestconfig.json"
{
"name": "my-react-typescript-package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc",
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\"",
"prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\"",
"test": "jest --config jestconfig.json"
},
"keywords": [],
"author": "gapon2401",
"license": "ISC",
"devDependencies": {
"@testing-library/react": "^13.3.0",
"@types/jest": "^28.1.1",
"@types/react": "^18.0.12",
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"jest": "^28.1.1",
"jest-canvas-mock": "^2.4.0",
"jest-environment-jsdom": "^28.1.1",
"prettier": "^2.6.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"ts-jest": "^28.0.4",
"typescript": "^4.7.3"
}
}
Run yarn test
. You should pass the test:
Compare your project structure after step 6:
Step 7. Configure package.json and prepare for publishing
I suggest to split our build
. We will compile not only the ECMAScript module, but also the CommonJs module to make our package as accessible as possible.
In package.json
replace:
"build": "tsc",
With the following code:
"build": "yarn build:esm && yarn build:cjs",
"build:esm": "tsc",
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
We added build:esm
and build:cjs
and combined them in one command.
Run yarn build
and you will see, that our dist/
now has also a cjs
folder.
Go further.
In package.json
we can use magic scripts that are automatically called when the package is published. They will help us to check our package for all kinds of errors and not accidentally upload an update that will crash hundreds of thousands of projects in which our package will be used! 😜
-
prepare
— runs BEFORE the package is packed and published. Runs on local npm install without any arguments, -
prepublishOnly
— runs BEFORE the package is prepared and packed, ONLY on npm publish. Here will be our tests.
Add to scripts
section:
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run prettier && npm run lint"
Change the version
, description
.
Tell npm where it can import the main file of our project from, and also where all the types are located:
Replace:
"main": "index.js",
With:
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
Add information about remote git repository (specify your git url from step 3):
"repository": {
"type": "git",
"url": "git+https://github.com/gapon2401/my-react-typescript-package.git"
},
Specify that the project that will use our package must have a react version of at least >=16:
"peerDependencies": {
"react": ">=16"
},
To ensure that your package does not have any redundant files, use only allowed files and folders that will be added to the package:
"files": [
"dist",
"LICENSE",
"README.md"
],
Add keywords so everyone can find your project:
"keywords": [
"react",
"typescript",
"awesome-project"
],
Specify your license:
"license": "MIT",
Don’t forget to change the author
:
"author": "Igor Gaponov (gapon2401)",
I think that’s enough.)
Add description to your README.md
file.
For now I have only one row there. This is the h1:
# my-react-typescript-package
Take a look at the final version of package.json
:
{
"name": "my-react-typescript-package",
"version": "0.1.0",
"description": "My first react typescript package",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/gapon2401/my-react-typescript-package.git"
},
"scripts": {
"build": "yarn build:esm && yarn build:cjs",
"build:esm": "tsc",
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\"",
"prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\"",
"test": "jest --config jestconfig.json",
"prepare": "npm run build",
"prepublishOnly": "npm test && npm run prettier && npm run lint"
},
"peerDependencies": {
"react": ">=16"
},
"files": [
"dist",
"LICENSE",
"README.md"
],
"keywords": [
"react",
"typescript",
"awesome-project"
],
"author": "Igor Gaponov (gapon2401)",
"license": "MIT",
"devDependencies": {
"@testing-library/react": "^13.3.0",
"@types/jest": "^28.1.1",
"@types/react": "^18.0.12",
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"jest": "^28.1.1",
"jest-canvas-mock": "^2.4.0",
"jest-environment-jsdom": "^28.1.1",
"prettier": "^2.6.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"ts-jest": "^28.0.4",
"typescript": "^4.7.3"
}
}
Step 8. Commit and push your code
First of all, let’s connect remote and local repositories and push our project.
Run the following code:
git add .
git commit -m "Initial commit"
git remote add origin <Repository Url>
git push -u origin master
Don’t forget to change <Repository Url>
on yours. It can be https
url, or ssh
. This url you can get in your repository.
Take a look on examples, how it could be.
- HTTPS repository url (you will need to authorize)
git remote add origin https://github.com/gapon2401/my-react-typescript-package.git
- SSH repository url (you need to configure connecting with ssh)
git remote add origin git@github.com:gapon2401/my-react-typescript-package.git
I use the second solution.
Step 9. Publishing to NPM
- Choose the package name
We have to check that the name of our package is free to use. Go to the website https://www.npmjs.com/ and use search tool.
You can find and change default name of the project in package.json
:
In my case it my-react-typescript-package
. There is no such package yet.
I prefer to check this way: insert the name directly to the link
https://www.npmjs.com/package/<Your package name>
Instead of <Your package name>
use the name of your project.
I get the following url:
https://www.npmjs.com/package/my-react-typescript-package
If the name is free, you will see 404 page:
- Register/login to NPM
In order to publish the project you need to authorize in https://www.npmjs.com/.
If you don’t have account yet, go and register https://www.npmjs.com/signup or use command line:
npm adduser
You will be asked to enter username
, password
and email
.
If you already have an account, run:
npm login
And complete the authorization.
- Publishing
Before publishing, I recommend you to check that you will have only the necessary files in the package, there are no errors, everything is formatted correctly. For this you can run the command:
npm publish --dry-run
Package WILL NOT BE published, don’t worry.
You will see, that the “magic script” prepublishOnly
will be called and tests and code formatting will run.
Then you will get the list of all files, which will be included at the project:
In Tarball Contents
we have the files and folders, that were specified in package.json
:
"files": [
"dist",
"LICENSE",
"README.md"
],
Everything is fine, let’s publish the package!
Run the command:
npm publish
I always worry, when run this command 🤣
I am attaching the full result of the command call:
Now I can congratulate you!🎉 The package is published, it is public, it can be used by anyone! It wasn’t so hard 😉
Let’s take a look at the package on the NPM.
Open the link, we did it before.
https://www.npmjs.com/package/<Your package name>
Looks great! 🔥
Step 10. Creating of the example folder
Let’s keep making our package better and better. In this step we will create an example folder in which we will show how we can work with our package. In this folder, you can quickly start the server, play around with the code.
To quickly launch the application, we will use https://parceljs.org/.
Create a folder example
.
Inside that folder create empty folder src
and files:
-
.gitignore
:
node_modules
yarn.lock
.parcel-cache
dist
yarn-error.log
-
package.json
:
{
"name": "example",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "parcel src/index.html"
}
}
-
README.md
:
# How to start example page?
Then in the example directory, run all dependencies:
### `yarn install`
Then use the command:
### `yarn start`
Open [http://localhost:1234](http://localhost:1234) to view it in the browser.
Now pay attention! In the command line from the root of your project move into example folder:
cd example
Then run:
yarn add -D parcel my-react-typescript-package react react-dom @types/react-dom @types/react
Inside src
folder create the file index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Example page for my-react-typescript-package"
/>
<title>my-react-typescript-package</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script type="module" src="index.tsx"></script>
<div id="root"></div>
</body>
</html>
Now we need to import our package and create the example of how to use it.
Inside src
folder create index.tsx
file:
import React from 'react'
import ReactDOM from 'react-dom/client'
import { MyCounter } from 'my-react-typescript-package'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
<React.StrictMode>
<div>
<h2>Default counter</h2>
<MyCounter />
</div>
<hr />
<div>
<h2>Counter with predefined value</h2>
<MyCounter value={5} />
</div>
</React.StrictMode>,
)
Time to run the server! Use the command:
yarn start
You will have the following message after successfully starting the server:
Open the link http://localhost:1234 to watch the example:
Compare the example folder structure, after all installations and server running, it should look like this:
Step 11. Setup automated builds
Let’s get into automated builds. It’s rather inconvenient when you have to push changes to git, to npm with each release. We will automate this process with Github Actions.
Create at the root of the project structure the folder .github
.
Inside it create the folder workflows
.
Inside workflows
create the file publish.yml
:
# This is a name of the workflow
name: build
# Controls when the workflow will run
on:
# Triggers the workflow on published releases
release:
types: [published]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Checkout
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
uses: actions/checkout@v3
- name: Setup Node
# Setup node environment
uses: actions/setup-node@v3
with:
# Node version. Run "node -v" to check the latest version
node-version: 16.x
registry-url: https://registry.npmjs.org/
- name: Install dependencies
run: yarn && yarn install
- name: Build
run: yarn build
- name: Publish
run: yarn publish
env:
# We need this to our NPM account
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
The main points in the file have been commented.
When we will release to github, our package will be automatically built and pushed to NPM.
I want you to look at the line:
# We need this to our NPM account
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
This is the way we are going to connect Github with NPM.
In browser open your account on https://www.npmjs.com/, go to the page with tokens:
Generate new token:
You will be prompted to enter its name and select the type. Automation
is suitable for github-actions:
Copy your token and open the github repo.
Go to the tab Settings
, open Secrets — Actions
and create new repository secret variable. Give it a name NPM_TOKEN
and paste inside the value of the token from NPM:
Well done! Now it remains to create a new version of the project and push it to github.
Don’t forget before committing any changes to run:
yarn prepublishOnly
Just to make sure that your code will be nice and clean.
After you push the project, go to the Actions tab, where you will see that github has detected that you have workflow actions. But it hasn’t launched anything yet, because we haven’t made a release yet.)
Step 12. Demo page
We have already a folder with an example of using our package, but we would like to create a separate page so that the user can quickly see the package in action without having to clone the entire project. Let’s get on with this page!
We will use github-pages for creating the demo.
Create new git branch:
git checkout -b gh-pages
And now delete all the files from the project! 😱
Don’t worry, all previous files will stay safe in another master
branch. The branch gh-pages
will be used only for the demo, that’s why we need to delete all files. Come on, delete everything! 😈
Then in command line run:
npm init -y
This command will create file package.json
. We will not configure it in detail this time.
For demo page I suggest using parcel
, which is familiar for us (step 10)
Run:
yarn add -D parcel my-react-typescript-package react react-dom @types/react-dom @types/react typescript
Create file .gitignore
:
node_modules
yarn.lock
.parcel-cache
dist
yarn-error.log
Create file tsconfig.json
with contents:
{
"include": ["src"],
"exclude": [
"dist",
"node_modules"
],
"compilerOptions": {
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"outDir": "./dist/esm",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
}
}
Follow the step 4 to configure the Eslint.
Create empty folder src
. Inside it create file index.html
with the contents:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Demo page for my-react-typescript-package"
/>
<title>Demo page of my-react-typescript-package</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script type="module" src="./index.tsx"></script>
<div id="root"></div>
</body>
</html>
Create file index.tsx
:
Add to package.json
inside scripts
section:
"start": "parcel src/index.html",
"build": "parcel build src/index.html --dist-dir docs --public-url .",
Take a look at my package.json
:
{
"name": "my-react-typescript-package",
"version": "0.1.0",
"description": "Demo page of my-react-typescript-package",
"scripts": {
"start": "parcel src/index.html",
"build": "parcel build src/index.html --dist-dir docs --public-url .",
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/gapon2401/my-react-typescript-package.git"
},
"author": "gapon2401",
"license": "MIT",
"devDependencies": {
"@types/react": "^18.0.14",
"@types/react-dom": "^18.0.5",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"@typescript-eslint/parser": "^5.29.0",
"eslint": "^8.18.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.6.0",
"my-react-typescript-package": "^0.1.0",
"parcel": "^2.6.2",
"process": "^0.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^4.7.4"
}
}
Run the server to make sure, that everything works fine:
yarn start
Now run the code checking:
yarn lint
No errors! 🤗 Great! It’s time to build the page.
yarn build
You should see the folder docs
with all files of the demo project.
Here is the structure of the branch gh-pages
:
Now let’s push all the changes to git. Run:
git add .
git commit -m "Initial pages commit"
git push -u origin gh-pages
Open your github repository and go to Settings — Pages
. In the source
select /docs
and press Save
:
Wait about 3–5 minutes and your site will be available on the specified url, which is on your page:
We have done with the demo page. As you see, you can customize it however you want and create a page or website of any complexity.
Here is the result: https://gapon2401.github.io/my-react-typescript-package/
Step 13. README.md file and shields.io
Now when we’ve done with all the code, we can move to the description file of the package.
Switch to master
branch in git and open README.md
.
Replace contents with the following code:
For description file we are using markdown.
In README.md
I have added a short description of the package, link to demo-page and a usage section.
At the beginning of the readme file I have small cute icons, this is https://shields.io/. It is very convenient to have them. I’ve added just a couple as an example, you can use as many as you want.
Add shields.io
to your github applications.
Take a look at the end of the file, I’ve created variables with images and links. Markdown allows us to make such variables, so the description file looks more accurate. Don’t forget to change the path to your repo and the package name.
Change version in package.json
, make commit and push files to repository. Do everything by yourself, we’ve made it in previous steps.😉
Step 14. Making release
This is the last step. It will be short 🙌
We have done everything, what we planned! Now we can make an official release on github and also check how automated builds work.
Go to the main page of the repository and click Create a new release
:
Specify your current version as a tag, it will be created automatically on release. Print release title and description and click Publish release
.
Now open tab Actions
and make sure, that your build was successfully done.
Let’s check, that package was updated in NPM.
Open the package link:
https://www.npmjs.com/package/<Your package name>
I will open mine:
https://www.npmjs.com/package/my-react-typescript-package
You should see a new version with new description:
Congratulations! 🥳🎉👏 You are brilliant! 💎✨
It was a long journey, but I hope very useful. I tried to describe everything that I had difficulty with when I first published my package and collected this information piece by piece.
Thank you for reading! ❤️
Top comments (0)