angular / angular-cli

CLI tool for Angular
https://cli.angular.io
MIT License
26.73k stars 11.98k forks source link

Add ability to import, install & setup an external library into your project #9387

Closed Brocco closed 4 years ago

Brocco commented 6 years ago

Background

Adding support for an external library (i.e. @angular/material) into your project can be a difficult task for a few reasons, most notably is the multiple steps to get things configured and setup properly. This could require going back and forth between documentation, blog posts and/or video tutorials.

Desired behavior

Add a command to the Angular CLI which would allow users to add functionality of a library to their project.

ng add [name of library]

An example would be to add support for @angular/material which could handle the following steps automatically:

Implementation Considerations

Determination of the library to be added: possibilities considered thus far:

  1. a pre-determined name which can resolve to a library/schematic (i.e. material -> @angular/material)
    • pros: simpler cognitive load on users
    • cons: maintaining a list of libraries is not practical
  2. a schematic path (i.e. `@angular/material:add)
    • pros: very explicit about what will be run
    • cons: could cause confusion and allow running of any schematic
  3. the package name (i.e. @angular/material) map to the schematic could live in the package's package.json file
    • pros: clearly conveys what logic will be added, gives control/responsibility to the library owner
    • cons: no clear cons at this time

Additional/Future Features

Add an option to ng new to allow adding library support upon project creation ng new foo --add=[name of library]

IgorMinar commented 6 years ago

I'm not sure if you are thinking about it in the right way. Or at least I think what I asked for is different than the feature proposed.

What you are proposing is essentially bypassing the npm/yarn client and having a wrapper around these tools to add packages. This is how ember-cli did it, maybe they still do.

Why can't you do the same via a postinstall hook in these packages? So instead off:

ng add @angular/material

you would do

yarn add @angular/material

this would kick off a postinstall script defined in the material package that would do whatever you are trying to do via add.

So, contrast that with what I had in mind when we talked about it. What I'd like to have is for me to be able to say that when I'm starting a new project, I want it to be based on a non-default starter template/schematic.

ng new @angular/material/layouts/basic-with-sidenav

this would do the following:

We should not try to make this work for existing projects because of a possibility to clobber files and mess stuff up. This feature would be just for brand new projects. If a developer wants to apply this to an existing project they can generate a new project and manually move files around into an existing project.

In this proposal I'm intentionally piggy backing on the existing material package because maintaining lots of packages is a pain in the butt, and we don't want users to remember lots of different packages. Because of these reasons we should seriously consider including these schematics within the material package (subject to discussion with @jelbourn).


side (bottom) note: we also discussed the --pwa option. I think this should be just a flag because to pwa or not is orthogonal concern to what start layout/template to use. So ideally I should be able to do something like:

ng new @angular/material/layouts/basic-with-sidenav --pwa
IgorMinar commented 6 years ago

adding @amcdnl who's working on the layouts/starter templates for material. Austin, can you please review and provide feedback? My goal is to make the first-time-user experience great. thanks

clydin commented 6 years ago

This use case may be more tangential to ng add then. And the goal for this use case would be to turn ng new into a form similar to the following:

ng new <template> [new-options] [template-options]

wherein template would be an identifier that references an underlying schematic that would setup a new application as it sees fit. The command would also default to the standard existing CLI template if none provided. This would also allow some of the current options to be turned into templates instead (e.g., --minimal). It might be useful to include standard Angular templates (material, for instance) with the CLI. (These could be bundled directly or point to an external location). However, a design question would be: what should be allowed as a template identifier. Should it be unique template names? Or a npm package reference? a schematic file? Or should there be an install mechanism to register allowed templates with the global CLI (the CLI has a global config file that could be leveraged). Or a combination of the aforementioned? From a new user perspective, having simple names may be the most beneficial. As node/npm/yarn, packages, etc. may be a brand new experience.

amcdnl commented 6 years ago

@IgorMinar I created a schematic for the CLI that you would run once you have an existing Angular application scaffolded and would enhance that setup by adding:

Reference: https://github.com/amcdnl/material-schematics/tree/master/src/shell

As an end user, I wouldn't want my package manager doing this for me setup for me. Yes, it would be magical and whatnot but it would be unexpected and jarring for advanced users who need to fine comb some of this operations (such as making fonts local vs over CDN). If the action were to take place as a CLI command, I believe there would be a different expectation from the end user and whats going on.

In that schematic collection, I also have schematics that will scaffold out navigation/etc by generating new components. At first I started with replacing the existing code in place (app.component/etc) but then realized like you mentioned it would clobber existing setups and people could want to be adding this in post development phases. Instead I took the approach of generating a new component that had everything already added/imported/etc and they could easily drop that tag into existing pages. While this isn't as a magical approach, its impossible to determine what the end user whats to do in this situation without asking a series of questions which wouldn't be as clean and still have a rocky implementation.

Reference: https://github.com/amcdnl/material-schematics/tree/master/src/nav

I think building on the story of a ng new dashboard --material or something along those lines would be a compelling story for new app creation and kick starting them with material. The community could easily expand this adding things like ng new dashboard --bootstrap/etc.

Brocco commented 6 years ago

@IgorMinar I'm not really a fan of the post install handling for this... by having a post-install script handling the addition of features there is no controlling how often that is being run. It would not just run when the dep is added, but also whenever someone reinstalls deps, a new dev sets it up and when CI runs to name a few.

I think we should be more explicit about adding features, but I think adding the ability to specify which functionality/setup should be added is a good idea. To continue upon the material examples, one could setup a project with left-nav, and another could use a top-menu nav (as a quick example)

FriOne commented 6 years ago

It would be great to be able to add libraries interactively. For example, if we ran ng add @angular/material a console start to asking us what we want to include, change, where we should place modifications, etc. It may store answers in variables that is passed then to schematics of a library (material in this case). So, in that way we need tools to make possible easily write own library with set of questions, variables and rules to apply changes that are needed to user.

Airblader commented 5 years ago

Shouldn't this issue be closed now? That's what schematics do, right? ;-)

kyliau commented 4 years ago

Closing this, since the feature requested can already be fulfilled by ng add today.

angular-automatic-lock-bot[bot] commented 4 years ago

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.