Publishing a JavaScript library as an NPM package

I never imagined that publishing a simple JavaScript “library” as an NPM package could be complicated … But hell it was! Most likely the reasons for finding it pretty complicated can be found in the fact that I’m a bit impatience.

For the next example you can have a look at the wpo365-fxlib library over at gibhub. It’s a simple helper library that I’ll be using soon in combination with the wpo365-login plugin for WordPress to allow client applications developed in React to request access tokens for Microsoft Office 365 services such as Graph, SharePoint Power BI etc.

Since my library is not a single (or multiple) page app, it doesn’t necessarily has a logical entry point. And to make it more challenging, the library’s core functions are in multiple files that by default will result in multiple exported (commonjs) modules. For this reason I’ve added a the index.ts to have an artifical entry point into the library (which can be thought of as the public API of a DLL class). In addition, to output a DLL type JS library, it turned out that I needed to update the webpack.config.json by adding the following two lines to the output property:

...
library: 'wpo365-fxlib',
libraryTarget: 'umd'
...

Obviously, since using TypeScript, I also wanted the library to bring its own typings to the table. This proofed to be the hardest part. Simply updating the tsconfig.json and setting

...
"declaration": true
...

isn’t enough. This will generate a d.ts (TypeScript definition file) for each .ts file. But similar to the JS library being bundled together, I also needed the type declarations to be bundled. The solution I found – probably a bit hacky – was using dts-bundle in a rather creative way. Having read their README file it seemed that I could implement the following build steps:

  1. Run webpack to bundle my JS files and create a d.ts file per .ts file
  2. Delete the index.d.ts file (to avoid redeclarations)
  3. Run dts-bundle –name wpo365Fx –main src/lib//*.d.ts –out ../../index.d.ts –outputAsModuleFolder** to bundle all remaining d.ts files into a single index.d.ts (without declaring an additional module by using the outputAsModuleFolder switch) that is placed right next to the main index.js bundle
  4. Delete all the remaining d.ts files

I have implemented those steps as custom build steps in the scripts section of the package.json file and now I can create a library simply by typing npm run build

You May Also Like

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: