Angular CLI: Different ways to include assets

Angular CLI: Different ways to include assets

In this article I will discuss several methods of adding and referring to static files in an Angular CLI application – may they be images, fonts or scripts:

  • when the assets are in the assets folder
  • when the assets are in any other folder
  • when the assets are in the node_modules folder

Assets from the assets folder

project
├───src
│   ├───app
│   │   └───app.component.html
│   │
│   └───assets
│       └───logo.png
│
└───angular.json

This is the simplest case. Just add files to the assets folder and refer to them using assets/file path:

Add file src/assets/logo.png
Add the following line to src/app/app.component.html:

HTML
src/app/app.component.html

This is the contents of the dist folder after building:

dist
└───our-application
    ├───assets
    │   └───logo.png
    │
    ├───index.html
    └───...

Assets from other folders

project
├───src
│   ├───app
│   │   └───component1
│   │       ├───assets
│   │       │   └───icon.png
│   │       └───component1.component.html
│   │
│   └───assets
│
└───angular.json

Let’s assume we want to keep assets close to their usage. Let there be a component that has an icon, and we don’t want to put that icon together with all other assets in the global src/assets folder, but instead we want to keep the icon in the same folder as the component.

One option is to include the component’s assets to the assets list in angular.json:

JSON
angular.json

This approach has a disadvantage: after building, the asset will go to app/component1/assets folder in the dist folder:

dist
└───our-application
    ├───app
    │   └───component1
    │       └───assets
    │           └───icon.png
    │
    ├───assets
    │
    ├───index.html
    └───...

Well, it’s not a problem, it just looks ugly. You can still refer to that icon in the component by providing its relative path:

HTML
src/app/component1/component1.component.html

How to make the path look better? Continue reading.

Rename/move assets

The case is the same as previously – we have an asset in an arbitrary application’s folder:

project
├───src
│   ├───app
│   │   └───component1
│   │       ├───assets
│   │       │   └───icon.png
│   │       └───component1.component.html
│   │
│   └───assets
│
└───angular.json

Now we have to fix the generated folder structure. This can be achieved by renaming or moving assets. It can’t be done using simple single line configuration in angular.json, but it’s still easily configurable. We have to use an old inclusion “glob” format.

So instead of single line:

JSON
“assets” in angular.json

write 5 lines:

JSON
“assets” in angular.json

or, equivalently:

JSON
“assets” in angular.json

What does this mean? Look for files matching the glob pattern in the input folder and save them to the output folder in dist under the respective glob name.

Source: <input>/<glob>
Destination: dist/<output>/<glob>

Still unclear? Let’s look at the example:

Copy file "assets/icon.png" from the "src/app/component1/assets" folder and save it to "dist/./assets/icon.png" (simply: "dist/assets/icon.png").

Advice

A glob pattern does not have to be one file. You can use any wildcard characters here, including "*.js" (all .js files) and "**/*" (all files in all subfolders).

In order to refer to that file in an HTML file, link to it using the join of output and glob paths:

HTML
src/app/component1/component1.component.html

Take a look at the generated dist folder:

dist
└───our-application
    ├───assets
    │   └───icon.png
    │
    ├───index.html
    └───...

Include assets from a node module

project
├───node_modules
│   └───jasmine-core
│       └───images
│           └───jasmine-horizontal.png
│
├───src
│   └───app
│       └───app.component.html
│
└───angular.json

If you tried to include an asset from node_modules to the application:

JSON
angular.json

you’ll see an error:

Error: The node_modules/jasmine-core/images/jasmine-horizontal.png asset path must start with the project source root.

Although it is not possible to directly include an asset from outside the source root (in this case – from node_module), to the assets section, there is a workaround using the old style of files inclusion. This is a variation of the previous method (read there for a bit of explanation).

So, instead of creating a line in the section:

JSON
“assets” in angular.json

add the following lines:

JSON
“assets” in angular.json

What does it do?

Copy file "jasmine-horizontal.png" from the "./node_modules/jasmine-core/images" folder and save it to "dist/jasmine-horizontal.png".

In order to refer to that file in an HTML file, link to it using the join of output and glob paths:

HTML
src/app/app.component.html

This is the contents of the dist folder after building:

dist
└───our-application
    ├───assets
    │
    ├───index.html
    ├───jasmine-horizontal.png
    └───...

I don’t really like assets to be mixed with other global files. I suppose it would be better to put that image to the same folder as other assets:

JSON
“assets” in angular.json
HTML
src/app/app.component.html

And this is the contents of the dist folder after building:

dist
└───our-application
    ├───assets
    │   └───jasmine-horizontal.png
    │
    ├───index.html
    └───...

Further reading

Find 3 different methods of retrieving an asset’s content in Angular.

Leave a Reply

avatar
  Subscribe  
Notify of