Parcel 2 has just been released and along with it comes some improvements on top of the zero configuration experience we already know and love.
The zero-configuration capability draws massive appeal when writing and maintaining your own NPM packages.
In today's post, we'll look at how to build a small TypeScript NPM package using Parcel 2 and then install it into another NPM project to see it in action.
Note: this post will be deploying a GitHub NPM package. It will not cover the requires from an older post about creating your first GitHub NPM Package, but you will still be able to follow along. It is very similar for publishing NPM packages in general.
Source code for the final package can be found here and the example project that uses the package here
First, we will create our project that contains our package code.
$ mkdir hello-parcel-2-npm-packages
$ cd hello-parcel-2-npm-packages
# Create a src directory to host the package contents
$ mkdir src
# initialise npm project with basics
$ npm init -y
$ npm install --save-dev parcel @tsconfig/recommended
# Create the required working files and a TypeScript configuration file
$ touch src/index.ts src/math.ts tsconfig.json
At this stage, our project is now ready to start working with.
Something worth noting: we are not actually installing TypeScript yet. We will see later that Parcel can do that for us based on the configuration requirements that it detects! You can of course install this yourself, but I wanted to demonstrate how helpful Parcel can be.
The library @tsconfig/recommended that we installed comes with configuration files that are recommended for use. Since this is a simple example, we will use the recommended configuration by using the extend keyword in our local tsconfig.json file.
Add in our library files
We are going to build an unbelievably contrived "math" library that will only contain the functions add, subtract, divide and multiply.
I use this contrived example as it is a good example of how to use TypeScript and Parcel to build a package.
Within src/math.ts, add the following:
/**
* Adds two numbers together.
*
* @param x First argument.
* @param y Second argument.
* @returns Result of addition.
*/
export const add = (x: number, y: number): number => x + y;
/**
* Subtract the second argument from the first.
*
* @param x First argument.
* @param y Second argument.
* @returns Result of subtraction.
*/
export const subtract = (x: number, y: number): number => x - y;
/**
* Multiplies two numbers together.
*
* @param x First argument.
* @param y Second argument.
* @returns Result of multiplication.
*/
export const multiply = (x: number, y: number): number => x * y;
/**
* Divides the first argument by the second.
*
* @param x First argument.
* @param y Second argument.
* @returns Result of division.
*/
export const divide = (x: number, y: number): number => x / y;
I won't explain the above: it is simple arithmetic. We are just exporting contrived versions of the functions.
We will let index.ts be the entry to our package, so inside of that file we will want to export those functions:
export { add, subtract, multiply, divide } from "./math";
I am being explicit with my export statement here (in case we have any functions we don't accidentally want to export), but you can also just export the whole math file for our example.
At this stage, we are almost ready to build our package.
Setting up package.json for Parcel 2 and the GitHub NPM registry
Finally, the last thing we want to do is setup some key-value pairs in our package.json file. Mine will look like the following:
I've set the package name to @okeeffed/hello-parcel-2-npm-packages which will be what we export from in our example project.
The source key tells Parcel where the entry to our project is.
main. is the target output file of our build as CommonJS while module is our destination for an ES module. See more here.
types is the destination for the TypeScript definition file. Parcel will manage this for us!
Under scripts, we add a watch script to run Parcel in watch mode for development, and a build script to build your project for release.
At this point, we already just want to build, so run npm run build in your terminal.
You will notice in the output that Parcel lets you know that it detected the package and installs everything it needs. Once installed, you will then get the output from the build:
$ npm run build
> @okeeffed/hello-parcel-2-npm-packages@1.0.0 build
> parcel build
✨ Built in 115ms
dist/main.js 794 B 48ms
dist/module.js 525 B 38ms
dist/types.d.ts 826 B 37ms
Amazing! We see our three files being build out.
If we go back and check out package.json file now, we will see a change to our devDependencies which Parcel managed for us based on the detected configuration:
It installed typescript along with the required @parcel/* namespace packages.
Publishing the package
I already have everything configured that I need to publish my package to the GitHub repository under the @okeeffed namespace, so I can just run npm publish.
There isn't anything too special here, but know that we have a script dev that will run our index.ts file with Node.js after letting SWC Node handle the transformation.
Finally, it is time to installed our package.
$ npm install @okeeffed/hello-parcel-2-npm-packages
added 1 package, and audited 2 packages in 2s
found 0 vulnerabilities
Again, I already have the configuration for my ~/.npmrc file to be allowed to publish and install from that namespace.
Here I am use calling our main function to run our code which logs out examples of all of our functions.
While you are here, begin to play around with the imports and functions. Notice that because Parcel handled the type output, we are already getting type information for our functions.
First type error for no arguments.
Second type error for invalid arguments.
Finally, if we run npm run dev we can see our desired output and the package working as expected:
$ npm run dev
> hello-parcel-2-npm-packages-using-pkg-example@1.0.0 dev
> node -r @swc-node/register index.ts
3
1
4
1
Summary
Today's post demonstrated how awesome Parcel 2 can be. It makes life super easy when you can focus on the code and let it handle the output.
We built a (super contrived) package as a demonstration and installed it into another project to see the results of the output from Parcel 2.
I strongly recommend that you check out the Parcel documentation for more information on how to use Parcel and have a play around! I certainly will be updating a few of my repos to let Parcel handle the hard work.