Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

The Pragmatic Guide to Your First JavaScript Library

Sameer KumarFollowBetter Programming--ListenShareJavaScript libraries! Every man and his dog has a node_modules folder full of them. This article will be more or less a pragmatic guide to writing these without going neck-deep in history and theory. Let’s get started.First of all, a bit of pseudo-nomenclature. For all intent and purposes, we will classify libraries into two sections:Intuitively, it’s clear that building utilities is easier than building components because of the technical stack’s width involved. What the particular Library internally does is beyond our scope. We will focus on how to pack, distribute, and use them.Remember, in most cases a good library is a decoupled section of your Application that you want to distribute to others.You can get the idea by looking at the example application I have set up. Codes living in the lib folder, don’t directly link to the business logic of the main application.For our first example, we are building a utility library that returns a random ninja’s name using a highly complex randomization logic. Let’s look at the file contents:Looks good. Let’s try to run it. A flying brick received right in the face. Hey, we are positive people. We are going to look into it. No worries!The error looks straightforward. Let’s try to look into the second suggestion before dialing into the whole node_modules ecosystem. We are going to rename those JS files to the mjs extension. And voila! It works. Even the HTML example started working as expected after changing the extension of the referenced file there.For its help, mjs definitely deserves a discussion here. MJS is an acronym for Modular JavaScript.So, officially, there are two flavors of JavaScript: one regular one and another that imports and exports modules “natively.” There are technical differences in their internal implementation and scope resolution, but let’s not get ahead of ourselves.MJS is newer and may not work in a Neanderthal’s machine running Internet Explorer, but for common masses, its good to go.Now, we’re revisiting the previous suggestion of using a package.json file. Apart from the internal cons of mjs, the main reason for the former approach being widely accepted is because of more familiarity with devs and machines.We rolled back those mjs extensions to regular js files and added this bare-bone package.json file at the root of our project. Notice we mentioned it’s a module here. Everything works as expected!This lib folder is now ready for shipping. You can push it to GitHub or npm. Each platform has a very easy quick start guide to publish there; nothing too technical involved. Your users get exactly what you have written in the lib folder — no surprises packaged. This works well depending on the complexity of your library and how much less it depends on other libraries.Now that we have written something, we want to distribute it to other folks in a clean “packaging.” After all, we just added a package.json file, so the name should carry the weight.A module/library can be packaged in a few well-accepted formats. Some techniques are:UMD is a versatile module format that works in all environments, including in the browser. It provides a way to create modules that can be used with minimum expectations from the consumer.Forget the mumbo-jumbo, remember the script tag from the golden days. You’ll go for this packaging if you want to simply import in an HTML file and move on like we used to in our beloved jQuery. Here’s what that looks like:ECMAScript Modules (ESM) are a native module system for JavaScript, and modern browsers and Node.js support them. They use import and export statements to define and load modules.We have already done an example of this format in our previous ninja finder example. Here’s the code:CommonJS is a module system used primarily in Node.js. It uses the require and module.exports (or exports) syntax to define and import modules.No wonder you have seen it once or twice. It is the predecessor to the ES6 import/export syntax we used in our above example. It is slowly fading out of even the backend development ecosystem in favor of the ES6. You must have seen it in Express apps.It’s very important to consider this packaging format if you are shipping your library for both frontend and backend.Many more of these formats are custom-tailored for specific use cases, but the above three should be good enough for us potato developers. ;)Honorable mentions should extend to SystemJS and AMD (Asynchronous Module Definition) as well.Now, the real fun starts. You don’t want the user to import 42 separate js files to handle other files that need to be imported. To be honest, your user won’t take a look at your library either. It should be as close to a one-click installation as possible. As seen in the UMD example above, we added a ton of jQuery features just by adding one line of script tag.Some common bundling toolchains build your application/library into an optimized distributable bundle. The strategy can vastly differ from everything bundled into a single js file or split into chunks that automatically load when needed. A few big names in this game are:Each one has its own nuances, but for us, all are doing the same work of bundling. Some are faster, some are more extensible, some are more supported, etc.For our purpose, nothing matters. When choosing one for your project, you’ll do deep analysis for sure. One that I can suggest, which works well, is a tool called Vite. Vite is not a bundler but a build framework that internally uses esbuild and Rollup for bundling. Let's implement it in our ninja application.Adding Vite is super simple. Let’s add it to our package.json file. Notice the scripts and devDependencies sections. Run npm install or yarn to install the new dependencies we added. Here’s what that looks like:With it installed, we are ready to roll with all the goodies with Vite, especially my favorite, hot reload. Before we start our dev server, let’s make some changes so the code will accept Vite.By default, Vite looks for the index.html file in the root directory, so we are good there for now. Let’s simplify the HTML a bit by adding the following code:That is all. Nothing else is needed to run the application. We can start the application by doing npm run dev or yarn dev. A local server will run and manage our application on a certain port 5173 by default. All properties of Vite can be configured by adding a vite.config.js file at the project’s root.The application can be optimized and built by running npm run build or yarn build. It creates a distribution folder, dist, which contains one HTML and js file that encapsulates the entire application. Even if we add ten more files, the output will still produce the same two files. And hence came the name of the process, bundling.Hey, hey, hey, where did we go in the flow? We were building a library, not another single-page application. Oopsies, my bad!Let’s add the vite.config.js file we talked about earlier. Here, we instructed Vite to build a library and also pointed to the main file of our library, as you can see below:Upon running the build command again, we see that now the dist folder only contains the library we want to ship — thankfully, in two flavors by default. ninja.es.js works better as an npm package but ninja.umd.js will be better as a script tag. Note that we can configure it to churn out other formats, too.Let's chime into the magic now. Here, we added a new demo.html file that has literally no connection to our application. We got our application working by importing it as a simple js script, not even type=“module”.Let’s get “modern” and use ESM build as well. Works like a charm.Though this may look similar to what we were doing earlier, on the bright side, this one import can have hundreds of files clubbed and optimized in a single unit.After going through all the foundational work, we are now ready to get into the real deal. Let’s imagine we are building a notification library of sorts. Calling js functions only is not going to suffice. We need to do some HTML of our own and, in turn, hook it to the user’s DOM as well.Vite or any other build system can only bundle JavaScript as its core functionality. Our requirements have overgrown our capabilities. Anyway, let's give it a shot. We’ll make sure not to go in the same single-page application direction again.We will display a message on the screen without end user intervention by using our own HTML. This can vary from a simple text to a self-contained application. Here’s what the code looks like:Okay, all done. This setup will smoothly bring the component we created in our library to the consumer application. I played a trick regarding HTML files. Did you notice?Using the above import syntax, we can inject HTML into the js file as if it were a raw string. This is super powerful in bundling because our bundler will otherwise error out, saying that it doesn’t identify the HTML file type. Makes sense, it is a JavaScript bundler, after all.Rest assured, it builds correctly, and we get the same single-file builds in our dist folder, one for umd, and one for esm.The last piece is all about fusing our styles. CSS is a world with dozens of build systems just like JavaScript. One sane thing to do here is pray to our overlord, Vite, to manage it somehow. Luckily, Vite has a rich ecosystem of plugins (actually, esbuild and Rollup plugins).Here, we have added one such plugin, vite-plugin-css-injected-by-js, that injects all CSS used in the library’s js files directly into the bundle, which will create a host application.Adding some random stylesAnd it works, no doubts there. The dist folder still consists of just a single JavaScript output, which contains HTML, CSS, and JavaScript, ready to be imported into the host application with zero configuration. If you have a larger library, then it will be better to keep bundles split for performance gains.I hope this walk-through was somewhat helpful. There is a lot of tooling around single-page applications mainly due to the popularity of the mighty three: Angular, React, and Vue.This guide is a bare minimum boarding point to help you explore the library. If you are/get stuck somewhere, feel free to reach out. Good luck. Craft something helpful!Get the full code at this link.----Better ProgrammingWorking as Technical Consultant at Tarka Labs, India. I love Coding, Travelling and Teaching. 😇Sameer KumarinBetter Programming--7VinitainBetter Programming--36Benoit RuizinBetter Programming--206Sameer Kumar--1Harshit Gambhir--Yuri BettinStackademic--4Mohamed Amine HAINEinJavaScript in Plain English--23Sanjay PriyadarshiinLevel Up Coding--20Emma Delaney--1Patrick Karsh--HelpStatusAboutCareersBlogPrivacyTermsText to speechTeams



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

The Pragmatic Guide to Your First JavaScript Library

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×