- Published on
Create your own typescript library with Parcel.js
Overview
If you find yourself writing the same typescript code over and over again it might be time to put this code into a reusable package.
There are many ways of doing this. Bundlers like Rollup has been around for quite some time, but require quite a lot of setup. Modern alternatives like Parcel provides almost zero config out of the box but can also be configured if you have specific requirements.
- The finished code
- Getting started
- Install Parcel
- Define project configuration in package.json
- Create the entrypoint file in src/index.ts
- Setup a basic tsconfig.json file in the root of the folder
- Setup a .gitignore file in the root of the folder
- Add dev and build commands to package.json
- Add dependencies for basic linting
- Add a .eslintrc.js in the root of the project
- Add a .eslintignore in the root of the project
- Add a lint script to your package.json
- Add testing to your project with jest
- Add a test for your code in src/index.test.ts
- Add script for triggering tests and update package.json
- Prepare to publish your package to npmjs.com
- Add a .npmignore file in the root of the project
- Update your package name to include your npmjs.com username
- Publish your package to npmjs.com
The finished code
Getting started
mkdir parcel-library-starter
cd parcel-library-starter
npm init -y
Install Parcel
npm install --save-dev parcel
Define project configuration in package.json
{
"name": "@ihaback/your-typescript-lib",
"version": "1.0.0",
// The source field defines the entry point for your library
"source": "src/index.ts",
// The main field defines the target output of your library
"main": "dist/main.js"
// The types field will output a dist/types.d.ts file containing type definitions for your library
"types": "dist/types.d.ts",
// To add an ES module target, add the module field to your package.json
"module": "dist/module.js"
}
Create the entrypoint file in src/index.ts
// Chunk an array into smaller arrays of a specified size
export const chunk = (arr: Array<any>, size: number) => {
return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
arr.slice(i * size, i * size + size)
)
}
Setup a basic tsconfig.json file in the root of the folder
{
"compilerOptions": {
"target": "ES5",
"lib": ["ES2015"],
"types": ["jest"],
"esModuleInterop": true
}
}
Setup a .gitignore file in the root of the folder
node_modules
dist
.parcel-cache
.cache
coverage
Add dev and build commands to package.json
When you build
your package Parcel will automatically transpile your code into a dist
folder, and generate types that can be used in a repo that consumes this package. The dev
command is handy during development.
{
"scripts": {
"dev": "parcel watch",
"build": "parcel build"
}
}
Add dependencies for basic linting
npm i eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier eslint-config-prettier eslint-plugin-prettier @parcel/packager-ts @parcel/packager-ts @parcel/transformer-typescript-types -D
Add a .eslintrc.js in the root of the project
module.exports = {
env: {
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'prettier'],
rules: {
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],
},
}
Add a .eslintignore in the root of the project
node_modules
.parcel-cache
dist
.eslintrc.js
package.json
package-lock.json
coverage
Add a lint script to your package.json
{
"scripts": {
"lint": "eslint . --fix"
}
}
Add testing to your project with jest
npm i jest ts-jest @types/jest -D
Add a test for your code in src/index.test.ts
import { chunk } from '.'
describe('chunk', () => {
test('should chunk array into smaller arrays of a specified size', () => {
const bigArray = Array.from({ length: 100 }, (v, i) => i)
const chunkedArray = chunk(bigArray, 25)
expect(chunkedArray).toHaveLength(4)
})
test('should not chunck into multiple arrays if source array is less or equal to chunk size', () => {
const bigArray = Array.from({ length: 100 }, (v, i) => i)
const chunkedArray = chunk(bigArray, 100)
expect(chunkedArray).toHaveLength(1)
})
})
Add script for triggering tests and update package.json
{
"scripts": {
"test": "jest --coverage"
},
"jest": {
"preset": "ts-jest"
}
}
Prepare to publish your package to npmjs.com
Add a .npmignore file in the root of the project
**/.eslintrc.js
**/.eslintignore
**/.parcel-cache
**/.github/README.md
coverage
Update your package name to include your npmjs.com username
"name": "@your-username-here/your-package-name-here"
"name": "@ihaback/your-typescript-lib"
Publish your package to npmjs.com
npm login
npm publish --access public