angular-cli: Angular 6 CLI does not copy library's assets folder into dist folder.

Versions

Angular CLI: 6.0.7
Node: 9.3.0
OS: darwin x64
Angular: 6.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.6.7
@angular-devkit/build-angular      0.6.7
@angular-devkit/build-ng-packagr   0.6.7
@angular-devkit/build-optimizer    0.6.7
@angular-devkit/core               0.6.7
@angular-devkit/schematics         0.6.7
@angular/cdk                       6.2.0
@angular/cli                       6.0.7
@angular/material                  6.2.0
@ngtools/json-schema               1.1.0
@ngtools/webpack                   6.0.7
@schematics/angular                0.6.7
@schematics/update                 0.6.7
ng-packagr                         3.0.0
rxjs                               6.2.0
typescript                         2.7.2
webpack                            4.8.3

Repro steps

  • Create a library @acme/lib1 using ng generate library @acme/lib1
  • Create assets folder under projects/acme/lib1/assets and add images
  • Add a "projects" -> "@acme/lib1" -> "architect" -> "build" -> "options" -> "assets" key to the library’s config within angular.json file.
  • Build library using ng build @acme/lib1
  • Fail error should show and none of the assets will be copied to dist folder.

Observed behavior

Upon building & packaging an Angular 6 library e.g. @acme/lib1 using ng build @acme/lib1, the Angular CLI does not copy the library’s assets into the dist/acme/lib1/assets folder. This happens also when using the --prod flag.

The CLI seems to only support copying the root app’s assets but not library specific assets. When trying to add "assets": ["src/assets"] to project @acme/lib1 within angular.json, the following error appears in the command line:

Schema validation failed with the following errors: Data path “” should NOT have additional properties(assets).

When creating the following custom rule to copying the files on ng build:

 "assets": [
    "src/favicon.ico",
    "src/assets",
     { "glob": "**/*", "input": "src/assets", "output": "../acme/lib1/assets/" }
],

I get the following error:

An asset cannot be written to a location outside of the output path.

While it is possible to work around this issue using other command line tools/scripts, it will be more consistent to add support for library’s assets copy as well.

Desired behavior

Use Case Very often libraries include image files, icons, css files and other static files which are needed to be distrubted with the package.

What would like to see implemented? Add ability to define a library specific assets property within angular.json. Example -

"@acme/lib1": {
      "root": "projects/acme/lib1",
      "sourceRoot": "projects/acme/lib1/src",
      "projectType": "library",
      "prefix": "lib",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-ng-packagr:build",
          "options": {
            "tsConfig": "projects/acme/lib1/tsconfig.lib.json",
            "project": "projects/acme/lib1r/ng-package.json",
            "assets": [ // <--------- this is currently not supported
              "src/assets"
            ]
          },
  ...}

What did you expect to see? Project’s specific assets should be copied from projects/acme/lib1/src/assets into dist/acme/lib1/assets.

Mention any other details that might be useful (optional)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 302
  • Comments: 47 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Glad to see I’m not the only one with this problem.

Heya, this isn’t the first time an issue has been opened on this topic. https://github.com/angular/angular-cli/issues/13285, https://github.com/angular/angular-cli/issues/10927 and https://github.com/angular/angular-cli/issues/10869 are essentially the same thing as this one.

The short answer is that libraries are built with ng-packagr, and ng-packagr does not have an assets functionality. The feature request in its issue tracker is https://github.com/ng-packagr/ng-packagr/issues/1092.

But it’s a frequent issue that gets a lot of attention so I think it’s worth it to go more into detail about this topic. We’ll also leave it open and label it as a FAQ to increase visibility.

Building your browser app and building are library are similar insofar as they are both built. There are a bunch of source files that get transpiled and bundled and whatnot and put somewhere.

That’s about how similar they are though. Building an browser app is actually a completely different build pipeline than building a library. And that means that the pipeline has different configuration options.

For building browser apps we use webpack and a customized set of configurations in the @angular-devkit/build-angular package, whose sources are in this repository. For building libraries we use ng-packagr, whose sources are in https://github.com/ng-packagr/ng-packagr.

Some options you don’t really expect to be there when building a library, like the path to the index.html file. It just doesn’t make a lot of sense. Other options, like assets, you do expect to be there. It does make sense for a library to have assets, and many libraries do.

But since ng-packagr doesn’t have an assets like feature, you can’t set that option in angular.json. You get the Schema validation failed error, which means that the option doesn’t exist.

I agree this is a desirable feature and that many libraries, like @angular/material, have assets and need to build them using custom code. It is reasonable to expect the feature to exist.

But the right place to request it is in https://github.com/ng-packagr/ng-packagr/issues/1092 because that is where the code for building libraries is. If you are interested in contributing to this feature, that is where you should discuss possible approaches and collaborate with people working on this feature.

Although it sounds like an easy thing, it’s not necessarily as easy as just copying some files over. Especially if we’re talking about sass files, or other files that are meant to be consumed in specific ways. Often you’ll find special instructions in libraries about how the assets must be used.

I hope this sheds some light on the topic.

Thank you for your interest in this issue. This issue is currently on the project backlog. However, as there is a viable method to accomplishing the underlying use case and post-build staging will always be required for specific scenarios, other issues currently have a higher priority. If the issue is not being addressed at the priority you would prefer, please consider contributing. The project is open source and greatly appreciates and accepts contributions from the community. For further details please see the contributing guidance found here: https://github.com/angular/angular-cli/blob/master/CONTRIBUTING.md

I can’t understand how, after almost 4 months, this issue is not at least in progress. Yes, there is a workaround, but it’s like working against the angular.json configuration to do something outside of it when it should handle it.

this works for me (latest version) "assets": [ { "glob": "**/*", "input": "src/assets", "output": "/assets" } ] @n00dl3 / @StickNitro: sorry for the missing context: above is related to Angular CLI 6 and the configuration I mentioned goes to angular.json

here is a complete project configuration in angular.json assets are definitly copied for the karma tests:

@lvm/core-components”: { “root”: “projects/lvm/core-components”, “sourceRoot”: “projects/lvm/core-components/src”, “projectType”: “library”, “prefix”: “cc”, “architect”: { “build”: { “builder”: “@angular-devkit/build-ng-packagr:build”, “options”: { “tsConfig”: “projects/lvm/core-components/tsconfig.lib.json”, “project”: “projects/lvm/core-components/ng-package.json” }, “configurations”: { “production”: { “project”: “projects/lvm/core-components/ng-package.prod.json” } } }, “test”: { “builder”: “@angular-devkit/build-angular:karma”, “options”: { “main”: “projects/lvm/core-components/src/test.ts”, “tsConfig”: “projects/lvm/core-components/tsconfig.spec.json”, “karmaConfig”: “projects/lvm/core-components/karma.conf.js”, “assets”: [ { “glob”: “**/*”, “input”: “src/assets”, “output”: “/assets” } ], “preserveSymlinks”: true } },

Environment Angular CLI: 6.0.8 Node: 8.11.2 OS: linux x64 Angular: 6.0.4

I can’t understand how, It’s been more than one year.

Hi there, earlier this week i was starting to migrate our company’s library build to the Angular CLI way.

First i have to say, that it was a bit of frustrating me because i assumed that it would be easy going since the Angular tools are so great.

When I realized that there is no copy functionality for library assets, I did consider for not migrating to the cli tools. But Angular schematics and architect builders are so a great tools. That’s why I decided to continue.

I have extended the @angular-devkit/build-ng-packagr:build and created an own one with asset copy functionality.

Here you will find how to use it: https://github.com/linnenschmidt/build-ng-packagr#how-to-use-it

npm install @linnenschmidt/build-ng-packagr --save-dev

Please give it a try. Maybe this approach is enough for you.

@bniedermeyer: the current workaround is to manually copy the assets

You can write a simple npm script to copy the assets after library is built using cpx:

    "build-lib": "ng build test-lib --prod && npm run copy-lib-assets",
    "copy-lib-assets": "cpx \"projects/test-lib/.npmrc\" \"dist/test-lib\""

But it would be really great if this is possible via angular.json

This definitely should be available from angular.json. Library should be totally independent project and assets are quite important part of it.

Hello, we’re also using a library with internal assets, Having the ability to include those assets without a custom script would be highly desirable.

Why is this still not resolved?? Angular 6 not displaying assets,images after --prod build??? works fine locally! Finally ready for deploy and assets are not rendering at firebase after my ng build --prod? All my other projects have worked in the past and I missing something in the latest version?

check your base directory contains special character Wrong Eg : c:\programfile(S)\test
In above example ( is special character Working Eg : c:\programfiles\test\

Thanks dhanaraj.k

On Mon, Nov 11, 2019 at 1:28 PM rorry121 notifications@github.com wrote:

Any news no this?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/angular/angular-cli/issues/11071?email_source=notifications&email_token=AJWMR6ZWIRYMBQETAVAWAKLQTEGB3A5CNFSM4FCPTQF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDV66EI#issuecomment-552333073, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJWMR62QZPISAW6P2DT5V2DQTEGB3ANCNFSM4FCPTQFQ .

This is currently expected behavior from ng-packagr, which powers the library packaging process in the cli. The current suggestion is to copy manually after the build. I’ve heard mention that they will be addressing this in the future though.

See https://github.com/dherges/ng-packagr/issues/123#issuecomment-330029214

Hello I’m having same problem when creating library with extra localization files and also extra sass styles file which has to be preprocessed before a copy. I have to run another script to copy files into destination. It would be nice if that could work as integrated functionality of angular-cli, same as it can do with application type project. Will there be such support ?

I just logged similar issue and it seems right now the only solution is either again gulp tasks or running directly npm command.

Other than that for a library support and probably there already feature requests you need to have a option to release a version, so some command in the chain that is able to bump up the version !

Otherwise library support is good for some simple usecases, but its definitelly good step forward !

Well in the meantime I developed my own builder, that executes @angular-devkit/build-ng-packagr and then follows with additional functionality like copying assets etc. That way I do not need to leave the realm of ng commands and even logs fit perfectly.

There is however one more thing…I had to configure application assets in angular.json to copy the library assets so they are accessible during the runtime of the application.

Just to add another use case for this feature: when publishing a module to a private VSTS npm feed, it’s required that the module include a .npmrc file at the root of the module that points to VSTS registry. Since this file doesn’t get copied into the dist directory, the file must be manually copied after each build before publishing. This is a bit of a pain!


Actually, scratch that: the .npmrc file needs to be at the root of the whole repository, not in the dist directory. So it works without this feature. Although I still agree that this feature would be great to have!

Any news no this?

@blemaire in fact I just opened an issue in angular-builders for that very reason. I didn’t want to create yet another package, I’d rather contribute there.

Re the last comment by @Splaktar, this blog post was just published which explains the Architect API: https://blog.angular.io/introducing-cli-builders-d012d4489f1b

@filipesilva I understand it would be job for ng-packagr but since Angular CLI runs ng-packagr and we have no option to change the command to something like ng-packagr && node copyOurStuff.js — could you at least add some sort of hooks to Angular CLI so this could be done with Angular CLI in a single step? After all, it looks like this would be the idea behind angular.json and ng that I would create a library and build it using ng run my-library:build. But now I also have to sorta leave ng realm and run some irrelevant npm run my-library:postbuild task that I have to configure in a separate place of package.json that would run the script and only the name of it would be a sign that it is a necessary step in the build process.

EDIT: Found there’s an issue for that already: https://github.com/angular/angular-cli/issues/11787

It seems there are only two workarounds for this problem if angular-cli doesn’t provide the capability of copying the assets folder across.

  1. Forget about ng and write some hack in npm to emulate it and copy the assets folder across. With the npm postbuild hook or something.
  2. Or just do it manually.

Either of those slow down quite a lot the development process. If someone has any other better idea, please shout!

@alvics it sounds like you are having a different issue other than what this thread is about. You are correct that assets were (and still are) included in builds for normal Angular projects managed by the CLI. However, this thread is talking about bundling assets for libraries created by the CLI with the ng generate library <library-name> command. This is due to a limitation of ng-packagr - the tool that enables the building of libraries within the CLI. See here for some more info on what’s going on and some suggested strategies.

If you’ve recently added a library to an existing project’s workspace that you recently upgraded and are now having assets issues there are some steps that may help you out here. If you are just trying to create a library is there a repro you could throw together that demonstrates your problem?

If you are not trying to build you own Angular library creating a new issue or reaching out to Stack Overflow or the Gitter channel should get you the help you need 😄

Thanks For the update. I have some solution for assets/resources and release cycle as well https://github.com/SAP/angular-metaui that I am using right now, its not perfect but better than nothing;-) Hopefully they will add in the next release or so.

@lammers Could you expand on your answer please, where does this need to go for this to work?

Ck your base directory contain Any special characters

On Mon 16 Sep, 2019, 1:19 PM Bastien Lemaire, notifications@github.com wrote:

Brilliant @klemenoslaj https://github.com/klemenoslaj could you share your implementation?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/angular/angular-cli/issues/11071?email_source=notifications&email_token=AJWMR66WGH53XVFBYCKK6ODQJ43ARA5CNFSM4FCPTQF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6YLGKI#issuecomment-531673897, or mute the thread https://github.com/notifications/unsubscribe-auth/AJWMR6Z5N4CH3M4DANDDOFTQJ43ARANCNFSM4FCPTQFQ .

Brilliant @klemenoslaj could you share your implementation?

Something ? Anything ??

i have solved this by changing the file path to another location which folder doesn’t contain special character

@fkolar This is a bit off topic, but we’ve managed to incorporate semantic-release into our Angular CLI Library release process. It’s not perfect but we’ve been happy with it so far. The key for us was to change the pkgRoot key in the config to point to the built library in the dist folder. Our versions are based on git tags so we haven’t run into issues with the version being determined incorrectly.

You could probably use their exec plugin to script the syncing of the versions in the various package.json files in your project.

ok … I just recognized that my scenario is different … my assets are in the main project and are copied with the configuration above for the karma tests of the library project.