DEV Community

Erik "Noaa" Engervall
Erik "Noaa" Engervall

Posted on

Entering open-source software

open source software

Credit: Getty

I've built free web-apps fulfilling various practical purposes (mostly silly) for quite some time, but it wasn't until fairly recently (~1 yr) that I started getting into open-source software (OSS). It has opened my mind to a whole new world and has had an enormous impact on my general understanding of JavaScript and its ecosystem. This extension of knowledge was partly thanks to contributing to open-source projects but even more so by simply reading a lot more source code written by other developers. The realization that all source code is written by mere mortals, and that it doesnโ€™t bite, caused the threshold for deep diving into libraries whenever issues arose to be significantly lowered.

Learnings

My OSS journey hasnโ€™t been without bumps in the road. But where thereโ€™s bumps, thereโ€™s learnings.

Git & npm: The Confusing Parts

npm tags

Git and npm has a lot of overlapping terminology which can be confusing at first. When starting out with developing my own projects I had a lot of assumptions as to how the two platforms interacted. For example, a misconception I had early on was that npm would interpret my libraries' versions and make contextual decisions, such as "marking" a release published as 0.0.1-alpha.0 as an alpha-release rather than a latest-release. However, even though 0.0.1-alpha.0 is completely valid semver, npm requires that one explicitly tag releases: npm publish --tag alpha.

A npm tag can be pretty much anything except for something resembling semver. For example,npm publish --tag ihavenoideawhatimdoing is completely valid:
npm tags

git tags

We just learned what a tag is in npm's world. What about Git?

A tag in Git is essentially a snapshot of a repository at a particular time in its history. Dealing with Git tags is fairly straightforward. The weirdest part is that the tag's name can be literally anything and doesn't have to conform to semver. Developers commonly use tags to help mark releases and thus, for sanity's sake, use their library's version as a Git tag (prefixed by v of course ๐Ÿคท๐Ÿผโ€โ™‚๏ธ):

# Create tag
git tag v0.0.1

# Push to repo (will turn up as a commit)
git push --tags
Enter fullscreen mode Exit fullscreen mode

TypeScript

Building your library in TypeScript?

typescript is supereasy

Expose your type declarations

There's a ton of options for compiling TypeScript projects. However, there's one in particular that'll make whoever depends on your library super happy ๐Ÿผ:

{
    "compilerOptions": {
        "declaration": true
    }
}
Enter fullscreen mode Exit fullscreen mode

This'll generate declaration files (file.d.ts) next to each JavaScript file outputted from the compilation that'll be exposed to your users when they import your library.

Fighting your IDE ๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป๐ŸฅŠ

The relevance of this particular tip may vary depending on your IDE.

There's a wide variety of IDE's out there, from those that give absolutely zero support whatsoever to those that borderline autocompletes your thoughts. My current IDE of choice, VS Code, is somewhere in the middle of this range. It is equipped with a bunch of debugging tools and a solid selection of extensions, improving developer experience via customizability. In a perfect world a developer wouldn't have to run e.g. ESLint's CLI but would solely rely on an extension that'd guarantee the same experience.

When developing TypeScript your IDE relies on your tsconfig.json to validate your code and highlight type errors. This behavior, as intended as it may be, causes some level of cumbersomeness when publishing your library to e.g. npm.

Why?

Well, hopefully, your project is blessed with at least one unit test. Ideally, tests shouldn't turn up in the distribution code, i.e. the dist, just as development dependencies shouldn't turn up in production. However, using exclude in your tsconfig makes VS Code a sad ๐Ÿผ and you'll see the errors such as:

Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try npm i @types/jest or npm i @types/mocha.

Sad VS Code

I haven't found any better workaround than to include all TypeScript files in my tsconfig.json and create a separate tsconfig.publish.json that'll be used when publishing to npm. This setup makes VS code happier...

Happy VS Code

...but forces developers to remember yet another detail before publishing: compile the dist using yarn tsc --project tsconfig.publish.json instead of simply yarn tsc.

Pipeline - automate automate automate

A colleague of mine who's an OSS wizard once recommended me to automate as much as I possibly could for my projects. Not being a huge fan of pipelines and such, I kindly nodded and postponed the advice as long as possible.

However, my patience finally got the best of me. I learned the hard way that a bunch of manual steps easily led to mistakes and ultimately frustration. Lucky for me, GitHub Actions had just been released and it matched my level of interest in DevOps. With it, I could fairly painlessly create workflows that would automate everything I needed in order to publish libraries.

What kind of steps does this entail? Well, here's roughly the flow of my pipeline:

  • Linting: Running e.g. ESLint is a great way to discover problems without having to run any code.
  • Tests: Just like the responsible developers that we are, there's plenty of tests validating that our code can do stuff, even better if it does what it's supposed to. Extra points for integration tests โจ‘

Since we only wish to publish to npm on version bumps, the following steps only execute on git refs starting with refs/tags/

  • Publish library: Install dependencies, build the dist and publish to npm. This step also attaches necessary npm tags, for example v0.0.1-alpha.0 results in npm publish --tag alpha.
  • Build and deploy website: Creating a website for your library's documentation is pretty sweet once the README starts occupying a few viewports. I recommend Docusaurus since it's easy to use and deploy.

Conclusion

This article was intended to outline some of the challenges I've encountered during my adventures on GitHub, I hope it inspires more than it frightens ๐Ÿ™Œ๐Ÿผ

If there's interest I'd be happy to share more on this topic!

Oldest comments (0)