Publishing a real NodeJS package: Project Bootstrap
For one of my TypeScript projects, I have needed a Windows-compatible unzip tool. I haven’t found one, which has a d.ts declaration file. So I decided that I will implement a zip/unzip NodeJs package with build-in TypeScript declarations.
Of course, it would be easier to write a declaration file for one of the existing tools, but a step-by-step guide about publishing a NodeJS package would be more useful.
Due to the length of the topic, I split the guide into four articles:
- Project Bootstrap
- Implementation and Testing
- Code Quality Improvements
- Publish with GitHub Actions
1. Create a public GitHub repository
If it is done, clone the repository into your local machine, with the following command:
git clone https://github.com/<your_username>/<your_repo_name>.git
2. Initialize the NodeJS package
Open a terminal in the project folder, and generate a package.json
file with the npm init -y
command. Edit the created file as it is in the following snippet:
...
"version": "0.0.0",
"author": "<your_name>",
"license": "MIT",
"keywords": [
"nodejs",
"javascript",
"windows",
"zip",
"unzip"
],
"main": "dist/index.js",
"types": "index.d.ts",
"files": [
"dist"
],
...
3. Installing and configuring dependencies
In this project, we will need these tools:
- Babel for compiling the source code of the project,
- Jest for running tests,
- rimraf for keeping our work directory clean,
- and standard-version for making the versioning easier.
Install them with the following command:
npm i -D @babel/cli @babel/core @babel/preset-env jest rimraf standard-version
If everything is installed, we need to configure Babel and Jest by adding these two files to the project’s main directory:
.babelrc
{
"presets": ["@babel/preset-env"]
}
jest.config.json
{
"testEnvironment": "node",
"testRegex": "/test/.*\\.(test|spec)?\\.js$",
"moduleFileExtensions": ["js", "json", "node"]
}
4. Updating the scripts in package.json
Long story short:
...
"scripts": {
"test": "jest",
"prebuild": "rimraf dist",
"build": "babel src --out-dir dist",
"release": "standard-version",
"postrelease": "git push --follow-tags origin main",
"prepublishOnly": "npm run build"
},
...
And also here is the long story:
test — Runs tests with Jest.
prebuild — Runs BEFORE build
and rimraf deletes the dist directory.
build — Runs Babel and compiles the source files into the dist directory.
release — Runs standard-version for versioning and generating CHANGELOG.md file. This tool should be used with Conventional Commits.
postrelease — Runs AFTER release
and pushes standard-version’s modifications into the project’s git repository.
prepublishOnly — Runs BEFORE publish
and makes a new build, just to prevent us from publishing an empty package.
5. Writing some code and tests
Let’s start simple. Just declare our functions and their arguments in the src/index.js
file:
function zipSync(path, dest) {
}function unzipSync(path, dest) {
}module.exports = {
zipSync,
unzipSync
};
also, write some simple tests in the test/index.test.js
file:
const { zipSync, unzipSync } = require('../src');describe('Test', () => {
test('zipSync should be truthy', () => {
expect(zipSync).toBeTruthy();
}); test('unzipSync should be truthy', () => {
expect(unzipSync).toBeTruthy();
});
});
and of course, the most important is the index.d.ts
file:
export declare function zipSync(path: string|string[], dest: string): void;
export declare function unzipSync(path: string, dest: string): void;
Now we can run the build: npm run build
or the test: npm test
. Both should run without any error.
6. Publishing v0.0.1
Yep, we don’t have a finished package yet, but nevertheless, it is worth publishing the 0.0.1 version just to reserve the name of our new package on npmjs.
The first thing we should do is to push everything that we created into the git repository:
git add .
git commit -m "chore: init package"
git push
As you can see, the commit message follows conventional commit rules. This helps to standard-version
to “figure” out the next version for the package.
Now run the release script:
npm run release
The standard-version will update the CHANGELOG.md and the package version. The postrelease
script will push these modifications into the git repository with a new version tag.
Just to make sure that we don’t publish any unnecessary files in the package, run the npm pack
command. The node will generate the tar file of the package without publishing it. If the content of this archive is okay, we can publish our new package:
npm publish
Here is the result on npmjs.com:
If you enjoyed this article, please share, give a few claps, and the most important stay tuned for the next one, which will about the implementation and testing of the windows-zip tool.
Thanks for reading!