如何使用 angular-cli (6.x) 创建 mono-repo 项目结构
How to create a mono-repo project structure with angular-cli (6.x)
我想使用 angular-cli 生成一个新的工作区
目前唯一的方法是 运行:
ng new asdf
cd asdf
ng g application whatever
但是所有 src/
文件都保留了下来(以及现在存储不一致的项目的原始 angular.json 信息)。没有 src
文件夹就无法创建新的回购...当我使用自定义原理图通过本质上复制 angular-cli 的 ng-new
并删除 https://github.com/angular/angular-cli/blob/6449a753641340d8fc19a752e1a1ced75f974efa/packages/schematics/angular/ng-new/index.ts#L61 来执行此操作时schematic('application', applicationOptions),
每当我运行它...
$ 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)
只有 e2e 文件被放入 projects/
,angular.json
文件大部分为空:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {},
"cli": {
"defaultCollection": "my-schematic"
}
}
我怀疑这与应用程序示意图中的某些无提示故障或路径关闭有关...但我想先检查是否有更简单/更优选的方法。
$ 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
编辑注意我熟悉第 3 方库(例如 Nrwl/Nx),但我试图避免这些。我也将此问题发布到 GitHub:https://github.com/angular/angular-cli/issues/11402
试试 ng g application {project-name}
。
结果
和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"
}
目前没有办法按照我的意图执行此操作。
hacky 解决方法是 运行:
ng new <mono-repo name>
cd 进去 (cd <mono-repo name>
)
生成第一个应用名称(ng generate application <app-name>
)
然后删除原来的 src / e2e 文件夹 (rm -rf src e2e
) 和 angular.json 中的相应条目。
从那时起,无论何时生成库/应用程序,所有内容都将在项目文件夹中。
如果您不希望您的初始应用驻留在 /src 中,您可以按照以下 2 个步骤操作:
ng new my-workspace --create-application=false --defaults
--create-application
告诉 Angular CLI 不要生成初始应用程序。
--defaults
告诉 Angular CLI 不要提示你关于路由和 CSS 预处理器
ng generate application my-app
通过这两个步骤,您将得到如下文件结构:
.
├── .git/
├── node_modules/
├── projects/
├── .editorconfig
├── .gitignore
├── README.md
├── angular.json
├── package.json
├── tsconfig.json
├── tslint.json
└── yarn.lock
您将在 projects
文件夹中找到您的应用程序及其对应的 e2e 应用程序:
projects/
├── my-app/
└── my-app-e2e/
我这里是如何使用 Nx 和 Angular CLI 执行此操作的指南
here
最简单的方法就是从生成一个空的 Angular CLI 项目开始:
ng new --createApplication false
或者如果您使用 NX:
create-nx-workspace myworkspacedemo
从这里您可以在应用程序文件夹中生成应用程序:
ng g app myapp
并在 libs 文件夹中生成库:
ng g lib mylib
如果您使用的是 NX 原理图,这也会提示您进行许多额外的配置选项,例如生成惰性加载模块、路由、使用 Jest 等...
好吧,创建一个 monorepo 架构太容易了
让我们看看
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
除此之外,您还可以 运行 不同端口上的所有应用程序并单独创建构建
我想使用 angular-cli 生成一个新的工作区
目前唯一的方法是 运行:
ng new asdf
cd asdf
ng g application whatever
但是所有 src/
文件都保留了下来(以及现在存储不一致的项目的原始 angular.json 信息)。没有 src
文件夹就无法创建新的回购...当我使用自定义原理图通过本质上复制 angular-cli 的 ng-new
并删除 https://github.com/angular/angular-cli/blob/6449a753641340d8fc19a752e1a1ced75f974efa/packages/schematics/angular/ng-new/index.ts#L61 来执行此操作时schematic('application', applicationOptions),
每当我运行它...
$ 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)
只有 e2e 文件被放入 projects/
,angular.json
文件大部分为空:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {},
"cli": {
"defaultCollection": "my-schematic"
}
}
我怀疑这与应用程序示意图中的某些无提示故障或路径关闭有关...但我想先检查是否有更简单/更优选的方法。
$ 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
编辑注意我熟悉第 3 方库(例如 Nrwl/Nx),但我试图避免这些。我也将此问题发布到 GitHub:https://github.com/angular/angular-cli/issues/11402
试试 ng g application {project-name}
。
结果
和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"
}
目前没有办法按照我的意图执行此操作。
hacky 解决方法是 运行:
ng new <mono-repo name>
cd 进去 (cd <mono-repo name>
)
生成第一个应用名称(ng generate application <app-name>
)
然后删除原来的 src / e2e 文件夹 (rm -rf src e2e
) 和 angular.json 中的相应条目。
从那时起,无论何时生成库/应用程序,所有内容都将在项目文件夹中。
如果您不希望您的初始应用驻留在 /src 中,您可以按照以下 2 个步骤操作:
ng new my-workspace --create-application=false --defaults
--create-application
告诉 Angular CLI 不要生成初始应用程序。--defaults
告诉 Angular CLI 不要提示你关于路由和 CSS 预处理器
ng generate application my-app
通过这两个步骤,您将得到如下文件结构:
.
├── .git/
├── node_modules/
├── projects/
├── .editorconfig
├── .gitignore
├── README.md
├── angular.json
├── package.json
├── tsconfig.json
├── tslint.json
└── yarn.lock
您将在 projects
文件夹中找到您的应用程序及其对应的 e2e 应用程序:
projects/
├── my-app/
└── my-app-e2e/
我这里是如何使用 Nx 和 Angular CLI 执行此操作的指南 here 最简单的方法就是从生成一个空的 Angular CLI 项目开始:
ng new --createApplication false
或者如果您使用 NX:
create-nx-workspace myworkspacedemo
从这里您可以在应用程序文件夹中生成应用程序:
ng g app myapp
并在 libs 文件夹中生成库:
ng g lib mylib
如果您使用的是 NX 原理图,这也会提示您进行许多额外的配置选项,例如生成惰性加载模块、路由、使用 Jest 等...
好吧,创建一个 monorepo 架构太容易了
让我们看看
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
除此之外,您还可以 运行 不同端口上的所有应用程序并单独创建构建