Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Multi-app projects config #3281

Closed
imhoffd opened this issue Jun 3, 2018 · 6 comments
Closed

Multi-app projects config #3281

imhoffd opened this issue Jun 3, 2018 · 6 comments
Labels
docs project type: angular Ionic Angular 4+ projects

Comments

@imhoffd
Copy link
Contributor

imhoffd commented Jun 3, 2018

Branching off main issue re: project structure configurability: #2232

We can add support in the Ionic CLI for multi-app projects.

@PoiScript summed it up nicely:

The primary problem is that we can not specify which project to use with ionic-cli

These multi-app projects are typically in the shape of monorepos which have multiple apps and libraries.

  • For now, let's assume all apps are of the same project type: angular. This means a shared angular.json at the root of the monorepo.
  • The starters come with an angular.json. Not a big deal, but it would need to be deleted

The builders in ng-toolkit were built with Angular 6 tooling, so they support any project structure that the Angular CLI does. The issue is how do we map ionic serve and related project commands to the requested project such that Ionic and Angular know which project to use.

These commands already have a --project and --configuration option to configure which map to configuration within angular.json. I think all we need to do is read angular.json, use the key from --project and find the project root and then look for ionic.config.json inside the specified directory.

cc @stupidawesome

@ionitron-bot ionitron-bot bot added the triage label Jun 3, 2018
@imhoffd imhoffd added this to the Ionic Angular 4 milestone Jun 3, 2018
@imhoffd imhoffd added project type: angular Ionic Angular 4+ projects and removed triage labels Jun 3, 2018
stupidawesome added a commit to stupidawesome/ionic-cli that referenced this issue Jun 4, 2018
…gle workspace. Related ionic-team#3281

Adding `--project` support for almost every Ionic command.

Create an `ionic.json` config in project root. This closely mirrors `angular.json` but doesn't depend on it.
```
{
  "defaultProject": "app",
  "projects": {
    "app": {
      "name": "Ionic App",
      "type": "angular",
      "integrations": {
        "cordova": {
          "root": "cordova"
        }
      },
      "hooks": {}
    }
  }
}
```

Example commands
```
# With project name
ionic cordova platform add android --project app

# With defaultProject
ionic cordova platform add android

# Other commands
ionic cordova resources --project app
ionic cordova plugin add cordova-plugin-splashscreen --project app
ionic cordova build --project app
ionic cordova run --project app
ionic cordova emulate --project app
ionic cordova requirements --project app
ionic cordova prepare --project app
```
stupidawesome added a commit to stupidawesome/ionic-cli that referenced this issue Jun 5, 2018
…. Related ionic-team#3281

Adding `--project` support for almost every Ionic command.

Create an `ionic.json` config in project root. This closely mirrors `angular.json` but doesn't depend on it.
```
{
  "defaultProject": "app",
  "projects": {
    "app": {
      "name": "Ionic App",
      "type": "angular",
      "integrations": {
        "cordova": {
          "root": "cordova"
        }
      },
      "hooks": {}
    }
  }
}
```

Example commands
```
# With project name
ionic cordova platform add android --project app

# With defaultProject
ionic cordova platform add android

# Other commands
ionic cordova resources --project app
ionic cordova plugin add cordova-plugin-splashscreen --project app
ionic cordova build --project app
ionic cordova run --project app
ionic cordova emulate --project app
ionic cordova requirements --project app
ionic cordova prepare --project app
```
@stupidawesome
Copy link
Contributor

stupidawesome commented Jun 5, 2018

Working on a proof of concept that should enable support for multi-app workspaces by adding additional configuration to ionic.config.json.

Constraints:

  1. The workspace consists of a single monorepo with multiple apps and libraries.
  2. Each Ionic "project" should map to one angular "project" of the same name.
  3. Additional configuration is needed to enable a multi-app workspace.
  4. Existing apps should continue to work without introducing new breaking changes.
  5. Potentially support other project types

Case Study:
Given the following ionic.config.json configuration:

{
    "defaultProject": "first-app",
    "projects": {
        "first-app": {
            "type": "angular",
            "integrations": {
                "cordova": {
                    "root": "integrations/first-app/cordova"
                }
            }
        },
        "second-app": {
            "type": "angular",
            "integrations": {
                "cordova": {
                    "root": "integrations/second-app/cordova"
                },
                "capacitor": {
                    "platforms": {
                        "electron": {
                            "root": "integrations/second-app/electron"
                        }
                    }
                }
            }
        }
    }
}

And the following extract from angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "",
  "projects": {
    "first-app": {
      "root": "projects/first-app/"
    },
    "second-app": {
      "root": "projects/second-app/"
    }
  }
}

We can produce the following directory structure:

.
├── projects
|   ├── first-app
|   └── second-app
├── integrations
|   ├── first-app
|   |   └── cordova
|   |       ├── build.json
|   |       ├── config.xml
|   |       ├── platforms
|   |       |   ├── ios
|   |       |   └── android
|   |       ├── plugins
|   |       ├── resources
|   |       └── www
|   └── second-app
|       ├── cordova
|       └── electron
├── node_modules
├── angular.json
├── ionic.config.json
└── package.json

When running Ionic commands, the defaultProject will be used if it isn't specified using the --project flag. The goal is to also make it possible to "switch" projects from the CLI via ionic config set defaultProject or something similar. Note that the defaultProject from angular.json will not be used.

The root key is important as it sets the current working directory for cordova. Capacitor integration here is only illustrative and not part of this proof of concept.

With this configuration and directory structure in place, we can now run some commands:

Generate resources for the second app

ionic cordova resources --project second-app

Add platform for the second app

ionic cordova platform add ios --project second-app

Build the first app (via ng-toolkit)

# Can omit --project since it's the defaultProject
ionic cordova build ios

And so on...

Existing Apps:
The current proposal is strictly opt-in, meaning that existing Ionic apps will continue to work without making any changes to ionic.config.json. To make this possible the CLI will look for the projects key in the configuration file to determine whether the workspace is set up for single or multiple apps. Migration however should be easy, and new projects could potentially be generated in the newer format.

To migrate an existing app to the new configuration schema:

{
  "defaultProject": "app",
  "projects": {
     "app": { ...yourCurrentConfig }
   }
}

Other considerations:

  • This assumes a single git repo without submodules for application code.
  • This assumes a single root level node_modules for sharing dependencies. We might need additional package.json files for storing cordova config/dependencies?
  • Only considering angular project types for now.

@imhoffd
Copy link
Contributor Author

imhoffd commented Jun 5, 2018

new projects could potentially be generated in the newer format

angular projects will likely default to multi-app because Angular itself does

This assumes a single root level node_modules for sharing dependencies. We might need additional package.json files for storing cordova config/dependencies?

Yep, Cordova config would need to be stored in separate package.json files. I'm tempted to assume a monorepo structure like a lerna project. Lerna can hoist and dedupe dependencies to a node_modules folder at root, but it's not a requirement. If dependencies are hoisted, it still creates symlinks for bin files in each package for package dependencies. For example, if a package depends on rimraf, it will install it into the root node_modules, but it will create a node_modules/.bin/rimraf symlink inside the package that links back to the root. The lerna way is the proper way to manage dependencies in a monorepo.

stupidawesome added a commit to stupidawesome/ionic-cli that referenced this issue Jun 9, 2018
…. Related ionic-team#3281

Adding `--project` support for almost every Ionic command.

Create an `ionic.json` config in project root. This closely mirrors `angular.json` but doesn't depend on it.
```
{
  "defaultProject": "app",
  "projects": {
    "app": {
      "name": "Ionic App",
      "type": "angular",
      "integrations": {
        "cordova": {
          "root": "cordova"
        }
      },
      "hooks": {}
    }
  }
}
```

Example commands
```
# With project name
ionic cordova platform add android --project app

# With defaultProject
ionic cordova platform add android

# Other commands
ionic cordova resources --project app
ionic cordova plugin add cordova-plugin-splashscreen --project app
ionic cordova build --project app
ionic cordova run --project app
ionic cordova emulate --project app
ionic cordova requirements --project app
ionic cordova prepare --project app
```
imhoffd pushed a commit that referenced this issue Jun 13, 2018
* wip: proof of concept for running multiple apps in a single workspace. Related #3281

Adding `--project` support for almost every Ionic command.

Create an `ionic.json` config in project root. This closely mirrors `angular.json` but doesn't depend on it.
```
{
  "defaultProject": "app",
  "projects": {
    "app": {
      "name": "Ionic App",
      "type": "angular",
      "integrations": {
        "cordova": {
          "root": "cordova"
        }
      },
      "hooks": {}
    }
  }
}
```

Example commands
```
# With project name
ionic cordova platform add android --project app

# With defaultProject
ionic cordova platform add android

# Other commands
ionic cordova resources --project app
ionic cordova plugin add cordova-plugin-splashscreen --project app
ionic cordova build --project app
ionic cordova run --project app
ionic cordova emulate --project app
ionic cordova requirements --project app
ionic cordova prepare --project app
```

* refactor: adapt multi app workspace to single app config

By treating each "project" as its own self-contained ionic configuration within "projects" we can reuse most of the existing command logic.

* fix: start and config commands

* refactor: clean up code and pass cwd to shell commands

* fix: syntax and runtime errors

* fix: throw exceptions when trying to use unknown project name

* fix: throw exceptions more reliably when project type cannot be detected

* feat(ng-toolkit): pass through cordova base path to ng cli

* test: add a few more tests
@imhoffd
Copy link
Contributor Author

imhoffd commented Jul 5, 2018

@ph55 subscribe to this issue. I will be building out documentation for this. You can also look at the commits linked in this issue to figure it out for yourself if you'd like to test. The latest RC has this. See this issue for testing instructions: #3019

@imhoffd
Copy link
Contributor Author

imhoffd commented Jul 30, 2018

Hi all! 👋 Ionic 4 was released! (see the announcement on our blog)

But, I still have to write some documentation about a multi-app config for CLI 4. We wanted to make the experience for single-app repos solid first. Please be patient, and thanks for subscribing to this issue for updates!

📝 One bonus: with this, we can also document how to modify angular.json to customize project structure! 🎉

@imhoffd
Copy link
Contributor Author

imhoffd commented Aug 3, 2018

Moving to ionic-team/ionic-docs#83

@matheo
Copy link

matheo commented Sep 18, 2019

Just want to thank you guys for the awesome stuff!
ionic capacitor run android -l --address=0.0.0.0 worked like a charm within a multi-project repo, so much time saved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs project type: angular Ionic Angular 4+ projects
Projects
None yet
Development

No branches or pull requests

3 participants