loading...
Cover image for Create a library with Angular and publish it to GitHub Package Registry

Create a library with Angular and publish it to GitHub Package Registry

brgrz profile image Marko Hrovatič Originally published at Medium ・7 min read

How to set up Angular library project, pack it up into an installable package, publish it to GitHub Package Registry and use it in another project

Intro

This post will only feature crucial steps that took me some time to get right. I will try to be as concise as possible but still provide enough details to make things easier for you.

In case you didn't know some time ago GitHub announced their own Package Registry which at the time of writing this article is in beta. There are a couple of reasons why I think GitHub Package Registry (GPR) is great news for developers:

  • when you publish to GPR you publish to a known/selected GitHub repository; that way your packages reside next to where their code/implementation is;
  • you can publish different packages to the same repository, meaning it doesn't have to be one repo = one package (you just have to set it up correctly and I will show you how to do it later on);
  • you can reuse your existing team/organization structure that you have on GitHub not having to replicate everything on NPM (or any another registry, for that matter);
  • personally I never liked the NPM experience be it either their search or the administration side of it and would much rather have everything on GitHub,
  • using GitHub to host both code and packages just means one (or more) less service you have to configure and learn to use,
  • the familiar GitHub experience,
  • the GPR is currently in Beta and you can use it free of charge even for private packages; at the moment of writing I don't know of any other online package registry where one can host private packages free of charge,
  • you can also use GitHub's registry for other types of packages for instance Gem (Ruby), NuGet (.NET), Maven (Java) and others.

Learn more about GitHub Package Registry and if you want to sign up for Beta please use this link

Lets start

1. Create an empty Angular workspace

We will be using Angular CLI for this. There's been changes in the latest versions of Angular which make this very easy.

Create an empty Angular workspace that can host multiple projects. This will set everything up with correct configuration in package.json and angular.json.

ng new LibraryWorkspace --createApplication=false

2. Create a new Angular library project within the workspace

This will create /projects folder under the workspace root with a library subfolder inside. It will also create a new library module and a service and component to start with.

ng g library ComponentsLib --prefix cmpts

3. (optional) Build (and pack your library)

Step 3 is only required here as a precaution. Building the library at this point makes sure our Angular workspace and library project were set up correctly by the CLI. You will be rebuilding the library again after you've completed the steps 4-7.

Now, the previous CLI command will also create files required for the project to become a package at some point:

  • package.json,
  • ng-package.json,
  • and an important file src/public-api.ts

At this point we have everything we need to run a build for this project.

The CLI is smart enough to build the default library first if you also happen to have other projects within the workspace. It will also build for production by default so you don't have to use the --prod switch.

ng build

To pack the library you will switch to the dist folder and use npm pack. You can do that now OR do it later after you've set up the GitHub Package Registry settings (steps 4-7).

cd ..\..\dist\ComponentsLib\
npm pack

You could of course make these lines part of a custom script in package.json but I won't go into details on that.

4. Register with GitHub Package Registry

This is very straightforward, just sign up for the beta at
https://github.com/features/package-registry and you should be fine.

5. Authenticate to GitHub using personal token and store it in your personal .npmrc file

When I did this for the first time I had issues both with .npmrc file not containing what I wanted and with logging into GitHub from cmdline in the first place. Please, take your time and give it a couple of retries if it doesn't work the first time.

First, you need a token from GitHub and you can get it by following the steps outlined here https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line

When you have the token bring up your cmdline/powershell/whatever and do this

npm login --scope=@OWNER --registry=https://npm.pkg.github.com

The @OWNER is the package scope and you should use either your GitHub account name or your GitHub organization name here (prefixed by the @ sign).

Follow the steps presented at cmdline and login to GitHub with your token.

Succesful login will create .npmrc file in your machine-wide personal folder (on Windows, this will be C:\Users\accountname\.npmrc).

If you open this file you should find the following lines in it. If the two lines are not present just add them yourself.

//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN_HERE
@OWNER:registry=<https://npm.pkg.github.com/>

Again, @OWNER will be replaced with your GitHub username or organization name (prefixed by the @ sign).

6. Modify your library files

Certain files in your library code have to be modified with GitHub specific NPM settings/configuration.

Modify your ./projects/ComponentsLib/package.json like this

(that is the package.json within the library folder in your Angular workspace NOT the one at the root of your workspace)

change

    "name": "ComponentsLib",

to

    "name": "@owner/ComponentsLib",

(@owner is the same as in step 5 but it has to be all lowercase here!)

and add the following lines

    "repository": {
        "type": "git",
        "url": "git://github.com/OWNER/REPOSITORY.git"
    }

When you're finished your package.json should look something like this

{
    "name": "@owner/ComponentsLib",
    "version": "0.0.1",
    "peerDependencies": {
        "@angular/common": "^8.2.13",
        "@angular/core": "^8.2.13"
    },
    "repository": {
        "type": "git",
        "url": "git://github.com/OWNER/REPOSITORY.git"
    }
}

7. Create .npmrc file in your library folder

This file is needed by the npm to discover your GitHub registry and for npm to know where to publish your package when you run npm publish later on. You would also check this file into source control.

Create a new .npmrc file alongside package.json and add this line to it:

registry=https://npm.pkg.github.com/owner

If you plan to have packages that belong to multiple developers or different organizations within the same Angular project you can support multiple scopes by adding the registries in the following format in .npmrc:

@owner:registry=https://npm.pkg.github.com

8. Build and pack you library

With all those files changed you can now build the library and produce a package for it

ng build
cd ..\..\dist\ComponentsLib\
npm pack

This should result in a tarball being created in your dist folder

owner-componentslib-0.0.1.tgz

9. Publish the library package to GitHub

You should now be able to publish the package to GitHub repository configured in package.json and .npmrc.

npm requires you are still logged in with GitHub for this to work.

npm publish

10. Use the published package in another app

Go to your GitHub repository and click on the packages link (should be next to commits and branches tabs) and it will take you to a list of published packages within that repo.

It will also be accessible by URL

https://github.com/owner/repository/packages

Clicking on a package will give you the instructions for installing it, either via npm i or adding it to package.json.

Now, to make the installation work the destination app will also need a .npmrc file so it can find your GitHub registry (unless you have registered it in your personal .npmrc file).

At the root of your app (the app where you want to install your library package) create .npmrc file with the following contents:

registry=https://npm.pkg.github.com/owner

Finally, you can bring in the library

npm install @owner/componentslib

You would then import the ComponentsLibModule to one of your Angular modules in your destination app (be it the root app.module or any other module).

11. Publishing new versions of the library

When you modify your library and want to update the package with a newer version you will have to update the version (semver) number for it.

You can simply use npm version command for that and it will automatically advance your version number.

npm version [patch | minor | major | ...]

The npm version command docs

You will then want to rerun the build, pack & publish step.

Finish

Hopefully this post will help others to set up GitHub as their package registry and contribute to module/component reuse either within private or public teams.

Should you have any questions or comments feel free to post them below.

Also, here is a list of links that helped me while I struggled with setting this up for the first time:

The excellent Creating a Library series by Todd Palmer

About GitHub Package Registry

Configuring NPM for use with GitHub Package Registry by GitHub

Creating a personal access token for the command line

Configuring your registry settings as an npm Enterprise user

HTH

Story photo by jesse ramirez on Unsplash

Posted on by:

brgrz profile

Marko Hrovatič

@brgrz

Business founder, full stack web developer and UX guy. Avid mountain biker. Who dares, wins.

Discussion

markdown guide
 

I follow all the steps and I complete my job! thank you!

 

Hi Marko!

I followed this tutorial. In the end, after npm publish I get an error:
24 error Only absolute URLs are supported
Any idea why this might happen?