How to create a mono-repo project structure with a

2020-07-24 03:11发布

问题:

I'd like to use the angular-cli to generate a new workspace

The only way to do this at the moment is to run:

ng new asdf
cd asdf
ng g application whatever

but then all of the src/ files remain (and the original angular.json info for a project that is now inconsistently stored). There's no way to create a new repo without the src folder... and when I do this using a custom schematic by essentially duplicating angular-cli's ng-new and removing https://github.com/angular/angular-cli/blob/6449a753641340d8fc19a752e1a1ced75f974efa/packages/schematics/angular/ng-new/index.ts#L61 schematic('application', applicationOptions),

Whenever I run it...

$ ng new asdf -c=my-schematic
$ cd asdf
$ ng g application whatever
    {"inlineStyle":false,"inlineTemplate":false,"routing":false,"prefix":"app","style":"css","skipTests":false,"skipPackageJson":false,"name":"whatever"}
CREATE projects/whatever-e2e/protractor.conf.js (752 bytes)
CREATE projects/whatever-e2e/src/app.e2e-spec.ts (304 bytes)
CREATE projects/whatever-e2e/src/app.po.ts (208 bytes)
CREATE projects/whatever-e2e/tsconfig.e2e.json (219 bytes)

Only the e2e files get put into projects/ and the angular.json file remains mostly empty:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {},
  "cli": {
    "defaultCollection": "my-schematic"
  }
}

I suspect this has to do with something silently failing in the application schematic or a path being off... but I wanted to check first if there was an easier / more preferred way.

$ ng --version                                                 

Angular CLI: 6.1.0-rc.0                                        
Node: 10.1.0                                                   
OS: win32 x64                                                  
Angular: 6.0.7                                                 
... animations, common, compiler, compiler-cli, core, forms    
... http, language-service, platform-browser                   
... platform-browser-dynamic, router                           

Package                      Version                           
------------------------------------------------------         
@angular-devkit/architect    0.7.0-rc.0                        
@angular-devkit/core         0.6.8                             
@angular-devkit/schematics   0.6.8                             
@angular/cdk                 6.3.1                             
@angular/cli                 6.1.0-rc.0                        
@angular/material            6.3.1                             
@schematics/angular          0.6.8                             
@schematics/update           0.7.0-rc.0                        
rxjs                         6.2.1                             
typescript                   2.7.2     

Editing to note I'm familiar about 3rd-party libraries (e.g. Nrwl/Nx) but I'm trying to avoid those. I also posted this issue to GitHub: https://github.com/angular/angular-cli/issues/11402

回答1:

There currently isn't a way to do this the way I intend.

The hacky workaround is to run:

ng new <mono-repo name>

cd into it (cd <mono-repo name>)

generate the first app name (ng generate application <app-name>)

and then remove the original src / e2e folders (rm -rf src e2e) and the corresponding entry in angular.json.

From then on whenever libraries / applications are generated everything will be in the projects folder.



回答2:

If you don't want your initial application to resides in /src, you can follow these 2 steps:

ng new my-workspace --create-application=false --defaults
  • --create-application tells the Angular CLI not to generate an initial application.
  • --defaults tells the Angular CLI not to prompt you about routing and CSS preprocessor
ng generate application my-app

With these two steps, you will end up with a file structure like this:

.
├── .git/
├── node_modules/
├── projects/
├── .editorconfig
├── .gitignore
├── README.md
├── angular.json
├── package.json
├── tsconfig.json
├── tslint.json
└── yarn.lock

And you will find your application and its corresponding e2e application in the projects folder:

projects/
├── my-app/
└── my-app-e2e/


回答3:

Try ng g application {project-name} instead.

Result

And Angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "mono-repo": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/mono-repo",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "mono-repo:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "mono-repo:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "mono-repo:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "styles.css"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "mono-repo-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "mono-repo:serve"
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "project-alpha": {
      "root": "projects/project-alpha/",
      "sourceRoot": "projects/project-alpha/src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/project-alpha",
            "index": "projects/project-alpha/src/index.html",
            "main": "projects/project-alpha/src/main.ts",
            "polyfills": "projects/project-alpha/src/polyfills.ts",
            "tsConfig": "projects/project-alpha/tsconfig.app.json",
            "assets": [
              "projects/project-alpha/src/favicon.ico",
              "projects/project-alpha/src/assets"
            ],
            "styles": [
              "projects/project-alpha/src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "projects/project-alpha/src/environments/environment.ts",
                  "with": "projects/project-alpha/src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "project-alpha:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "project-alpha:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "project-alpha:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "projects/project-alpha/src/test.ts",
            "polyfills": "projects/project-alpha/src/polyfills.ts",
            "tsConfig": "projects/project-alpha/tsconfig.spec.json",
            "karmaConfig": "projects/project-alpha/karma.conf.js",
            "styles": [
              "projects/project-alpha/src/styles.css"
            ],
            "scripts": [],
            "assets": [
              "projects/project-alpha/src/favicon.ico",
              "projects/project-alpha/src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "projects/project-alpha/tsconfig.app.json",
              "projects/project-alpha/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "project-alpha-e2e": {
      "root": "projects/project-alpha-e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "projects/project-alpha-e2e/protractor.conf.js",
            "devServerTarget": "project-alpha:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "project-alpha:serve:production"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "projects/project-alpha-e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "mono-repo"
}



回答4:

I here is a guide how to do this using Nx and Angular CLI here The easiest is just to start with generating an empty Angular CLI project:

ng new --createApplication false

or if you use NX:

create-nx-workspace myworkspacedemo

From here you can generate apps in the app folder with:

ng g app myapp

And generate libs in the libs folder with:

ng g lib mylib

If you are using NX schematics this will also prompt you for a lot of extra configuration options such as generating lazy loaded modules, routing, use Jest etc...



回答5:

Okay it's too easy to create a monorepo architecture
let's see

By doing this you specified an architecture without consisting any application. this gives you code like this...

OOoh it seems you have created your architecture
now come into your code editor and now create your application

Now time to check if everything works well or not.
let's run with any random port where you want...

you can have multiple application in single architecture and they all would going to use the same node modules
so in future once you update your any module, all your applications would be accessing the updated one so no need to update them one by one

apart from you can run all your applications on different different ports and create the build as separately