Angular-cli: [RFC] Library Support and Boilerplate Comment Thread

Created on 30 May 2017  Â·  163Comments  Â·  Source: angular/angular-cli

As a follow up for https://github.com/angular/angular-cli/issues/1692#issuecomment-304970595.

Continue the conversion here.

RFC / discussion / question faq

Most helpful comment

Pardon my French, but WTF? Has Angular jumped the shark?

One of the top priorities of Component framework is to facilitate re-usability of components. I don't know what Angular Devkit is and I don't understand what multi-application support means. I just want to package a measly combo-box and share it with the team and/or the world.

Lack of standardization and lack of guidance in this area is really hurting the ecosystem.

I realize that the underlying complexity is beyond understanding of any casual app developer who just uses NG but, frankly, put your hand on your heart and ask yourself this question:

"Have we dug ourselves into a complexity black hole?"

The promise of NG2 was to banish the complexity and unfamiliarity of NG1. Time for a sincere introspection is now.

Meanwhile for us, who have to explain to our managers what JIT is or AOT and why builds randomly break even though they're perfectly good Typescript and why it takes so long to extract common functionality that already works to be used in another project, well, we might be forced to jump the ship.

All 163 comments

@hansl

Thanks for the official reply.
Hoping to see a update from the team soon :)

Thoughts from me (I maintain ngrx as well as Angular devrel)

So long term, this will land in the devkit, but that's a fairly major architecture change. In the interim, lets start with a "seed" style repo people can just fork and start work with.

MVP should basically:

  • use npm scripts for task running, with setup for build/test/publish: sample from ngrx/store: https://github.com/ngrx/store/blob/master/package.json#L7-L21
  • use ngc + rollup to produce FESMs + metadata + d.ts (though this really only applies to single function things - this is not an ideal process for material-type megarepos.
  • have a minimal test setup + integration spec to verify functionality + AoT friendlines

Anything beyond that is going to quickly get into the realm of bikeshedding best practices / fav code coverage tool of the week, so let's start minimally and go from there.

First off thanks @hansl for the update, it's very much appreciated.

I'd like to understand the future of ng cli, where this fits with the Angular Development Kit and the tools to generate custom templates.

Our company has put a lot of time and effort in to getting on board with Angular 4.x and using the ng cli, we have been though many refactors thought the libraries lifecycle. We are currently using a custom build process simular to what @robwormald describes for building and testing our component libraries, which we were hoping could be removed once this feature landed in cli.

I'm left worrying that we will have to change our non-library applications build process again once these new tools land, or will they just for library projects?

At Google, we use the terms "binary" and "library" for this:

  • a binary is a shippable-to-the-browser-artifact that's "self executing"
  • a library is a designed to be consumed by binaries (or other libraries)

The current Angular CLI was, from the very beginning, built to be a tool for managing binaries. In the early days, when we used ember-cli + broccoli, outputting libraries would have been simpler to do, as it was less opinionated and more flexible. The Angular community demanded (rightly, IMO) that we switch over to Webpack. Webpack is designed to build binaries, and so we're kind of stuck.

@mattem the whole point of not giving you access to the internals of Webpack is that its our goal to allow seamless transition as we evolve the underlying tools. Long term our goal is to dramatically simplify the whole process, but that takes time. The point of this thread is to provide an interim solution.

@mattem long term, we're working on eliminating the need to ship metadata and such to npm in favor of shipping precompiled code. We have this setup in place to allow us to be flexible with the compiler APIs (this is what allowed us to change everything in between v2 - v4) - once we're happy with the API we'll mark it as public, which opens up a number of really cool new possibilities. This is (currently) on the roadmap for about a year out, but the work to prepare for that is in progress.

@mattem Rob didn't answer this question, so I'll take a stab:

I'd like to understand the future of ng cli, where this fits with the Angular Development Kit and the tools to generate custom templates.

The DevKit will be a set of libraries and tooling that you can script or develop against. Parts of it will be to build, test and generate files. This sounds really generic because it is; it will be a lot of conventions enforced at the API level so that tools (such as IDEs, scripts or CIs) will work in a similar way.

The CLI in the future (version 2? 3?) will only be a tool that uses the DevKit in the background, abstracting it from users. If you use the CLI today, you should be _very_ familiar to the CLI in the future. The real difference is that every pieces underneath will be able to be used independently by other tools. So you could see, e.g., a VSCode extension that knows how to build your app/library, which uses the same code path as the CLI.

Pardon my French, but WTF? Has Angular jumped the shark?

One of the top priorities of Component framework is to facilitate re-usability of components. I don't know what Angular Devkit is and I don't understand what multi-application support means. I just want to package a measly combo-box and share it with the team and/or the world.

Lack of standardization and lack of guidance in this area is really hurting the ecosystem.

I realize that the underlying complexity is beyond understanding of any casual app developer who just uses NG but, frankly, put your hand on your heart and ask yourself this question:

"Have we dug ourselves into a complexity black hole?"

The promise of NG2 was to banish the complexity and unfamiliarity of NG1. Time for a sincere introspection is now.

Meanwhile for us, who have to explain to our managers what JIT is or AOT and why builds randomly break even though they're perfectly good Typescript and why it takes so long to extract common functionality that already works to be used in another project, well, we might be forced to jump the ship.

My 2 cents in the whole topic from the previous thread to the one I started.

First @oliverjanik I couldn't say it better.

I took the decision of do not move out of my Front end stack again, I can't be jumping between stacks while I want to create something mature that allow me to focus on the business rather than being "cool" or just change it for a minor improvement at the end of the day.

So I went back to Angular (I was in Angular 1 long time ago) because I saw the architecture changes and it looks fantastic pretty much, but then I hit wall that shouldn't be there for me #6466 , After a full week trying to get answer to my concern I realice that I will have to hack the setup and it will no be straight forward either.

Why should I hack something some simple as @oliverjanik explain, when all I want to do is to create the most common use case on any ecosystem: shared a reusable module.

CLI are meant to be use base on the ecosystem, I got that, but the same time there is common use case that should be fixed already, specially when there is a lot of people with the same concern.

And then even worse you read something like this https://github.com/angular/angular-cli/issues/1692#issuecomment-302742332 that scare me a lot as something that wants to think in long term and base out a whole company on it.

If you (Angular Ecosystem main contributors) don't want to support your community (it doesn't mean you didn't do it at all), just be clear with us. A lot of people depends of you and sometimes it doesn't even take a week for implement something with a huge impact for the good of the community. No everything can be Google interests but at least be clear about it.

I am speaking from the side of a person that just started 2 weeks ago, a person that was happy in React ecosystem but always wanted to go back to Angular for many reasons, a person that wants to be part of your community and probably in the future could be a potential contributor, making your life easier.

Please think in your community, it will pay off in the long term and don't read this and feel bad about it and think in the negative mindset because I can't express how thankful I am that you did an amazing job on Angular but at the same time, don't let small things like this one opaque your greater.

just be clear with us

@yordis Agreed. Before we talk about technical solutions, there should be a mention of this issue in the Docs. I created a PR https://github.com/angular/angular/pull/17129

My 2 cents is that for most people, they just need to know there is some direction in creating reusable Angular Modules. If we could add @robwormald's solution to the docs, then count me in. It doesn't need to be the most technically optimal solution for now, there is a lot of value in rallying behind non-optimal solutions for the sake of having consensus. Until then, Angular is the framework that "Makes great decisions so you don't have to... but you can't reuse your code."

@oliverjanik @yordis @rjsteinert appreciate the feedback.

I just want to package a measly combo-box and share it with the team and/or the world.

I don't want to in any way minimize what you're saying here, because there's a lot of good points in it - but we should be clear that this is absolutely possible today. Its absolutely more complicated than it needs to be, but there are some good examples out there you can use as a reference.

A great one to look it is ng-bootstrap: https://github.com/ng-bootstrap/ng-bootstrap/

Here's the packaging format guidelines Jason presented at ng-conf: https://goo.gl/AMOU5G - admittedly I had to ask around to track that down, so we'll see about getting that posted somewhere more reachable.

@filipesilva has also done great work on writing up a guide for this in the docs, and a starter repo you can clone, and unfortunately the pull request got caught behind our infrastructure changeover. I'm working on getting this merged ASAP.

You can see that PR here: https://github.com/angular/angular/pull/16486
And the starter repo here: https://github.com/filipesilva/angular-quickstart-lib

Lack of standardization and lack of guidance in this area is really hurting the ecosystem.

It should be said that there's pretty much zero precedent for what we're trying to do here. Some of the challenges in this space alone:

  • The JS ecosystem and NPM currently have no standard plan for shipping ES2015+ code to NPM.
  • NodeJS and friends are still debating how node will load ES modules.
  • Webpack, out of the box, doesn't transpile code coming out of NPM, but...
  • ES5 code is effectively un-treeshakeable.
  • Until about a month ago, no browser had any support for ES2015 Modules, static or dynamically loaded.
  • NPM is built on a non-standard, non-statically analyzable module format that is not great for performance: https://nolanlawson.com/2016/08/15/the-cost-of-small-modules/
  • Some developers want the easiest thing possible (drop the script in the page) and others want the absolute freedom to eek out every single ms of performance. This means UMD for the former, and ESM/ES2015/6/7 for the latter. See http://2ality.com/2017/04/setting-up-multi-platform-packages.html and note the meta there - it refers back to the above proposal from the Angular team.
  • Historically, bundling all your code has been the "right" way of doing things, but in a world with http2(push) and low-power mobile devices, this may not be the correct path forward!

...and all this is before we even start talking about Angular! Again, we're totally with you on this, but this is an ecosystem we're all a little bit at the mercy of. One thing that became quite clear when joining the Angular team is that we really are working at the bleeding edge - a lot of this stuff we literally have to invent as we go. It's a big reason I love my job, but it means that sometimes, yeah, you're gonna have to try things that sometimes won't work.

Example: the FESM format mentioned in the above doc works great for projects like ngrx, but unfortunately it had an impact on libraries like Angular Material, and so we're tweaking those guidelines for cases like that. A lot of these things you just don't know until you try.

One thing I think is important to understand here is that we (the Angular team) are dealing with this problem twice - once internally, for all the projects at Google and Alphabet that use Angular, and once for the FOSS community. Why?

At Google, we use an entirely different set of tools than are used in the open source world:

  • Blaze (or bazel.io) , our build system used to build everything at Google, from Angular to Maps to Gmail.
  • Closure Compiler, which does bundling (replacing Webpack), optimization (replacing Uglify), module loading (replacing SystemJS or Webpack)
  • A whole lot of strictly enforced conventions and rules, with the build infrastructure to enforce it.
  • we have our own special module format (closure's goog.require)
  • we don't use NPM or node_modules

This means @hansl, who runs the open-source facing CLI project, is doing work that can't be shared by the internal Angular infrastructure teams (because we're not using Webpack et al), and vice-versa.

If we're being perfectly honest, this situation, and the internals of CLI as it exists today are not sustainable. Having a great scaffold from the ember-CLI project and leveraging @TheLarkInn and the awesome Webpack community allowed us to get a functional tool that was usable ASAP - but its led to a fairly significant amount of technical debt.

This isn't unexpected, and again, it's the reason we've held fast on not exposing the Webpack internals - we knew at some point, we'd have to pay off that technical debt, and we want to do so without exposing developers to churn.

The idea of the DevKit project is to finally allow us to share tooling between our internal and external customers - meaning @hansl and co aren't duplicating work, and excitingly, developers of teams at Google can help improve the same tooling open-source Angular developers use. @alexeagle has written a bit about this - https://medium.com/@Jakeherringbone/what-angular-is-doing-with-bazel-and-closure-21f526f64a34 - We've requested and helped design features from the Typescript team (like the transformers pipeline) that will finally unlock further code sharing and streamline our TS tooling.

If you don't care about how it works, then you won't have to care about how it works. It will, however, allow developers who want to, to build and extend the toolchain to do all sorts of powerful things. As an off the cuff example - we speak to lots of teams who want a standard boilerplate for their internal packages. DevKit will enable that - and not in a patched-on-the-side fashion, but baked into the design from the beginning. Want to plug into the generation pipeline and add your own custom license to every generated file? Sure.

All software is about balancing tradeoffs - we made a decision early on to provide open-source developers who want to be productive building applications a tool they could use immediately. I think, with a few exceptions, we've delivered on that goal. We're trying to do this while also balancing long-term maintainability, and delivering for the teams at Google that pay our salaries (and those of our awesome contractors) and make the entire Angular project possible at all, and there's only so many hours in the day!

If there's anything else you'd like clarification on here, please don't hesitate to ask.

@robwormald I do not understand why you say the problem is Webpack when there are thousands of examples of libraries built with Webpack

I completely agree with @oliverjanik, it is not understandable that from the team of Angular is not given priority to this. You can't make a framework based on compononents that doesn'tallow reuse of components. It's completely absurd.

In our development team, the first thing we did when we started working with Angular was to create a library of reusable components for all our modules. It does not make sense that Google has not thought the same way.

We have also been able to create reusable components such as a combo box without effort. If you are interested in knowing our project is this:

https://github.com/Stratio/egeo

Two main concern in how to approach this because I am misunderstanding.

  1. https://github.com/angular/angular-cli/issues/6466 Based on that issue, why do the CLI force me to have a bootstrap application when I only want to have NgModule and use the CLI for run the testing in this case.
    I do not understand why is that a big deal right now, when it's pretty much run the karma testing but for some reason something is stopping before complaining about some code analysis I guess, no clue why.
    The use case is pretty straight forward. 3 applications. First application for the reusable core features. Second application for the github page release. Third application for development testing, like chicken sink for visual testing pretty much, exactly what material2 would use without needs of any gulp or any other setup.

What do we need to do for tackle that use case without any special case? Because so far there is only one issue with it

  1. What happen if we just push the Angular projects as Typescript projects rather than Javascript? You mentioned that Webpack do not compile from node_modules?! The last time I check you actually have to put the exclude filter for node_modules for stop that to happening. Right?!

Please keep it simple.

Now we have that Angular Package Format, we need a projection: (entryFile: string = 'src/public_api.ts') => NgPackageFormat

interface NgPackageFormat {
  main: string,
  module: string,
  /* ... */
}

It will take more than just one input property ... we need ONE workflow for creating that Angular Package Format from source. I agree with @robwormald that unit testing support is a major part. Taking away the burden of configuring several build steps manually will be the NEXT step towards. I do not care about the second and third steps for now. You will fail and the ng cli has failed for almost a year in doing the big "Library developer mode". Please take one decision. Do one step.

-- edit: I excuse for the bold wording. Please let us just stay focused on improving step by step.

@pjpenast please read the package format doc, as it dives into a lot of this, but i'll excerpt the important bit:

In today’s JavaScript landscape, developers will consume packages in many different ways. For example, some may use SystemJS, others could use Webpack. Still, others might consume packages in Node or maybe in the browser as a UMD bundle or through global variable access.

The Angular distribution package supports all of the commonly use development tools and workflow, and adds emphasis on optimizations that result either in smaller application payload size or faster development iteration cycle (build time).

While everyone in this thread is likely using angular CLI, there's a significant portion of our userbase who aren't, or can't, for various reasons. If we're going to have an officially supported tool, it can't exclude anybody who's not using webpack.

You can't make a framework based on compononents that doesn'tallow reuse of components. It's completely absurd.
It does not make sense that Google has not thought the same way.

@angular/material is used by dozens of teams inside of google, and they share their own components amongst themselves - but again, none of them are using webpack or any of the tooling you use - they all use closure compiler, which won't accept webpack output! We compile everything from source - it's simply a different environment.

In our development team, the first thing we did when we started working with Angular was to create a library of reusable components for all our modules.

Great! Maybe you could blog about your solution, and share what you've learned with the Angular community, or write up your findings and share them with us?

@dherges please refer to the Code of Conduct before posting further. Feedback is welcome, but keep it civil.

Now we have that Angular Package Format, we need a projection: (entryFile: string = 'src/public_api.ts') => NgPackageFormat

At a high level, this is exactly what the DevKit is about. It's not something we can simply tack onto the existing CLI. In the interim, a seed/starter project as linked above that implements these patterns seems like a reasonable first step. See https://github.com/filipesilva/angular-quickstart-lib.

@robwormald I understand that there are many different frameworks and you have to try to adapt them all (SystemJS, Webpack, Rollup, etc.), even in Google you have a framework different from the community as explained, which is a problem from my point of sight.

But that problem exists for all the libraries and frameworks of Javascript, it doesn't have to be an inconvenience that will stop you from approaching the community and make it easier for people to develop in Angular.

@angular/material is used by dozens of teams inside of google, and they share their own components amongst themselves.

Yes Angular Material is a good example of reusable code in Angular and we have used it as a reference for our library. But it is a rather complex solution and isn't easy to implement.

The problem in the ecosystem of Angular isn't that it is not possible to make reusable code libraries, we have done it, the problem is that it isn't easy to implement.

Great! Maybe you could blog about your solution, and share what you've learned with the Angular community, or write up your findings and share them with us?

In my team we would be happy to share our knowledge with the community of how we have built a library of components in Angular. Can you tell me the way you have to share this knowledge?

Thanks!

I think it's a big mistake to not listen to the community, in my opinion if you could ask everybody the majority would agree that an official way of making a reusable components' library is necessary. At least the Angular team and the angular material team could put together a simple guide in documentation of how angular material achieves this.

I work with @pjpenast and as he posted, we made work our library with AoT in other projects after a lot of effort and work. The solution was to see how (https://github.com/angular/material2) does this trying to understand its code.

They use the angular wrapper of typescript compiler to create d.ts and metadata.json, Rollup to create bundles and also they replace references to html and styles files with the content of files inline in metadata and javascript generated files.

We assume that Angular is backed by an important company like Google, we assume that Angular has a great support service and community, Above all we assume that if Angular aspires to be the best framework for doing reusable components,there should be no excuses for not having an official method of developing a library after a stable year of life of the framework.

The one immediately actionable item in this thread seems to be the documentation and link to a library seed project. I think it is fair to say that creating libraries isn't as straight forward as one would like but it is certainly possible. We should try to keep things constructive and less hyperbolic.

@hansl would it be possible to build a tool and works WITH a cli generated project to create a library? (use the .angular-cli.json file for info) Not sure if this would provide a solution that is maybe one better then a completely separate seed project?

ng new my-lib && ng-lib ./my-lib

w00t!

@filipesilva Your documentation PR looks like a great start! It's too bad it's stuck behind the aio documentation site's infrastructure upgrade. I'm sure there is a lot of fuming all over this issue queue that will die down once it is published. I'm looking forward to https://github.com/angular/quickstart-lib being a thing.

@robwormald Thanks so much for pointing that PR out, not to mention the presentation at NG Conf about how to package an Angular Library.

@deebloo @hansl Can you point to some docs on how to create new generators in the Angular CLI? I'm interested in playing around with rolling the quickstart-lib into a generator.

@hansl For folks landing on this issue, it might help to point to the documentation PR even if it's not live.

@robwormald thanks for yet more thoughtful, well-explained responses

For folks landing on this issue, it might help to point to the documentation PR even if it's not live.

By that I mean it would be helpful for the folks landing on this issue if the first comment was updated to summarize the efforts being taken.

@deebloo I wouldn't push for another command or any other tool that in the reality should live inside ng.

Angular team,
Look your Polymer partners, they push for bower because of the limitation of npm and everyone hate it but at the same time just dont care because it works at the end of the day and they show you all over the place how to do it. No by reading 3 pages long of some specification or something like that, their strategy includes short videos and a lot of interaction with the community, documentation and so on, but also the tooling backup.

Some take away from there, is that you do not have to adapt to everything in the Javascript community but if you don't teach us how to be productive, care about us, how can we use Angular. I am fine with any architecture and ecosystem switch if I will be back up for the creators and I will find the answers without reading a technical paper (no because I don't know, which I am excluding the people that actually don't, but because that detail on my stack should be far away from me as possible, even Typescripts configs).

And btw, probably the information is there but we failed on put it out.

@deebloo that's the intention behind ng-packagr. There's also a demo showing ng and ng-packagr side by side

@dherges is this what Angular CLI uses? I am trying to push such of tool in the Angular core team. They should be doing that work, IMO

Hi guys,

Following a massive work i'v done to integrate a solid build process I recently converted it to a general purpose repository due to demand in our community.

After some exploration I found that these are the key features a library template should provide:

  • Scoping (npm install @my-scope/my-lib)

  • Multiple library repository (@my-scope/my-lib, @my-scope/her-lib, ... all in the same repo)

  • Package extensions.
    Ship packages with an opt-in internal package (e.g: @angular/core/testing), extension are built separately.

  • Build hooks, tap in to alter package.json, tsconfig, rollup config etc... (globally and per package)

  • Webpack driven

  • Outputs:

    • Flatten ES Modules (es5, es2015)
    • Rollup UMD bundle + minified version + gzipped version
    • Source maps, complete and accurate.
  • Flat Angular compiler module via metadata.json file.

  • Resource inlining (html, css, scss) for source code + metadata.json

  • Resource inlining driven by webpack, no fuzzy tasks, use your favourite webpack loaders.

Some bonus features that are nice:

  • Dedicated demo app, write as if your library is a module (no relative imports)

    • Simulation mode - Run the demo app on the prod compiled library as if its in node_modules, in dev or prod mode.

The simulation is actually a big deal, it enables running the demo app against a compiled, published version of the library where the demo can be JIT and then AOT.
This is a good place to run E2E tests and verify that the publish (to be) version is legit.

The E2E unit tests on the demo app are more aimed towards the library ofcourse, not the demo app.


To make this work there are some changes needed in @ngtools/webpack.
This mainly concerns providing hooks in the AOT plugin for integration.

I'v implemented this in ngc-webpack which is a light compiler-cli wrapper that allows these hooks. (ngc-webpack provides the AOT integration in AngularClass/angular-starter)

The plugin will notify when the AOT compiler loads a resource, this allows saving the resource for future inlining. (lib is built with skipTemplateCodegen false)

The huge benefit here is that we don't need gulp or any other process to manage our resources. They are handled **natively through the webpack loader chain we configured, this is a seamless process that ensures consistency. (think SCSS, postCSS, etc)

@hansl I know that @jskrzypek started talking with tou about that, based on the work I'v done in ngc-webpack, but he had to drop it due to other constraints.


All of the features I'v listed above (+ the demo and simulation) are part of the library starter repository I mentioned previously.

You can check it out in this repo: https://github.com/shlomiassaf/angular-library-starter

It is working great and there are examples there where you can see the output, its the same output as angular packages with support for UMD, FESM (es2015+5), tree shaking etc..

One good example to look at is a scope, multi-lib project with internal extensions (e.g. @angular/core/testing) which I call extensions / plugins.

Scope: @corp

There are 3 libraries and 2 extensions:

  • @corp/core

    • extension: @corp/core/testing
    • extension: @corp/core/plugins/core-plus
  • @corp/common

  • @corp/rare

This is a good example since it demonstrates the capabilities for building a complex structure with inter-dependencies and how they are handled when bundling (rollup external and globals)


Frankly, I'm not a fan of starters if we can integrate it into the CLI, I would love to help getting it into the CLI.

cc @shairez


Edit: Theoretically speaking, if we achieve the above the angular project, material, etc.. can all use the cli, which is remotely similar to TypeScript written in TypeScript :)

@shlomiassaf I really like the idea of build hooks and the in-library scoping of packages.

Currently on Angular Librarian we have a lot of the features you mentioned plus some light scaffolding capabilities (initializing project, components, directives, services) and it'd be great to integrate some of those features in.

I know it's not the official Angular CLI, but I'm just trying to fill the gap in the meantime as best I can.

So I gave https://github.com/filipesilva/angular-quickstart-lib a shot.
And after having spent a day playing with it, my conclusion is that it has a ways yet to go. It's a bit un-DRY, and I dislike the reliance on systemJs and Rollup. While Rollup might produce smaller bundles, I'm drowning in complicated techs that I don't have time to get fully acquainted with; techs that produce obscure errors, from time to time.

So my suggestion for people coming here looking for a module bundling solution, is wait a while longer.

Use npm link for now.

My 2c.

@larssn My guess is that these errors mostly concern the bundling, more specifically defining externals and globals.

IMHO, this will not change in a CLI implementation as well, you will have to provide proper configuration to your library build process.

While there is a high probability that external entries can be discovered automatically, globals are less likely, you'll have to provide them if you want UMD bundle support.

Anyway, building a library is considered advanced and some knowledge, I believe, is expected.

@shlomiassaf Yes, the errors were mostly related to that. I'd fix one, and a new one would pop up. The challenge I laid on myself was to have import support for json. Mostly got it working, except for tests, which is where I gave up for now. Might have been able to solve it; but a part of it was to review the work involved in quickly creating reusable libraries; a point on which I'm not convinced on.

@larssn That happens because you have to declare 3rd party imports. For each unique import token you need an external declaration, that's for FESM. For UMD you also need to declare the global name.

So, if you add import { Observable } from 'rxjs/Observable'; you need to make sure you declare

external: rxjs/Observable
globals: Rx

external is straight-forward, this is why it can be automated.
globals is custom, the way the author decided a UMD bundle will register in the global (e.g. window) object.

Other examples:

rxjs/operator/combineLatest - Rx.Observable.prototype

@angular/common - ng.common

Not so difficult to maintain, specially since rollup will notify whats missing.

For 9-out-of-10 libraries in the Angular world, these configurations can and should be provided w/ well-known values out-of-the-box.

A rollup config for rxjs and the @angular/* packages doesn't need to be copy-pasted from one seed to another seed to yet another starter... it can be simple, when we try to improve one step after another.

Hi folks, I wrote up a proposal of how we can share Angular Modules right now between Angular CLI Apps. I call it __NG Remix__ and it has two principles.

  • Principle 1 - All Angular Modules are uncompiled
  • Principle 2 - Angular Modules share NPM dependencies

In my proposal I discuss how we can apply those principles, the pros and cons, and also include a specification for a ng-remix CLI that could help take out the manual labor. I'm interested in feedback from folks. Certainly those two principles won't work for everyone, but if it works for let's say 50% of the thousands of Angular developers I'd say it could spur a lot of sharing.

See the proposal here -> https://gist.github.com/rjsteinert/82b3000037a5672f43a4d15313ac613f

@robwormald I'd be interested in your thoughts on comparing the seed library approach to the NG Remix approach I proposed above.

@rjsteinert feedback:

  • What does "uncompiled" mean in this context? Shipping Typescript to the outside world is a very, very difficult thing to manage properly - anybody who wants to consume your library has to be able to recreate the entire typesystem / environment on their end. We explored this early on but it appears to be a non-starter.

  • Why does bower come into this? Even the Bower authors are saying it's dead, and adding yet-another-package-manager seems like a bad idea.

I guess i'm not quite clear on what your approach is here?

@robwormald

anybody who wants to consume your library has to be able to recreate the entire typesystem / environment on their end

That's what ng-cli is good at I believe :-). Being an angular-cli created app is a hard requirement and I could make that more clear in that proposal. That also now makes me realize that these modules will eventually need to specify the version of ng-cli they are based on. Note, to someone like me __angular-cli is the Angular Framework__. If a framework is a bunch of things strapped together, angular-cli fits that description better than @angular/angular.

Why does bower come into this?

Lol, ya, surprising. It was recommended by Rob Dodson presenting at Google I/O for use with Angular in the context of Web Components right at this point in the talk. The reason for this is "flat installing". Why would we for example want two different versions of the same module that define the exact same route? Bower helps you sort that out when two modules define the same dependency but at different versions.

@robwormald Updates to your questions now added to the proposal. Thanks for taking a look!

The last few discussions here again stress the point in having small, focused tools do to the job. While seeds and starter packages are a nice thing, the questions is: how do they work together with ng CLI or custom webpack builds, or bazel, or _how-does-YOUR-set-up-look_?

Again, I think, it should be public_api.ts in and a dist folder in Angular Package Format out. As a good start, build and test should be the two commands to support!

# Build the library
$ <angular-library-build-tool> build -p <library-conf>.json
# Run unit tests from *.spec.ts files
$ <angular-library-build-tool> test -p <library-conf>.json

And it's definetly on the agenda for dherges/ng-packagr#5 next!

Well, after reading through #1692 and this issue I'm totally puzzled what approach to use to currently create a library. To get the least problems as soon as the angular / angular-ci team comes up with their own solution.
The most extensive approach seems to be the one from @shlomiassaf at https://github.com/angular/angular-cli/issues/6510#issuecomment-309702987.
But I don't really need the "multiple libs in one repo" approach in my case (although I understand its existence).

So what to choose:
https://github.com/filipesilva/angular-quickstart-lib
or
https://github.com/shlomiassaf/angular-library-starter
or
https://github.com/jvandemo/generator-angular2-library
or check out how they did it:
https://github.com/ng-bootstrap/ng-bootstrap

And if you just try to find a solution on the internet (like most people will do) tutorials like http://www.dzurico.com/how-to-create-an-angular-library/ or https://github.com/tpadjen/tpadjen.github.io/blob/master/_drafts/publishing-an-angular-2-typescript-component-to-npm.md pop up.

It gets even more complicated when you have resources (scss and images) or want to build a library that itself depends on a library/framework like bootstrap or zurb foundation. I fully understand @oliverjanik in https://github.com/angular/angular-cli/issues/6510#issuecomment-305050324 and there should be some official response what to do to fill the gap.

@Flixt See this talk from ng-conf for the most basic setup. Example from the talk is also available on GitHub, so you can take a look. It is not fancy (doesn't have many things you would like to have), but it works and let's you get started quickly.

@Flixt I want to point out that https://github.com/gonzofish/angular-librarian is also out there--similar to generator-angular2-library

It's a WIP, but it's been working for my day-to-day

@devoto13 How do you handle external templates inside components ?
simple-ui-lib mentioned in the talk uses inline templates.

@kkganesan Currently I use only inlined templates and styles. Not very convenient option, but it works for now.

I like how https://github.com/filipesilva/angular-quickstart-lib is made because it builds library to correct angular module format and it has integration tests running in jit and aot modes, but it uses crappy SystemJs. I rewrote development build process to use Webpack for demo app and unit tests in this simple library project https://github.com/anjmao/ang-select.

@robwormald any update on this?

Hey guys. Just wanted to share with you a solution which suits the company needs I am currently working. I managed to make cli work as a mono-repo with multiple apps and a shared library of modules. The current setup supports lazy loading, AOT, SCSS and a custom path ("@shared/") for my shared modules. Although this setup is considered a hack and probably does not follow the Angular Package Format , it does suit our needs. It is simple and easy to work with as you can have multiple apps that can be served/built independently that share your custom components and the same node_modules. The basic repo structure is:

  • src
    --- app1
    --- app2
    --- etc
    --- shared
    ------ components
    ------ providers
    ------ etc
  • dist
    --- app1
    --- app2
    --- etc
  • node_modules

A repo showing the setup after request: Github repo

I do want to thank the Angular team for this fantastic framework as I enjoy working with it everyday. Continue the great work guys :)

Thanks for sharing your solution @nekkon .
Do you have a GitHub repo showing a setup of this structure?.

I have updated the Github repo with more functionality after several requests:

Angular CLI with Library support (1.2.7)

This project was generated with Angular CLI. It is an extended version of a new app generated with ng new. It adds Library support for multiple apps in a mono-repo.

This starter is a result of many workarounds in order to make angular-cli work with a shared library of components/services/modules etc.

Currently supports:

Serving multiple apps at the same time
Production build of multiple apps (with AOT)
Shared Library of components/modules ( can be shared between each app with @shared/ )
Shared assets folder and polyfills. ( can be shared between each app )
Shared SCSS. ( can be shared between each app )
lazy loading of Shared modules
Unit tests for each app
E2E tests for each app
Custom commands to make your life easier
and everything else you would normally be able to do with an app generated with ng new.
Feel free to create an issue for a request or to fix something.

Star and support this project if you like it, to help it stay alive and maybe even be added as a boilerplate/starter to angular-cli (e.x. ng new app-name --template library).

@hansl any updates from the Angular team on this?

@yordis @piernik @desfero @RSginer @samherrmann @benjamincharity @gracegotlost @rafmagns-skepa-dreag Hey guys. Till the Angular-CLI team officially provides you with a library option you can try out library. Feel free to provide feedback, make requests or report issues. I will be updating it constantly cause I use it at work. (current version 1.3.2)

@nekkon Just to unterstand ... angular-cli-library shares common code from TypeScript sources with a compilerOptions.paths mapping, right? So in effect, each app links against sources and re-builds the shared library. The shared library is then not intended to be published on a npm registry, right?

@dherges "angular-cli-library shares common code from TypeScript sources" -> Yes. It uses modules/code located in the src folder, either in your app or from a library (shared code). The library can also be published on an npm registry if you want to. I could add an example to the repo. Because I do not want to pollute this thread, please provide feedback, ask questions, make requests or report issues in the repo

@nekkon Yes and no. If published to npm registries, it should be in the Angular Package Format and this involves a series of different build steps and tools.

@dherges The library can be published to npm registry. I have added an example where the shared library is imported from npm registry (Example2). Imported modules can be lazy loaded in other projects and are aot compatible. From my understanding, this thread is talking about a library that can be imported into other projects. I do not understand you. Why does a library need build steps and tools?

@nekkon would you create some video explaining how to use it and you can add to the video some questions asked already? Some people like me are more visual, just asking, no a big deal

@yordis I could do something like that but it would take me some time to make the video. I'll try to find some time during the weekend.

Fine!

I was mainly speaking about angular package format which is the recommended way of publishing a library - as opposed to publishing source files leaving the typescript compilation, template syntax & type checking, styles preprocessing like vendor-prefixing or scss/less preprocessing to the build tool of the lib consumer.

Cheers, David

On 24. Aug 2017, at 22:44, Nektarios notifications@github.com wrote:

@dherges The library can be published to npm registry. I have added an example where the shared library is imported from npm registry (Example2). It can also be lazy loaded in other projects and is aot compatible.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@dherges Thanks. I will add what you mentioned is missing ( typescript compilation, template syntax & type checking, styles preprocessing like vendor-prefixing or scss/less preprocessing ), although it can be used for most use cases as it is.

When people talk about adding library support, they're usually talking about a pre-compilation step and consuming it like that.

Just want to add my use-case that we need shared code that isn't pre-compiled. We want to be able to provide Core components that consume Images and SCSS variables. Depending on the app served, the SCSS variables provided to those Core components will be different.

We have a white-label website and then we have around 10 "skins" or "brands" or "themes" that only need to change the colours and images. Imagine you need to create 2 applications: "Coca Cola" and "Pepsi". The only thing that changes is the colours and images. We could achieve this with the monorepo stuff though I think

@intellix I recently experimented with project scaffolding for an Angular monorepo. The generated projects have a structure similar to the Angular repo or the structure proposed by Lerna, thus facilitating

  • building libraries in a monorepo
  • building apps from feature packages

I've outlined my main motivations for a monorepo approach in #6083 but repeat some here. (edit: see better explanation below)

@intellix I, too, consider a theme to be a separate package for the same reasons you mentioned. When generating a project you can choose to scaffold a theme-package, too.

From what I've seen so far I can recommend ng-packagr by @dherges to build packages conformant to Angular Package Format (no enterprise experience here, though).

TypeScript just pushed a fix for symlinked repositories containing a node_modules and not being able to resolve types as being the same: https://github.com/Microsoft/TypeScript/pull/18185

I pushed the 2x repositories that work with both angular@next and typescript@next:

Blue CLI depends on Red CLI and uses a component from it. I just referenced angular-cli-red locally since they're not published: "angular-cli-red": "file:../angular-cli-red" so checkout next to each other like:

angular-cli-red
angular-cli-blue

Potential solution until the CLI starts being able to build out component libraries thanks to @dherges's ng-packagr: https://medium.com/@ngl817/building-an-angular-4-component-library-with-the-angular-cli-and-ng-packagr-53b2ade0701e

@nikolasleblanc This is fantastic as a stop gap. Any chance you've used a monorepo setup like lerna with this config?

I've said a couple times in this thread (and I hate self-promoting, but here I go again) I've been working on a project called Angular Librarian that has worked pretty well for my team.

It has all of the scaffolding you'd expect from the CLI and bundles using the Angular Package Format. I'm trying to make it so monorepos can work out-of-the-box.

I really respect what @dherges has done with ng-packagr and it's integration with the CLI, but always want to give people options!

@gonzofish Any chance you and @dherges could work together to merge those projects?

That's probably the best solution, isn't it? I'd be game and I think integrating with the CLI might be a more ergonomic choice

@gonzofish Seems like a solid good goal but also sounds like CLI might change to integrate with DevKit so does integrating with it in its current state mean things get pretty brittle? I can't find it right now but I think the Angular team might have indicated to @dherges already that they weren't interested in landing this in 1.x either. I don't know the answer so would love to hear what Librarian and ng-packagr currently do and what the differences are. @dherges might have to give us some insight into his goals / tradeoffs he's run into. Anyhow I don't want to be the middleman unless the two of you would like it. As someone who is hoping to use these I can see how some consensus would help in an otherwise fragmented environment when it comes to packaging Angular libraries pre-devkit.

Here's a design doc for the motivation of the tool and the purposes of ng-packagr. Think of it as (entryFile: TypeScriptSource) => AngularPackageFormat. You can integrate it with any other build tools around. There's no official support for it, but the GitHub issues are also a source of documentation.

Angular CLI has library developer mode for one year now, well in the announcements. I have no "stake" in Angular CLI and cannot speak for the Angular team. I do not know what their plans are. I just speak about my highly subjective perceptions :-)

When you run several dev teams at different locations, you appreciate to have a common tool chain. Eventually, Angular CLI helps us out a lot for building apps. No one wants to maintain highly customized build scripts in more than {{pick an arbitrary number now}} source code repositories. For libraries we now have a solution, too. We can perfectly live by an opinionated tool and its several best practice configurations.

I published 3 npm packages using https://github.com/robisim74/angular-library-starter as a starting point.
https://github.com/orizens/ngx-infinite-scroll
https://github.com/orizens/ngx-typeahead
https://github.com/orizens/ng2-youtube-player

It's:

  • AOT friendly
  • supports ES5
  • Support UMD bundles
  • easy to publish to npm

Nx looks cool and all but I don't think its trying/meant to solve the library issue at all. It's really just putting everything into a monorepo so that you don't actually have to solve the library issue, right? Putting your whole company under one repo simply isn't going to work for a lot of organizations. Too many teams/people and releases to manage, and too much politics involved. This issue is more for generating standalone libraries that can be exported (and pushed to npm, for example) and imported into other apps (in other repos) - all while doing it with best practices (bundling, minification, etc), and supporting the developer experience as well.

True, Nx is a little bit of an overkill, plus almost nobody does mono-repo projects, except some huge enterprises. We just want Angular CLI to initialize a project in Library mode, that would be so nice.

Putting your whole company under one repo simply isn't going to work for a lot of organizations

nobody does mono-repo projects, except some huge enterprises

@Matmo10 @avatsaev I think you miss the point. Monorepos might not be necessary to build a library. But I think they are important beneficial to how libraries will emerge as part of an app development process. I find that Nx describes pretty much the same story I isolated from my own experience and consolidated here and here.

Monorepo doesn't necessariliy mean to develop all libs of a company in one giant repo (although Google, FB, etc. are said to do so) but also to develop one application from multiple smaller packages in the same repo. App development and library development are two sides of the same coin, I think. Done right, application development is a process of incubating new and reusing existing libraries. And even small companies develop large apps (should better say applications) and need to practice reuse to be competitive. They need to keep building blocks simple and focused to grow their system without growing the mental overhead to understand it on the same scale.

So let's assume collegues from another project asking you if you have solved the logging problem for your app. I can imagine teams which say, yes we have solved it. Just copy our sources. And I can imagine teams which say, yes we have solved it. Just run npm install foo-logging (much more appealing). I can even see the same team copying things around for the Next-Important-Big-Customer project and I can imagine the same team just installing their own logging-lib from the last Important-Big-Customer project.

With Angular and Angular-CLI as of today, unfortunately, I have seen a lot copy-cats beginning to fiddling around with relative import paths extracting the logging services, ngModule and other stuff out of their CLI-generated app once someone asks for reusing this and that. They might not like a monorepo approach and then decide to put the logging parts into a separate repo, okay. The question is why haven't they done it from the beginning?

In my experience - you won't get people to think modular if your project structure encourages a monolith and with costs for modularity as high and complex as they are today. If people have to set up and checkout separate repos for each package, if they have to set up build scripts for each package even more so since building a lib for angular is such a pain, then they simply don't do it early enough. Modularity will be an afterthought. Cutting a monolith into modules is ways harder than doing it right from the start and usually even more than just copying things around (unfortunately, YAGNI always sounds pretty cool unless you find out what N really means and how it relates to Spaghetti).

So you want to develop an application from packages but you don't want to necessarily spread the codebase in as much repos as you might happen to have packages. That's where a project can benefit from a monorepo structure. If it contains a package useful to other teams, then you might decide to move that package into a separate repo at some point in its lifetime. E.g. if you want to spread maintenance efforts accross all teams using the lib (company culture!). However, the first important thing is to imagine this specific package, the second is keeping costs of realising it small and only third step is to moving it into another repo. Monorepos help with all three points. For the third step: you don't have to adjust a mass of relative paths when you always imported foo-logging by its package name rather than its location in your repo. If you have always imported your own packages like an ordinary npm package, then moving it in another repo is peace of cake with minimum impact on the incubator app!

Said, this I think monorepo support is not a must have for library support, but it does definitely assist in library emergence as part of an app development process.

One does not need a monorepo at all! 💯

One could even publish npm packages to private git repositories and npm install | yarn install from git urls! Even angular does for their builds

One does not need a monorepo at all! :100:

@dherges Even though writing about benefits of monorepos I can support that. Being able to make a script iterate over a package folder during build like with ng-packagr is just enough for me at the moment :smiley: (optimized version supporting scoped packages here).

I don't think it's been mentioned here but according to official blog post https://blog.angular.io/the-past-present-and-future-of-the-angular-cli-13cf55e455f8

Future of the CLI
The team working on the CLI has a lot of plans for making developers’ lives even easier. Here are a few of the ideas the team hopes to (but doesn’t promise to) include in future releases:
[....]
Library support — Today the CLI can produce UMDs optimized for the browser, and CommonJS bundles optimized for the server. What if the CLI could help you produce a bundle that could be consumed by other Angular applications?
[...]

We're in the process of making a simple command tool for generating libraries. You just pass the ts-file you want to be the entry point of the library:

ngmakelib src/library.entry.ts library-name

and this creates a tar.gz that you may use directly with npm install.

Currently only exporting FESM module which works for all our usages for reuse in other Angular projects.

By installing this tool in your CLI project you may export it as a library to use in other projects.

You can take a look here:
https://github.com/fintechneo/ngmakelib/

https://github.com/dherges/ng-packagr does that with FESM2015, FESM5, and UMD formats, it's been broken in some uses cases, but the 4.4.5 release of Angular fixed the issue (https://github.com/angular/angular/pull/19579), the ticket was closed today, I've tested and it works great now https://github.com/dherges/ng-packagr/issues/101

There are a lot different aspects to Angular libraries.

  1. Rob said to distinguish binaries and libraries - let's use this terms now!
  2. Monorepos and Nx workspace do favour "libraries": everything is linked within a single source code repo, so every app can build the library from sources – also, this monorepo steam is trending… 🚂
  3. Angular Package Format is for distributing "binaries" to npm registry: the library is build from source before publishing.

I'd say you need to answer first _how_ your workflow is (or _how_ you like it to be)?!

When you have that ... 🎉 , then the very last step is to decide _what_ tools to use. There are a lot of and you have to decide how much you want to get into the details of the "fav tool of week"-thing 😂

Next question of interest: in what direction does the ng CLI want to go? Do they have plans for supporting Angular Package Format? Or is schematics / code scaffolding the primary way, thus telling and assuming to use monorepo? Is it a mixed approach?

@dherges I have great respect for your work and it makes me sound a bit like a smart-ass but I think you misunderstood what Rob meant when he wrote:

At Google, we use the terms "binary" and "library" for this:

  • a binary is a shippable-to-the-browser-artifact that's "self executing"
  • a library is a designed to be consumed by binaries (or other libraries)

Maybe @robwormald can jump in if I am wrong. But I am sure building the library from its sources into Angular Package Format doesn't make it a binary in the sense Rob meant.

Angular Package Format is for distributing "binaries" to npm registry: the library is build from source before publishing.

Let's stick to the APF docs and keep saying its a format for distributing packages / libraries which support the most common consumption patterns as well as the additional requirements to be consumed by Angular apps. The term binary isn't used anywhere in the APF docs. APF-compliant npm packages don't need to be self-executing bundles shippable to the browser. In many cases they will be component libraries like Material UI which aren't ever meant to execute independent of an app. The app is the binary here.

Rob said to distinguish binaries and libraries - let's use this terms now!

He said at Google they do distinguish in the way cited above. I wouldn't read it as a recommendation to adopt Google-internal terminology but just as an explanation by Rob. The term binary isn't self-evident in the JavaScript context and without explanation is misleading at best. In the end I am pretty sure we can skip any "binary" wording when we talk about library support and I advocate to do so to avoid confusion.

It's my understanding of the terms "binary" and "library" (as mentioned by Rob) in the context of a mono-repo (as explained by Victor, and as example used in Nrwl nx workspace).

If I am mistaken, maybe Rob or Victor can help out. But it pretty much sounds like the above because a FESM bundle is self-executing in the browser. You cannot see any output, still you can copy&paste the JavaScript to the browser's console and it will execute the instructions. Also, UMD bundles and IIFEs are self-executing in that perspective.

This issue was created on May 31 2017, and we are still here without any official working solution :(

@robwormald Are you referring to a super power of packaging Angular Components up as Web Components? https://twitter.com/robwormald/status/916748096511500288

If so, perhaps that's a major win for this issue?

I honestly believe that the absence of an easy and reliable solution to make Angular Libraries will drive developers away from the framework.

Right now there's a gazzilion different solutions, all of them shit the bed at some different corner cases, and Angular CLI still can't offer a reliable library mode. I've been Angular dev from the first Beta and this is what frustrates other devs and me the most.

Making a tool to easily build angular libs should be NUMBER 1 PRIORITY right now, not Angular 5, not Angular Universal, not RxJS 5.5/6 compatibility, not PWA, but Angular component libraries.

Nx workspaces are quite brilliant. I've got an example that uses multiple apps with lazy-loading and core modules etc: https://github.com/intellix/nx-cli
My last problem now is that compiler-cli doesn't like that a Component can be declared in 2+ modules which can happen if you need to replace a component by importing only the components you want.

@avatsaev That seems unnecessarily harsh.

There are tons of Angular libraries that already exist, created by developers that had to work hard to figure out how to create component libraries the hard way. Thanks to their efforts, there are tools that exist to try to make developing these libraries easier. If these tools are "sh*tting the bed", it's because they need help. So identify the problem, submit a PR, and fix it.

When the CLI's ready to officially support libraries, we can all shut this down and move on, but until then, let's suck it up and help each other out.

I know I'm always up for a PR on Angular Librarian and I doubt any of the other solutions are adverse to positive contributions to their projects as well

Thanks for saying that @nikolasleblanc

Looking at @filipesilva 's response for #8284, I've realized that Angular CLI doesn't work with libraries in TypeScript out of the box.

@filipesilva, I would like to thank you for explaining the issue and providing the workaround. In addition, I would like to explain my situation in more details.

Our team has faced the same issue as @rolaveric . We are building a product suite, which is made up of smaller applications for different domains. Since all apps follow the same design guidelines, we have a library with reusable shared components.

Actually, we do not have the team dedicated to library development. It is used just as a container for reusable code that can be referenced from applications. So, our library is not a standalone project and makes sense only within apps.

Our team considers TypeScript as a first-citizen programming language. It means that all development is carried out in TypeScript, and all repositories use the same TypeScript version and configuration. Taking this into account, we made a decision to ship our shared library just in TypeScript to avoid extra complexity.

I understand that we are doing this at our own risk and violate the Angular package format. However, since Angular CLI does not provide a solution at this point for libraries, this approach helps to avoid extra complexity of configuring and maintaining a custom build process for libraries. Moreover, this allows to dramatically simplify the application development process since we are able just to reference and test the library directly from the app, getting all benefits of fantastic Angular CLI features (e.g. live reloading) out of the box.

I admit that this can sound a bit hacky, but, from the other, side it helps the team to be focused on product development, but not the Angular build process.

Currently, we consider using the Nrwl Extensions for Angular, which looks really promising.

Does someone face the same issues? What approach would you recommend for such case?

  • Use a custom build process (like ng-packagr)
  • Use a mono repository with the Nrwl Extensions for Angular
  • Ship TypeScript library and wait the official solution from the Angular team
  • Something else

@alexeikostevich If you're in a closed company setting and might even have your own private npm registry then I'd say

  • Ship TypeScript library and wait the official solution from the Angular team

is just good. We've been doing this for the last year and it causes the least trouble for us at the moment. Not publishing TS to the public npm registry is all about web standards (ECMAScript is a standard, TypeScript not), interoperability and ease-of-use (not everyone wants to set up a transpiler). If TypeScript is a defacto standard inside your company then nothing prevents you from publishing TypeScript packages internally. if it works for you just do it.

Nrwl/nx describes an important story (monorepos) in terms of angular app development in general and a story related to library development but not necessarily the solution. E.g. what I don't like about Nrwl/nx is that libs are scoped packages but the scope name is derived from the name of the workspace. So you can't develop packages with different package scopes in the same workspace. Since you say your libraries only make sense within your app a project-specific npm-package scope might be less of an issue to you. If you have a policy, though, that all packages must share a common company-wide package-scope then I guess with multiple workspaces all of these would have to be named identical or you really can have only a single workspace and repo where you develop all of your company's libraries.

Apart from that installing Nrwl/nx via npm didn't work when I tried it. I had to use their bash script install process. For my own purposes the missing flexibility in case of package scopes is a limitation and I posted an issue on this edit: but didn't get an answer so far and the situation is likely to be addressed in some future versions.

What approach would you recommend for such case?

I am afraid its not the answer you look for but in the end I'd honestly recommend to not wait for recommendations but just take an hour or half a day yourself to try Nrwl/nx and ng-packagr. I am sure you'll quickly find out yourself whether they suite your needs or not.

Thank you for the detailed response @about-code !

We really publish our TypeScript library to the private company NPM since the package is not compliant with the web standards, but it helps us to keep going with product development and stay productive.

As you suggested, we will definitely review currently available alternatives in the nearest future. It seems that we are walking on the thin ice, shipping the library in TypeScript, and this can prevent us from updating to the Angular/Angular CLI in the future.

I wanted to raise this problem since this use case should be pretty typical for enterprise development.

Just wondering would it be easier to build something that could produce a library for only cli-based apps?

@neo Solutions for building libraries for consuming in CLI already exists - as mentioned above:

https://github.com/dherges/ng-packagr ( implements full Angular Package Format )
https://github.com/fintechneo/ngmakelib (minimum solution, not full Angular Package Format, but can be consumed in at least other CLI apps, ngc/rollup and SystemJS, I'm the author of this )

@neo although its build process doesn't directly leverage the CLI, my library, Angular Librarian, compiles to Angular Package Format

Hello to everyone.
I am really inspired by such tool like ng-packagr, mentioned above.
I've built simple library example, which is based on basic angular-cli app and ng-packagr. It has preview app inside, supports demo/developer mode and can be easily imported into your running angular5 apps. I've also added compodoc and live-rebuild mode to make it a bit more cool.

Check it out here: https://github.com/Tamango92/yo-lib
Read the docs (sorry in advance, I am not good in writing nice docs), feel free to rename lib in local package.json file and replace all 'yo-' prefixes with your own.

@alexeikostevich

It seems that we are walking on the thin ice, shipping the library in TypeScript, and this can prevent us from updating to the Angular/Angular CLI in the future.

I am less concerned about this, actually. TS is pretty stable in terms of backwards compatibility. The only thing you need to make sure is that your libraries don't declare TypeScript as a hard (dev-) dependency but as a peer dependency with a version range beginning with the minimal TS version the lib expects (based on the language features it uses) up to the next major version. If Angular requires a newer version of TypeScript then consumers of your lib can choose to install a newer or the newest TS version required by CLI and continue to use and compile your lib.

@about-code does angular/cli works ok with "Typescript libs"?
If I understood correctly, you work with private Typescript packages,
do you mind to share how to set them up? thanks for your time!

@matheo I am only using @ngtools/webpack regularly so can't speak about the CLI. But TS libs in the sense I understand them are just plain old NPM packages with TS sources rather than JS sources. They're published to an internal NPM registry untranspiled and when used get installed into node_modules of the dependant. They should have an index.ts at the same level of the package.json. TS implements the Node resolution algorithm and can find the index-file when it is imported via import { FooClass } from "package-name". The index file should (re-)export the public API of the lib - and only the public API. Try to avoid re-exports like export * from "...". TS libs when used in a TS app get transpiled with the app they're used in.

Once again I emphasize that TS libs should live in private registries and packages only. The NPM and node ecosystem shouldn't be polluted with TS libs as they aren't JavaScript and non-standard. Also note what @alexeikostevich wrote and the issue he linked. Some Angular-CLI contributors are heavily against TS-libs (see https://github.com/angular/angular-cli/issues/8284#issuecomment-341417325) so don't take my opinion for granted.

@about-code should we build a registry together 😅 that's what I thought it could be too

@about-code I figured out a way to compile my library with ng-packagr but not setting up the CLI project on the root of the repo, but inside a subfolder. Then I compile the lib to /dist and reference it from the root package.json to be consumed by my other projects. I will share more about this setup after get working all my stuff.
Thanks to all for the great work! :thanksgiving

Following my last issue comment...

I've done a lot of work on this and after analyzing my work I think we can split the problem into 3 parts, from which only 1 (number 3) is an issue related to angular:

  1. Project management (file structure and setup)
  2. Packaging / Bundling
  3. Compiling

I'll write briefly on (1) and (2), (3) is the thing that requires a solution right away.

Notice that (1) and (2) are not unique to angular, any framework or library or vanilla project will have to address these issues.

First some key points:

  • @ngtools/webpack is not related to this process, it bundles apps. For library compilation, we need to work with the @angular/compiler-cli.
  • Webpack can be used to compile resources only (not drive the process nor bundle). This will yield similar results for dev environment and enables usage of the loader configuration we already have!!!

Project management

Angular CLI does this already but for applications, not libraries.
A library needs a demo app for integration tests and easy development... This means that any project is a mono-repo...
This is not trivial, proper setup requires advanced configuration of typescript and webpack.

For now, Nx workspaces provide a proper solution.

Packaging / Bundling

This is the process of taking the compiled output (JS) and packaging it into a format/formats.
Angular has a spec for that, creating bundles in FESM ES2015, FESM ES5 and UMD along with d.ts files and metadata.json files.
This is quite technical and already done properly in several projects (material2, ng-packager, angular-library-starter)

This is an external process, it can be done in the cli or by a different package through @angular/dev-kit via separate config files. Because solutions exists we can use them for now. It is purely an implementation and definitely not the problem.

Compiling

This following might be verbose and complex, apologies :)

Compiling is taking the TS files and compiling them to JS files. This is fairly simple with TypeScript (tsc) but get's complicated when using the angular compiler (ngc)
The pain point is resources (html, scss, etc):

  • The angular compiler knows how to handle HTML and CSS only, al other formats (SCSS, LESS) will not work.
  • The compiler will not inline resources which are required for libraries.
  • Resources appear in 2 locations, JS output and metadata.json files emitted by the AOT compiler.

ng-packager solved this issue using external process and post-processing scripts, it means using different tools then your development environment (dev use webpack, post-process use gulp tools) and doing it externally instead of part of the compiler.

The @angular/compiler-cli packages is extensible, it can be thought how to load resources so they are loaded as part of the compilation process (no post-processing, native inlining). The problem is that it is missing an async API required for loading resources via webpack (see angular/angular#20130)
Once this is fixed it should be easy to do so (it can be done know by creating the API locally, everything requires is available)

By creating a CompilerHost and passing it to angular, we get control over resource loading, the compiler host is the loader of resources (among other things).
Now, all we need is a way to use webpack to compile resources only within the compiler host and return them to ngc. We also add custom transformers to inline all resources on the fly and that's it!!!

For this we need to have an API in the CLI that creates a webpack configuration for us (at runtime) and stops (not building an app), from there are can create a webpack instance and create a compilation that can compile resources.

It might look complicated but I already have a working POC that apply a patch to the cli that allows extracting the config, from there it run's the compilation with a native resource loading through webpack. The result goes through rollup and creates the bundles.

The compilation step is done without extra logic or complicated addition to the cli.

@filipesilva @hansl If it's possible, can we discuss it and I'll come with a proposal that will only allow integrating the compilation step (no bundling, no rollup no nothing).
This is a first step that will break the compilation barrier allowing ngc output that has resources inlined and compiled through webpack with cli configuration.

This is a logical flow:

  • Call CLI API to get webpack config object for a build state (build, prod, dev etc...)
  • Use custom compiler host that has a webpack resource loader loaded and ready to compile resources through the loader chain.
  • Call performCompilation (async version) with the compiler host and an inlining transformer.
  • Output is ready for bundling

Ok, with PR #8643 we should be able to make good progress.

@shlomiassaf Yes, it goes down to the TypeScript transformations which is a sync API. So from there, I chose to go two passes over the *.ts sources.

https://github.com/dherges/ng-packagr/commit/4753066ba7a75e6d570d0ce45052252a56b97214

dherges/ng-packagr#279

it's not really the typescript transformations but more the angular compiler implementation.

The compiler-cli does this split into 2 passes internally thus bypassing the sync limitation of TS.
So first pass will load all resources.

ngc -p will not do async, so it up to the user to do so...

The PR I created (#8643) should solve this

Just wanted to add some comments here.

In my current project we have multi-app angular cli application, which consists of 5 apps and 1 components folder, that shares all the common components between app.

Previously we've used few docker containers with mounted components folder in order to develop all the apps and see changes immediately during development.

After some time we decided to move sources into one single multi-app (thought it will be more flexible). But we ran into the problem, that all configuration files and all apps must be inside of the same folder, i.e. we must have 10 configuration files (1 for app and one for spec) in the same folder + every config file of the app must exclude all the other apps from compilation. We've found that unfriendly, cause cli restricts us and it doesn't give a chance to use other infrastructure. To be precise, ngc with aot doesn't support any baseUrl configurations (relative paths etc.).

Angular Package Format is very nice approach, but for development it gives a lot of pain, because you have to compile and install package every time you change it.

@serhiisol I have a monorepo with 10apps. You don't need to exclude all other apps anymore. That has been fixed in a previous version of the CLI. You can use the following in your tsconfig.app.json:

"include": [ "app1/**/*", "shared/**/*" ], "exclude":[ "**/*.spec.ts" ]

could be, but you can't keep configuration files in the application sources itself, they have too stay one level up with all the other sources (so like 10apps * 2 config files = 20 tsconfig files, which is way strange to see). Besides that you can't have components folder (with all the components, that are shared between apps) if you'll move config files into app sources folder + aot won't work :)

@dherges Does AOT compilation work for you this case? I had similar setup and JIT compilation worked as charm but AOT always complains:

ERROR in ./apps/calculator/src/main.ts
Module not found: Error: Can't resolve './../../../$$_gendir/apps/calculator/src/app/app.module.ngfactory' in '/Users/serhii.sol/Development/mono-app/apps/calculator/src'
resolve './../../../$$_gendir/apps/calculator/src/app/app.module.ngfactory' in '/Users/serhii.sol/Development/mono-app/apps/calculator/src'
  using description file: /Users/serhii.sol/Development/mono-app/package.json (relative path: ./apps/calculator/src)

PS. It seems like this approach doesn't work with lazy-routes (loadChildren)

@serhiisol There are ways to make aot and lazy loading work properly (with workarounds as in a repo I have created https://github.com/nekkon/angular-cli-library) but I agree it is not the right way to go or to have 20tsconfig files. I think all this is until a final proper solution/way is given by the Angular team for how to have a monorepo of multiple apps with a shared library of components (if that ever happens cause it depends on how important they feel it is). I haven't checked https://github.com/nrwl/nx yet, it could be a good solution.

What's the latest status? Are there docs for packaging libraries, yet? This is a very long thread.

Check this Talk: Juri Strumpflohner - Create and publish Angular libs like a Pro by @juristr

It covers most of the Docs using rollup and some other tools.

So basically...
Year and a half since the original suggestion was posted and still no official solution to what should be a fundamental competency for a component framework. 👎

NgPackagr has been an excellent tool to support Angular Library development

NgPackagr has been an excellent tool to support Angular Library development

no webpack support, so no require.context, webpack loaders and all this stuff

@artaommahe Webpack is not fit for library building, it's a known issue:

But since Webpack is still evolving this situation may change in future.

@artaommahe Webpack is not fit for library building, it's a known issue:

non-optimal bundle size and content is a smaller problem for us than inability to inline images/svgs to lib bundle )

sometimes I just feel like maybe we should just use git submodules 😂

Ok as far as I understood this thread, there is multiple packaging tools/strategies or at least starters to start with but I'm still missing one thing. How to actually develop those libs if I can not see a change instantly in my app where this lib is used?

I have a case where I have one app, which uses 5 different libraries. Ones are fairly straight forward and could develop them with good test coverage without testing them inside an app but others are fairly complex and dependent on a few of those 5 libs so without linking/using them together in an app I can not see a way how to develop them? Before Angular 5 I could npm link all of those projects together (they are just plain git repository projecs, basically an apps generated with ng new) and everything just worked. But since Angular 5 I can no longer npm link projects in an Angular 5 app if they are not following APF.

I can develop a build procedure, mono repo, anything that is needed for producing APF compatible libraries with some tool listed in this thread, but how do I develop them? The only way I see to support my case is to develop a process which will build the project into APF compatible lib on every change and link all of them together in an app. But I'm not sure how fast this is going to be, and also it will take some time to develop it in the first place so I'm not very interested in this approach. Is this really the only way, or am I missing something?

@metodribic Have you looked at the solution provided by @vsavkin and team at Nrwl - I think this has been mentioned before in this thread.

We are currently using this for a large enterprise application with 9 internal libraries, running approx 4000+ tests, working with a team of 15 developers. I'm happy to talk through our workflow and tooling if you are interested - unfortunately I can't share our code.

@mattem I'm interested, if you do so, add me please :)

There is also new JavaScript tooling that has emerged that could provide as
a perfect alternative to Java based build orchestration systems (like buck,
bazel, etc). https://github.com/boltpkg/bolt Something to consider :-D

On Mon, Jan 22, 2018 at 11:11 AM Mateo Tibaquirá notifications@github.com
wrote:

@mattem https://github.com/mattem I'm interested, if you do so, add me
please :)

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/angular/angular-cli/issues/6510#issuecomment-359531953,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADQBMIlpYx5RbvPrQoL0l52iDED98rLAks5tNN16gaJpZM4Nqsq5
.

@mattem i would love to know your setup and workflow with nx too, need it very much

And @TheLarkInn see you at ng europe!

@matheo @avatsaev I'll try and write something up about the workflow that we have and the tooling around it

@mattem Interested too ! We will migrate to this workflow soon.

I would love seen projects like @angular/cli/Nrwl working together with project like bolt to solve the issue of managing librairies in a common way :)

@matheo @avatsaev @jogelin we've been running the nx workspace in our app for about 4 months now. We have 11 libs and the development experience is fine (i.e. no compromises).

We are yet to graduate any of those libs to their own repro or publish to our internal npm registry, but so far so good.

@mattem I would be interested in your write up too.

@kevinkuszyk getting the libs through the CI and publishing them to private npm reg is actually the trickiest part, the part that i'm interested in.

@metodribic

But since Angular 5 I can no longer npm link projects in an Angular 5 app if they are not following APF.

You have to add preservesymlinks in .angular-cli.json config

...
"defaults": {
    "styleExt": "scss",
    "component": {},
    "build": {
      "preserveSymlinks": true
    }
  }
...

@avatsaev that's odd, I just checked the nx docs and I don't see any mention of graduating libs out into their own repro or publishing them separately. These were two of the criteria we used when choosing nx.

@vsavkin did I remember correctly, or has there been a change?

We went through some discussions on what to use for our front end framework and after going through the Hero tutorial, I really liked the way Angular is setup and how easy it is to build modules.

I want to separate our services and models from the components so that the services can be re-used by other projects. But, now I find out that Angular wasn't built to to have external libraries, unless you want to choose from one of the 20 hacks that people have written. That's a HARD sell to the company.

Funny that in all the pros and cons of these front end frameworks, that Angular doesn't have a HUGE asterisk next to it for this. There definitely should be. This should be priority # 1 for Angular, but after seeing this issue has been worked on for a year and half, it isn't and that's a deal breaker.

@Holzberg there are solutions that I wouldn't consider hacks and allow you to create libraries:

And, yes, there are other ways of coaxing angular-cli to do it for you.

And If you want to have Angular Mono repo for libraries you can have a look
at this: https://github.com/alan-agius4/ng-mono-repo-starter

On Tue, 23 Jan 2018 at 21:29, Matt Fehskens notifications@github.com
wrote:

@Holzberg https://github.com/holzberg there are solutions that I
wouldn't consider hacks and allow you to create libraries:

And, yes, there are other ways of coaxing angular-cli to do it for you.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/angular/angular-cli/issues/6510#issuecomment-359919986,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AQv-Wmx8nPPZSbNeJZZ7H4_v96A9ZbjAks5tNkEigaJpZM4Nqsq5
.

@gonzofish Those libraries are all 3rd party. There is no standard way.

I tried ng-packagr and I have the library compiling and working when installed into a client app, but how about easier development? Can I link the the files to a demo Angular app so I can test things? It sucks that I have to compile every time. I took the main app component out because that's not needed and I don't want to have to keep that just to do testing.

The only other way I can think of is to create tests in the spec files, but that doesn't allow me to see the rendered result for my directives.

I tried ng-packagr and I have the library compiling and working when installed into a client app, but how about easier development?

same issue here. Cant easely develop via yarn link on sources cause linked files are not compiled by main app's webpack

About working with ng-packagr locally, just add the reference to your /dist files in the main package.json and you will be able to yarn link your library, like:

  "main": "dist/bundles/coachcare-datepicker.umd.js",
  "module": "dist/esm5/coachcare-datepicker.js",
  "es2015": "dist/esm2015/coachcare-datepicker.js",
  "typings": "dist/coachcare-datepicker.d.ts",
  "metadata": "dist/coachcare-datepicker.metadata.json",

you can find your corresponding files in your dist/package.json

@matheo what about linking uncompiled files? I believe that is what @artaommahe was referencing.

I've got the same issue.. I can symlink my dist in fine, but every change requires a full rollup build to be generated which stinks for development speed

There's a talk on packaging libraries tonight at the Angular meetup in Mountain View. I hope we'll show the new ng_package bazel rule that we're moving Angular itself to use for packaging the framework, and which will work for third-party libraries as well.

@alexeagle will this talk b available later somewhere online please?

I believe talks at that meetup are recorded, yes

@dherges In ng-packagr, how do I include external libraries? For instance, I want to use crypto-js and I installed it via npm, but the project using my library errors out. I also tried install @type/crypto-js and that didn't work either.

What am I missing?

Just throwing my https://github.com/dominique-mueller/angular-package-builder in here which also does the job. Still, I'd also prefer an "official" solution for this ...

@Holzberg can you be more specific with what you mean by "errors out"? (Maybe better to open an issue there for this conversation :))

@alexeagle do you know if video recorded of event: https://www.meetup.com/it-IT/Angular-MTV/events/246637957/ will be published quite soon?

@meriturva The video is up here: https://youtu.be/QfvwQEJVOig?t=1h12s

Waiting for an "official" process also. Submoduling an angular project through git submodule works in the mean time..

There's a WIP currently that may allow to include ng-packagr (https://github.com/angular/devkit/pull/444) as a build tool into the Angular CLI in the future, among other possibilities.

Meanwhile using ng-packagr is perfectly fine, or you can use a more "monorepo" setup which is promoted by the nrwl/nx Angular CLI extension. I've talked about these recently, video of the talk should be up very soon as well:

The repository in specific has branches which show the various setup possibilities.

@juristr please post the video here when uploaded, very very needed, thanks :)

So for everyone interested, my talk from ngVikings is up:

I also would like to share something I came up with in order to make kinda final solution for the overall problem. Maybe it sounds a bit trivial, but still it could be helpful for somebody.

The repo of @juristr is able to create a library but there is also a requirement to have a demo for the library, right? So, the idea is that the repo has / uses:

  • all angular/cli features
  • ng-packagr in order to build the library

We can extend it with the idea that the angular cli app is a demo app where one can develop and see the result while developing and, most important, show the library in action to the consumers.

The key configuration points are (all below is of course not strict):

  1. Change output of angular cli to be dist-demo
  2. Change ng-packagr output folder to be dist-lib
  3. Add the repository name to be the base url for the package.json build: ng build --prod --base-href=/<your-repo-name-here>/
  4. Adapt .gitignore to include the dist folders above

and finally configure travis to deploy both demo to github pages and the library to npm repo with something similar to:

language: node_js

node_js:
  - '8'

script:
  - npm run build
  - cp dist-demo/index.html dist-demo/404.html
  - npm run packagr

before_deploy:
  - cd dist-lib

deploy:
  - provider: npm
    email: <your-email-here>
    api_key: $NPM_TOKEN
    skip_cleanup: true
    on:
      tags: true
  - provider: pages
    local-dir: dist-demo
    skip-cleanup: true
    github-token: $GITHUB_TOKEN
    keep-history: true
    on:
      branch: master

Here you go: the repo, the demo and the library with a minimal effort.

Would be quite good if future angular/cli could also generate a travis config for the library, because from my experience travis is not that newbie-friendly.

The only problem that i'm facing with ng-packagr is that it compiles everything before-hand, so it's not possible to add specific styles or overwrite SCSS variables for specifics projects.

To do like angular-material it will be necessary to remove the view encapsulation, that will be a huge refactoring of the components/scss.

I don't think if there's a solution this case 😞

Use CSS variables ;-)

Unfortunately, @oliverjanik, there are some cases in which we need to support browsers that don't support CSS variables like IE 11 (enterprise apps) 😞

The impossibility of scss / whatsoever styles variables configuration does not come from ng-packagr. This is a limitation of AoT which needs to compile everything beforehand. Thus, it is also not a problem which Angular CLI can / should solve.

The only visible (to me) solution of this problem is another workaround on top of the ViewEncapsulation on the angular core side, which will allow to support style variables that are coming from angular (kinda component variables to styles injection). In fact, angular would need to bind data not to HTML only but to the CSS as well.

Looking at all this from the prospective of angular core, I would rather wait for CSS variables in major browsers and do nothing instead of building a predictably dead piece of the framework.

As a result, extendng what @oliverjanik has said, use CSS variables or wait until they are supported in the major browsers :) For now, don't use the component styles.

I just read the update a few hours ago to the angular CLI, looks like we'll finally get this feature :+1:

Library support! That was one of the most requested feature. You can generate a new library in your project by using ng generate library <name>.

@geocine any hints as to how to get this installed? I just installed latest cli but doesn't look like it's available yet.

Update: I see it in 6.0.0 rc2 (https://github.com/angular/angular-cli/releases) but it doesn't seem to be working yet.

@ivanirjoao the library functionality is still in release candidate form; not fully released. So yarn add @angular/cli@latest will still give you 1.7.4 but yarn add @angular/cli@next should give you the release candidate.

See all available versions: https://www.npmjs.com/package/@angular/cli

Hello!

A new library can be created with the ng generate library command only? And create _application_ project before.

I think it would be convenient to create a new Lib project in this way (in addition to _generate_):
ng new <name> --type library

+1 for ng new <name> --type library as @aastrouski suggested

In version 6.0.0 of Angular CLI you will be able to create, test and lint libraries.

This functionality is available in the latest RCs of 6.0.0, and documentation can temporarily be found at https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/create-library.md. Once 6.0.0 reaches final, the documentation will be moved to the main wiki.

Does it support sub-library?

For example @angular/common/http or @angular/core/testing

Thanks.

On Thu, 3 May 2018 at 2:22 Filipe Silva notifications@github.com wrote:

In version 6.0.0 of Angular CLI you will be able to create, test and lint
libraries.

This functionality is available in the latest RCs of 6.0.0, and
documentation can temporarily be found at
https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/create-library.md.
Once 6.0.0 reaches final, the documentation will be moved to the main wiki.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/angular/angular-cli/issues/6510#issuecomment-386150875,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFIN3XLCMpv9hR04NamAEKAfwSLjFZwiks5tuj-ZgaJpZM4Nqsq5
.

Does it support sub-library?

Answer: Yes, by using NX and some changes to ng-packer json files and tsconfig files.

You can create sub-libraries without the need of NX. You can do so by configuring secondary entry points https://github.com/dherges/ng-packagr#secondary-entry-points

@alan-agius4 yes, that's what NX does but it also adds auto tsconfig support and seamless runtime support (no need to rebuild, demo runs on ts files)

I know that CLI blocks this by design but I can't work like that.
Anyway I run my tests on the built package

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NCC1701M picture NCC1701M  Â·  3Comments

naveedahmed1 picture naveedahmed1  Â·  3Comments

gotschmarcel picture gotschmarcel  Â·  3Comments

IngvarKofoed picture IngvarKofoed  Â·  3Comments

jmurphzyo picture jmurphzyo  Â·  3Comments