Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular 6 CLI does not copy library's assets folder into dist folder. #11071

Closed
7bamboo opened this issue May 30, 2018 · 47 comments · Fixed by ng-packagr/ng-packagr#1465
Closed
Labels
Milestone

Comments

@7bamboo
Copy link

7bamboo commented May 30, 2018

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)

@ChrisWithTheHat
Copy link

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

@bniedermeyer
Copy link
Contributor

bniedermeyer commented Jun 6, 2018

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 ng-packagr/ng-packagr#123 (comment)

@lammers
Copy link

lammers commented Jun 12, 2018

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

@StickNitro
Copy link

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

@n00dl3
Copy link

n00dl3 commented Jun 12, 2018

@lammers I don't see how that would work, build-ng-packagr schema being like so, we cannot add any custom property :

{
  "title": "ng-packagr Target",
  "description": "ng-packagr target options for Build Architect.",
  "type": "object",
  "properties": {
    "project": {
      "type": "string",
      "description": "The file path of the package.json for distribution via npm."
    },
    "tsConfig": {
      "type": "string",
      "description": "The file path of the TypeScript configuration file."
    }
  },
  "additionalProperties": false,
  "required": [
    "project"
  ]
}

@lammers
Copy link

lammers commented Jun 13, 2018

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.

@bmhumadi
Copy link

Having the same problem. Please let us know how to fix, or when a fix is in?

@mattezell
Copy link

It's not currently supported @bmhumadi #11317

@fkolar
Copy link

fkolar commented Jul 7, 2018

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 !

@JBoothUA
Copy link

we need support for this also!

@kawazoe
Copy link

kawazoe commented Jul 20, 2018

I’m working on a big project, big enough that we were considering using nrwl also but the effort required to get our dozens of libraries setup to handle asserts correctly is a big hold up for the project.

I would love to see a simpler integration for assets as well.

@bniedermeyer
Copy link
Contributor

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

@fkolar
Copy link

fkolar commented Jul 21, 2018

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.

@nfriend
Copy link

nfriend commented Aug 2, 2018

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!

@alvics
Copy link

alvics commented Aug 15, 2018

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?

@bniedermeyer
Copy link
Contributor

@alvics can you elaborate more on your issue?

The problem you describe sounds more like an issue with an Angular application. This issue is regarding bundling assets in a library that was created by the CLI and doesn't involve the normal applications generated with a ng new command.

If you are trying to build a library and find that your assets aren't being included the current workaround is to manually copy the assets to the build destination with a post build step before publishing your library.

@alvics
Copy link

alvics commented Aug 15, 2018

@bniedermeyer my current work around looks like it needs to change with every CLI update? No other project or version has ever been a problem with assets? I'm not having a go, but what you are saying is with this latest update I need to do more to work around this in order to render my assets? shouldn't it be getting simpler/easier? Why isn't the current version including the assets folder within dist automatically? it has in the past right?
What do you mean when you say manually copy the assets to the build destination with a post build step? input - output like this? I have tried and not working. Have you got an example?
"assets": [
{ "glob": "**/*", "input": "src/assets", "output": "/assets" }
],

This works in older projects by default just not now?
"assets": ["src/favicon.ico", "src/assets/"],

@bniedermeyer
Copy link
Contributor

bniedermeyer commented Aug 15, 2018

@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 😄

@daimoonis
Copy link

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 ?

@jbarber2016
Copy link

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.

@klofi
Copy link

klofi commented Aug 29, 2018

@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

@Drag13
Copy link

Drag13 commented Sep 2, 2018

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

@JEDacreWright
Copy link

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.

@clydin
Copy link
Member

clydin commented Sep 21, 2018

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

@dambrosiomike
Copy link

Since libraries are exported in the Angular Package Format, wouldn't that first have to be updated to contain guidance for asset output? I see a note about preferring "styles" and "template" over "styleUrls" and "templateUrls" but I don't see anything about assets.

@alan-agius4 alan-agius4 added feature Issue that requests a new feature devkit/build-angular:library labels Oct 13, 2018
@ngbot ngbot bot added this to the Backlog milestone Oct 13, 2018
@sergiojoker11
Copy link

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!

@filipesilva filipesilva removed the needs: discussion On the agenda for team meeting to determine next steps label Jan 3, 2019
@filipesilva
Copy link
Contributor

filipesilva commented Jan 3, 2019

Heya, this isn't the first time an issue has been opened on this topic. #13285, #10927 and #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 ng-packagr/ng-packagr#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 ng-packagr/ng-packagr#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.

@linnenschmidt
Copy link

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.

@waterplea
Copy link

waterplea commented Apr 10, 2019

@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:
#11787

@dhanarajknp
Copy link

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

@Splaktar
Copy link
Member

@waterplea Angular version 8 brings the a stable Architect API which will allow for the extension and/or customization of builders like @angular-devkit/build-ng-packagr.

@michaelbromley
Copy link

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

@tecsolucionesinformaticas
Copy link

tecsolucionesinformaticas commented Jun 25, 2019

After trying different approches.
My solution was to create angular build as a subfolder of where my assets are. This way I can access assets as ../

Example:

(build)---> myApp/myAngularBuild
(assets)--> myApp/

this way I can even build with
ng build --base-href ./ --watch

it's not genius, but it's functional.

@dhanarajknp
Copy link

dhanarajknp commented Jun 26, 2019 via email

@Cossack13
Copy link

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

Oh, so thank you, dhanarajknp! I used [] in the root folder name.

@gauri-kumar
Copy link

Something ? Anything ??

@lakhanmandloi
Copy link

I am using nodemon in my project. I have been able to copy the images in dist folder of library. https://github.com/Sunbird-Ed/sunbird-ui-components/blob/master/nodemon.json. This works

However, Now I am facing issues in using these images in the lib components.

@klemenoslaj
Copy link

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.

@blemaire
Copy link

Brilliant @klemenoslaj could you share your implementation?

@dhanarajknp
Copy link

dhanarajknp commented Sep 16, 2019 via email

@klemenoslaj
Copy link

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

@hiepxanh
Copy link
Contributor

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

@rorry121
Copy link

Any news no this?

@dhanarajknp
Copy link

dhanarajknp commented Nov 14, 2019 via email

alan-agius4 added a commit to ng-packagr/ng-packagr that referenced this issue Dec 4, 2019
This behaves the same way `srcs` of the `npm_package` bazel rule which allows copying of files to the distributable folder.

```js
  "assets": [
    'CHANGELOG.md',
    "./syles/**/*.scss"
  ],
  "lib": {
  }
```

Closes: angular/angular-cli#11071 and closes: #1092
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jan 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.