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.)


9 responses to “Publishing an Angular library with assets”

  1. Thanks.What about Js files…I need to include some external js files to library.

  2. You should be able to include those just like you would with a normal angular project. Using the “scripts” section from your angular.json. Unless the library doesn’t use them in imports, then the would get shaken out during the tree-shaking process.

    If you needed to have them there even if the library doesn’t use them, then I would include them the same way as including other assets.

  3. Great Post!! Almost gave up, glad I found this one 🙂
    Thanks David!!

  4. David this is awesome. I used your script to copy over files after the lib build. So I have my dist folder with assets/fonts copied over. However, when I do an npm install the assets folder does not get installed into the node_modules library folder structure. I am not publishing from npm. I do a PACK of my library and just npm install the tarball .tgz file that was created locally in the dist folder. Why do you think my assets are not being installed to node_modules? Thanks

  5. I’ve never installed npm modules via a tarball before. You may want to see if the tarball has the assets in it. If they aren’t there, then that’s your problem. 🙂 If they are, then I am clueless on that.

    When I have needed to test my libraries locally before publishing I have used `npm link`. So that may be a route you can try if the tarball isn’t working. Assuming of course that this is for testing and not a production use.

  6. I tried to use the image from lib-with-assets in lib-with-assets.component.html using img tag, but its not showing up.
    Is this only for exporting dist, How to use images from lib-with-assets assets folder inside lib components?

  7. These instructions are for publishing to a dist folder. I would need to know more about your situation in order to help with what you are attempting to do.

  8. Hi David,

    I have a different scenario , I have a library which contains img tag
    The actual image file is in Application/assets/image folder.

    When the library is installed in my application. I can see the expected image URL bind on the img tag

    But, Image not loading in browser . It expects the image to be in library assets/image folder. but it is in Application/assets/image folder.

    Is there any way to pass/bind image in library dynamically. I have 100 app. I need to load app logo as per the app but the library is common to all.

  9. Unfortunately, I’m not sure since it’s been a while since I have needed to build a library with assets. If I recall though, the script which copies the assets over to create the library is what was essential for putting the assets into the correct location in the library to be loaded by the consuming application.

Leave a Reply