Publishing an Angular library with assets

In the current Angular CLI (Angular 8 at the time of this writing) the tooling for libraries is really good except for one area, assets. Unlike when you build a project for production, building a library does not package assets like you might expect.

tl;dr – the boiled down steps

  1. Build the library
    • This article uses the vanilla AngularCLI
  2. Copy the assets to the dist folder of the built project
    • I use npm scripts with pre/post prefixes
  3. Optional – publish as npm package
  4. Update the project to import the assets
  5. Done

Building the Library with Assets

Under the covers of the Angular CLI, library projects uses ng-packagr to bundle up the code for the library for distribution. ng-packagr is almost the same as the packaging that the CLI uses for app projects but it has some crucial differences in how it does it’s packaging, such as it doesn’t bundle in assets such as fonts, images, and scss files.

There are cases where you need this functionality though and if the Angular CLI doesn’t give it to you, what do you do? Right now, you need to post-process the package so that you include the assets.

In a past project I have used CPX for file copy/globbing but it doesn’t work on all systems. (I work on a Pixelbook and I failed to get it working properly.) I know there are many other npm modules that allow for file copying, this was the one that seemed the most stable, however it also doesn’t seem to be maintained currently. Basically, I’d use it again if I needed it but I would look for other options first. ( CPX – https://github.com/mysticatea/cpx )

This isn’t about what tools to use, so for this example I’ve used a simple shell script to illustrate what you need to do in order to package up assets.

No matter what you use to copy the files over, you need to have it as part of your build process. I prefer a stripped down build system that is easily understandable. To do this, I use npm scripts and the ability to use pre and post prefixes on steps to make them easily understood.

   "scripts": {
     // Sample build script
     "build-lib": "ng build lib-with-assets",
     "postbuild-lib": "./copyLibAssets.sh"
   },

Including Styles from a Library

To include style paths more cleanly for scss imports, you can take advantage of the stylePreprocessorOptions setting in the Angular CLI. If you are using scss for your styling, this will allow you to do @import statements with just the file name and not the entire path to the dist directory or the node_modules directory if you published as an npm repo.

        "stylePreprocessorOptions": {
          "includePaths": [
            "dist/lib-with-assets/assets/styles"
          ]
        },

If you have published as an npm module, then I don’t believe you will need to do this step and instead can use the ~ at the front of the package name to import, since the CLI knows that SCSS @imports with a tilde come from node_modules.

This is the basics of getting set up and by no means covers every situation. If you have additional information or questions, I would love to get your feedback.

Sample Repository

I created a sample repository as a test bed for exporting assets as part of the library project. You can find it over on GitHub. https://github.com/vandermore/angular-library-with-assets

References: (Since we stand on the shoulders of giants to see further.)

We all do what we can…

(I wrote this post way back in 2015 but never actually published it. I’m publishing it now even though it could use a few edits.)

I was listening to the Oddfellows Local episode of Jared Axelrod’s Voice of Free Planet X today, and while listening to his voice actors tell the story he had written I was reminded of something I learned long ago, and he touches on in his story.

In Oddfellows Local, the reporter interviews some of the members of the vigilante super group, and also a member of the premier super hero group on Earth. Now, before I lose you with talking about superheroes, for those of you who aren’t into that, it’s the story that actually grabbed me and not the capes and tights.

See, many years ago I was made aware of something that you, dear reader, may already know as well. There are layers of things in this world. We are all people, but some of us are more influential, wealthier, or just luckier than others. (To some extent we make our own luck but that’s not always the case.)

In that, we all deal with our own layer of problems, our own issues. We deal with what we can. In the course of our lives, we move between these layers, usually up, but sometimes down (assuming up is better, but really it’s often just bigger). As a kid, we play on the playground and with our friends, but as we grow, we change how we play. We wouldn’t consider going back to the playground, and if we did, we would be the ones out of place.

Jared’s story highlights that. I don’t know if he did it intentionally, but if he did he did it really well, showing the reader and not telling them. The Oddfellows are doing what they can as costumed vigilantes, sticking up for the people of Clarkville. While the superheroes of the Society of Saviors are protecting the Earth from all sorts of other threats, both on planet and off.

We all deal with what we can, but sometimes can reach higher, if only for a little while.

http://planetx.libsyn.com/episode-10-oddfellows-local

 

Time

“Time is a created thing. To say ‘I don’t have time,’ is like saying, ‘I don’t want to.’” – Lao Tzu

RTMFP, where did all my neighbors go?

So while RTMFP is great for peer to peer connections, it does have some considerations that you need to take into account when using it. The biggest, knowing when peers connect and disconnect to the app.

When a peer connects, the app will receive a NetStatusEvent. The event’s info.code will be a “NetGroup.Neighbor.Connect”. You can use the info.neighbor as a unique identifier for the connected peer.

The nice thing, is if a peer comes in late to the p2p party, as soon as a peer sends a message that is received by yours, then the connect event will be fired. So you’ll always have a list of peers that have connected to your client.

When a peer needs to disconnect, it should call the NetGroup’s close() method. This will send out a packet letting all other peers know that it has disconnected.

The interesting thing is, this is RTMFP, so not all packets will get to all peers. So what happens if your client doesn’t receive the disconnect packet? How do you know that your list of connected peers isn’t stale? Good question. One I don’t yet have an answer to. So if any of you do, please let me know.