65

I am building a library which contains a custom icon font. However, when I build my library using ng build <library-name> --prod, the assets folder is not included in the build, which means icons do not show up when using the production build.

I've tried multiple solutions like adding the assets array in angular.json and copying the assets folder to the created dist folder.

I am using Angular 8, and the library was created using angular-cli.

I tried including the fonts two ways: using @import url( '../assets/icon_font.css' ); in one of the style files and adding ../assets/icon_font.css to styleUrls in one of the components that require it. (icon_font.css is the css file that includes the icon fonts)

Here's the layout of my library directory:

- src
  - lib
    - assets
      - icon_font.css
      - font files
    - component that requires icons
      - style sheet that has @import icon_font.css
    - other components and classes

I would like the .ttf and other font files in the assets/ directory to be available in the exported dist folder.

Aivaras Kriksciunas
  • 862
  • 1
  • 8
  • 11
  • Something to read: https://github.com/angular/angular-cli/issues/11071 – R. Richards Aug 31 '19 at 19:29
  • is the assets folder included in angular.json? – Reza Aug 31 '19 at 23:47
  • Yes, I included it under `options`, however now it gives me `Schema validation` error: `Data path "" should NOT have additional properties(assets).` – Aivaras Kriksciunas Sep 01 '19 at 06:02
  • Assets folder should be included in an `angular.json` project **only** in an angular app. For a library, you will receive the error @AivarasKriksciunas had. You'll have to add it in the `ng-package.json` of the targeted library _under the projects folder_ – Raphaël Balet Oct 29 '20 at 10:40
  • You can take another aproach: include the icons in the library like show this link:https://netbasal.com/elegantly-manage-svg-icons-in-angular-applications-5adde68a5c46 – Eliseo Nov 12 '20 at 10:06

3 Answers3

116

As already said, angular library now support assets since the v9.x of angular.
But it isn't well explained on their website. To make it work you'll have to:

  1. Add an assets folder at the root of your library project
    enter image description here
  2. Add "assets": ["./assets"], into the ng-package.json file of the library
{
  "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
  "dest": "../../dist/icon",
  "assets": ["./assets"], // <-- Add it here
  "lib": {
    "entryFile": "src/public-api.ts"
  }
}

Reminder: tsconfig.lib.json path do not work in an angular libraries, so after your change you may have to edit manually the import of the assets with relative path

  1. ng build custom-project --prod. It then appear in your dist folder
    enter image description here

Then you could just add what you want in this folder

Additional tips : Use it within your project

Then if you wish to use it into the project it get imported into, do :

Assets, js, styles in angular.json

Add those files into your angular.json file

 {
   /*...*/
   "assets": [ // Import every assets
     {
       "glob": "**/*",
       "input": "./node_modules/custom-project/assets",
       "output": "/assets/"
     }
   ],
   "styles" : [ // Only custom css
     "node_modules/custom-project/assets/my-css-file.css"
   ],
   "scripts" : [
     "node_modules/custom-project/assets/my-js-file.js"
   ]
 }

Js as part of the app.module

You could directly also add js into children file even if I'm not sure if it really lazy loading those files.
example, into your home.module.ts file, import

 import 'custom-project/assets/my-js-file.js'
Raphaël Balet
  • 6,334
  • 6
  • 41
  • 78
  • Is it possible to copy assets from the node_modules folder of the library project? I have tried "assets": ["../../node_modules/@foo/core/assets"] but no luck. My hope was that it would create an "assets" folder under dist/ and copy all the assets from foo. This works with a normal Angular project by adding the assets configuration to the build/builder/options in the angular.json for angular-devkit/build-angular:browser. – Eric Nov 11 '20 at 21:13
  • 1
    @rbalet Looks like post Angular 6, using the syntax you have given, you cannot add assets from a node module if they are not in the src directory. Instead of the string path, you have to put this object in the assets array:```{ "glob": "**/*", "input": "./node_modules/module_name/assets", "output": "./assets" }``` – Nirmal Nov 21 '20 at 16:04
  • @Nirmal,Thanks I've updated the answer. @Eric, should work now, don't forget to also **add it under the assets found under `production`** – Raphaël Balet Dec 17 '20 at 17:17
  • 2
    The solution works but in an Angular library created with the CLI the assets folder is inside the src folder, not at the same level. I don't get the point of having a solution for copying assets in Angular that is not compliant with default folder structure. It's not your fault of course, just saying that this seems to be a poor design decision by Angular or ng-package team. – Dani P. Jan 19 '21 at 12:39
  • @Raphaël Balet This works but then I get an error problem with the import statements for of the scss style files. How can this be fixed? I tried adding to tsconfig.lib.json -> compilerOptions -> paths the following: "assets": ["./assets"] and also tried "assets/*": ["./assets/*"] but non works – Noy Oliel Sep 15 '21 at 07:19
  • @olNoy Libraries can not work with the path of the `tsconfig.lib.json` the problem is that only the main project is taken, so you have to do it as I did, meaning moving the `assets` folder under the project directly. So you'll have to follow my instruction and do exactly like it if you want to make it work. _Or I may misunderstand what you did try to achieve_ – Raphaël Balet Sep 15 '21 at 18:30
  • @Raphaël Balet, I did "exactly" as described above and as you wrote, it works, *however* since assets folder was moved to a different location (by following your solution) I started having problems with the *non relative* paths, such as:@import "assets/somefolder/somefile" as they are not recognizing the files. only relative paths work (e.g. ../../assets/ect) To fix issue I tried playing with tsconfig.lib.json, however this failed. I was wondering what can I do in order to fix this issue as the assets folder is not in the original location. – Noy Oliel Sep 16 '21 at 20:55
  • @olNoy Ah, now I see the problem. Can you try the following. Let your `assets` folder where it was, change the `ng-package.json` and target your `assets` folder like following -> `"assets": ["./[yourPath]/assets"],`? You **shall not use tsconfig.lib.json path** in angular libraries. _I'm not sure it will work_. I case this do not work, then you'll have to correct the assets path. Another mention, if you're using a lot of scss mixins, then you would maybe like to add them to another library, so you could just `@use '~@myLib/my-scss-mixin-lib' as *` – Raphaël Balet Sep 17 '21 at 05:20
  • Hey, inside the projects/custom_project is it possible to render the image and actually see it? For me, everything that I try still won't show the image... – Mihai Feb 18 '23 at 22:27
  • @Mihai Yes, absolutely and it's the reason of my answer ;). Be sure to read my former comments in this topic since it may guide you. and be sure to have it under it's own folder, `assets` for example. and to export it properly in the `angular.json` file – Raphaël Balet Feb 20 '23 at 06:23
  • Hey, thank you so much for responding, but I've tried many options I see the assets being added to the `dist` folder but when importing the lib inside the angular project to see the images they are not found, and to be honest I don't know exactly why or if is supposed when developing an angular lib and importing it inside the project (not yet as a package) if they are supposed to show. Maybe I did something wrong but I don't know what :( – Mihai Mar 01 '23 at 19:43
  • @Mihai Would it be possible for you to provide a stackblitz ? I could then help you through – Raphaël Balet Mar 02 '23 at 07:55
  • What is assets/style.sccs has import another file css with relative code to node_modules? – user13314476 Jun 16 '23 at 11:31
  • For those trying to package your Angular project (with libraries) with electron packager, it seems like the assets won't work correctly if your assets folder in your library is not in your src folder. The only way I have managed to get assets for a library to work with electron. – Franco Jul 26 '23 at 14:57
15

Like you said in your answer, it wasn't possible to force the packager to pack assets along with the build files.

Now, ng-packagr released a new version that allows you to include the assets along with the build files:

You can copy these assets by using the assets option.

Edit the ng-package.json file in your library (or projects/<your-lib>/ng-package.json file if you use multi-project workspace) to define the assets which should be included:

{
  "ngPackage": {
    "assets": [
      "CHANGELOG.md",
      "./styles/**/*.theme.scss"
    ],
    "lib": {
      ...
    }
  }
}

More information here: https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md

yntelectual
  • 3,028
  • 18
  • 24
German Quinteros
  • 1,870
  • 9
  • 33
4

Looking at other posts and issues on github, it looks like there is no way to force the packager to pack assets along with the build files. What I ended up doing instead is copying the assets folder to the dist folder manually before deploying it to npm. After that I would just have to tell users to manually @import the icon_font.css into one of their stylesheets.

Aivaras Kriksciunas
  • 862
  • 1
  • 8
  • 11
  • 1
    What is the source path you mentioned in your library code to access assets which were present in your library? Where did you copy assets exactly in the dist folder? Can you help? – Mehul Parmar Jun 22 '20 at 11:07
  • 1
    This feature is added in ng-packager v9.x and higher. for the lower version, you have to copy manually. – Aamer Shahzad Sep 29 '21 at 06:46