Skip to content

Configurable project structure #2232

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

Closed
imhoffd opened this issue May 9, 2017 · 12 comments
Closed

Configurable project structure #2232

imhoffd opened this issue May 9, 2017 · 12 comments

Comments

@imhoffd
Copy link
Contributor

imhoffd commented May 9, 2017

Some pathing is hard-coded in CLI v3. Support configurability and detect issues when something isn't where it's expected to be.

See:

@imhoffd
Copy link
Contributor Author

imhoffd commented Feb 12, 2018

Some research: we're expecting some packages to be installed in <ionic dir>/node_modules (not parent directories). It would be much better to utilize require()/require.resolve() to use the proper node resolution algorithm, however with global CLIs it becomes difficult to substitute where require.resolve() looks for modules (it uses a set of paths that works backwards from the location of the main module, require.main).

For Node 8, require.resolve() got a new option, paths, which would allow us to use the algorithm to lookup modules in the standard way starting at a base directory of our choice. This would allow devs to use a monorepo setup where the ionic app is in a subdirectory and all dev dependencies are installed in the main repo. The problem is, a good chunk of CLI users are still using Node 6, and it's not particularly feasible to ask them to upgrade when the LTS EOL is over a year away.

This leaves us with 3 options:

  1. Require a local CLI installation.
  2. Require Node 8.
  3. Write a shim for Node 8's require.resolve() (probably not particularly difficult).

@johneast
Copy link

With regards to the three options and my own use case, I'd be happy with any of them. I wouldn't mind having to go through a couple of extra steps to set up my environment, for instance having to install a local version of the CLI, if I get the benefits of a mono-repo.

@PoiScript
Copy link

I suggest that we can provide this feature only for Node 8 or higher users. Anyone who wants this feature can upgrade their nodejs and get it automatically. :)

@imhoffd
Copy link
Contributor Author

imhoffd commented Feb 13, 2018

@johneast Aside from what I've detailed, are there any additional issues with the Ionic CLI related to using a monorepo? As a side note, FYI: Ionic Pro appears to support custom directory structures with custom npm scripts: https://ionicframework.com/docs/pro/basics/concepts/customizing-builds.html

imhoffd added a commit that referenced this issue Feb 14, 2018
This doesn't fix every issue Ionic apps have in monorepos, but it's a
good start from the CLI.

See #2232 for more info.

address #2987
address #2988
@imhoffd
Copy link
Contributor Author

imhoffd commented Feb 14, 2018

@johneast In your original issue, you mention you lose the ability to organized code in a monorepo as soon as an ionic project is added. Can you elaborate? Are the issues with the build process?

I found this commit, which makes me believe we likely won't be able to support monorepos for Ionic Angular v2/v3 projects with @ionic/app-scripts for tooling. However, Ionic Angular 4 will use the Angular CLI for tooling, which could make this work.

But... when I looked into importing a shared lib from a separate folder like @PoiScript wanted to do and building my app with the Angular CLI, I ran into this issue: angular/angular-cli#8783

I can fix what the Ionic CLI is doing wrong (and I have, see 9f1e202), but we're going to run into these issues everywhere.

The ecosystem just doesn't seem to be ready for it... so let's compile a list of issues and tackle them one at a time.

@johneast
Copy link

@dwieeb The biggest issue for me was the fact that I couldn't change the location of the node_modules folder. What I'd like to do, in the situation where I have multiple apps in my project repo is just have the one node_modules folder in the root and everything pulling in dependencies from there.

After that, the next biggest issue was the process of configuring the build scripts to pull in my shared lib code. I was able to do it by modifying webpack.config.js and watch.config.js in the config folder in my app project and the tsconfig.json file in the root.

For instance, my webpack.config.js looks like this:

const fs = require('fs');
const path = require('path');
const useDefaultConfig = require('@ionic/app-scripts/config/webpack.config.js');

// Taken from https://github.com/Robinyo/big-top/blob/master/config/webpack.config.js
// See also https://robferguson.org/blog/2017/11/22/working-with-typescript-webpack-and-ionic-3/
const env = process.env.IONIC_ENV;
useDefaultConfig[env].resolve.alias = {
  "@libs": path.resolve('../../libs/')
};

module.exports = function () {
  return useDefaultConfig;
};

My watch.config.js looks like this:

const watchConfig = require('../node_modules/@ionic/app-scripts/config/watch.config');
watchConfig.srcFiles.paths = [
    '{{SRC}}/**/*.(ts|html|s(c|a)ss)',
    '../../libs/**/*.(ts|html|s(c|a)ss)'
];

And my tsconfig.json looks like this:

{
  "compilerOptions": {
   ...Other config...
    "baseUrl": "./src",
    "paths": {
      "@libs/*":[
        "../../../libs/*"
      ]
    }
  }
 ...Other config...
}

At this point, I've had to specify the same path in three different locations and I don't feel I'm getting the benefit of the Ionic tooling as I'm having to do all the work myself. Also, this doesn't scale well. If I change my libs folder, or add others in, then I have to make many changes.

A nice option might be to have some config options in the ionic.config.json that feeds into webpack and tsc etc. Maybe something like:

{
    "name": "MyApp",
    "type": "ionic-angular",
    "paths": {
        "@libs": {
            "path": "../../../libs"
            "extensions": [".ts", ".js", ".html"]
        }
    }
}

A further enhancement, might be the ability in the ionic.config.json file to specify the root location of the app, relative to the location of the config file. That way, the ionic scripts can be in the root of the mono repo, but I could build and launch an app that is in a different location, and if I could specify the name of the app when I invoke the scripts, and the appropriate config is pulled in, that would greatly simplify things when I have multiple apps I want to test and build.

From the root of the repo I'd like to be able to run the command

ionic build MyApp1 --prod

MyApp1, might live in a sub folder, such as apps/myapp1/, and ionic.config.json might look like:

[{
    "name":"MyApp1",
    "root": "apps/myapp1",
    ...other config...
},{
    "name":"MyApp2",
    "root":"apps/myapp2",
    ...other config...
}]

That way I could choose which app to run or build. The default operation could still be to have one app that doesn't have to be named to be built or served.

Hope that all makes sense.

@imhoffd
Copy link
Contributor Author

imhoffd commented Apr 17, 2018

@johneast Thank you for the detailed explanation. Yes, it makes sense. Our use case throughout the years has been for single-app repos, but I'm hearing more and more that people want monorepo support for their Ionic projects.

I'll reiterate that support for monorepos in Ionic Angular 4 will be much better, simply because we've switched from our in-house @ionic/app-scripts tooling to the Angular CLI, which will support multiple projects in a single repo quite well in version 6. I'm not sure we'll tackle this issue in @ionic/app-scripts, as we'll be recommending people start switching to the Angular CLI for their apps when Ionic Angular 4 lands. Most of that path configuration, for example, would likely be done in one location: angular.json.

Our position on tooling has been changing from trying to do all the optimizations ourselves to reworking Ionic itself such that it can be applied to any framework effectively and efficiently and then letting that framework handle tooling.

📝 The Ionic CLI still makes some assumptions about the project structure, such as prompting for node_modules installation (see #3087 (comment)) and trying to git init during ionic start. I'll be working on these soon.

@imhoffd
Copy link
Contributor Author

imhoffd commented Apr 17, 2018

@johneast As for that last point (multiple apps in one ionic.config.json), I have to do some research on how we'll be handling multiple "apps" (according to angular.json) in Ionic. Lots of unknowns still and I've been tackling some higher priority issues.

@johneast
Copy link

@dwieeb Thanks for the update. Sounds great.

@WhatsThatItsPat
Copy link

Just chiming in to mention Nrwl / Nx (and their workspaces) to make sure this is part of the research here.

@PoiScript
Copy link

If I have understood correctly, Nx is nothing special but some handy schematics that help you build multiple apps in the same repo and you still serve and build everything using Angular CLI :).

The primary problem is that we can not specify which project to use with ionic-cli, for example, if I run ionic serve or ionic build --prod and it will always choose the first one.

@imhoffd
Copy link
Contributor Author

imhoffd commented Jul 30, 2018

Closing in favor of this issue: #3281 as I think documentation for a multi-app setup and configurable structure is the last piece of the puzzle this 🎉

If I'm mistaken, please let me know. 😄

@imhoffd imhoffd closed this as completed Jul 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants