如何不在Angular2生产包中包含模拟服务

Dav*_*han 17 mocking angular-cli angular

在构建用于生产的角度2 app时,我们使用

ng build --prod --w --aot 
Run Code Online (Sandbox Code Playgroud)

但是我们的模拟服务也可能因为我们拥有而捆绑和缩小

import {XMockService} from "./xxx-mock.service";
Run Code Online (Sandbox Code Playgroud)

这可以防止树摇晃丢弃未使用的服务.这是我们简化的app.module.ts,它在environment.mock = true时有条件地延迟加载模拟服务

我想这是一个常见的场景,但我找不到任何答案.

app.module.ts:

import {BrowserModule} from "@angular/platform-browser";
import {NgModule} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {AppComponent} from "./app.component";
import {environment} from "../environments/environment";
import {XService} from "./xxx.service";
import {XMockService} from "./xxx-mock.service";

let importedModules: Array<any> = [
  XService
];

if (environment.mock) {
  importedModules.push(
    {provide: XService, useClass: XMockService}
  );
} else {
  importedModules.push(
    XService
  );
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: importedModules,
  bootstrap: [AppComponent]
})

export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

Fab*_*nes 8

因此,根据其中一个主要贡献者,您的问题的解决方案将是这样的:

// main.ts
import './polyfills.ts';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment, AppModule } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);

// environments/environment.ts
export { DevModule as AppModule } from '../app/dev.module';

export const environment = {
  production: false
};
// environments/environment.prod.ts
export { ProdModule as AppModule } from '../app/prod.module';

export const environment = {
  production: true
};
Run Code Online (Sandbox Code Playgroud)

所以它与我之前的答案非常相似,不同之处在于您将使用不同的环境文件,而不是使用不同的主文件.

上一个答案

它最近在Angular-cli上开了一个问题,请求一个允许你这样做的功能.怎么样?通过切换您的webpack入口点.现在Angular-cli总是使用相同的入口点src/main.ts,这个功能背后的想法是你可以指定一个不同的入口点,所以你会有类似的东西src/main.dev.ts:

import './polyfills.ts';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppDevModule } from './app/app.dev.module';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppDevModule);
Run Code Online (Sandbox Code Playgroud)

然后你会导入你的模拟AppDevModule:

import {BrowserModule} from "@angular/platform-browser";
import {NgModule} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {AppComponent} from "./app.component";
import {environment} from "../environments/environment";
import {XMockService} from "./xxx-mock.service";

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [XMockService],
  bootstrap: [AppComponent]
})

export class AppDevModule {}
Run Code Online (Sandbox Code Playgroud)

这样做,让唯一的缺点是,你必须保持你AppModuleAppDevModule同步.

您可以通过创建第三个文件来解决这个问题,例如AppImportsModule:

import {BrowserModule} from "@angular/platform-browser";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {AppComponent} from "./app.component";
import {environment} from "../environments/environment";

export {AppComponent} //we also export this for simplicity

export const declarations = [
  AppComponent
];

export const imports = [
  BrowserModule,
  FormsModule,
  HttpModule
];
Run Code Online (Sandbox Code Playgroud)

然后在您AppModule.tsAppDevModule.ts您只需要导入您的提供商:

import {NgModule} from "@angular/core";
import {declarations, imports, AppComponent} from "./app.imports.module";
import {XMockService} from "./xxx-mock.service";

@NgModule({
  declarations, // with es6 this is the same as "declarations: declarations"
  imports, //same as above
  providers: [XMockService],
  bootstrap: [AppComponent]
})

export class AppDevModule {}
Run Code Online (Sandbox Code Playgroud)

因此,在没有实现该功能之前,我没有更好的解决方案来解决您的问题.


Sri*_*nth 3

所选答案不再有效。对于 Angular CLI 6,按照建议,我们必须将 dev 和 prod 视为共享相同代码库的单独项目。

解决方案总结

  • 每个环境都有单独的项目。(就像 angular.json 中的几行一样简单)
  • 拥有与 env 数量一样多的 AppModule,每个模块都有单独的 main.ts 文件
  • 每个环境都有单独的 tsconfig 文件
  • 通过 angular.json 告诉 Angular 有关更改的信息

细节

复制 AppModule 并将其命名为 DevModule。(DevModule 用于开发,AppModule 用于产品)。DevModule 将是具有模拟服务的模块。

每个都有单独的 main.ts 文件。对于 prod 来说是 prod-main.ts,对于 dev 来说是 dev-main.ts。唯一的区别是 prod-main 加载 AppModule,而 dev-main 加载 DevModule。

将 tsconfig.app.json 文件复制到 tsconfig.prod.json 和 tsconfig.dev.json。在 tsconfig.prod.json 的排除部分中,输入“dev-main.ts”、“app/dev-module.ts”、“**/mock-*.ts”。也输入其他开发模块(加载模拟的模块)。

对开发人员重复此操作。对于 tsconfig.dev.json,排除 prod-main.ts、app/app-module.ts。如有必要,也对 tsconfig.spec.json 文件进行相关更改(具有类似的排除)。

更新 angular.json 文件以反映新的 tsconfig 文件。

// angular.json. Only the relevant parts are given below.
// Essentially, separate tsconfig files for 2 projects - dev & prod
{
  "newProjectRoot": "projects",
  "projects": {
    "my-prod-proj": {
      "architect": {
        "build": {
          "options": {
            "main": "src/main-prod.ts",
            "tsConfig": "src/tsconfig.app.json",
          },
        },
        "test": {
          "options": {
            "tsConfig": "src/tsconfig.prod.spec.json",
          }
        },
        "lint": {
          "options": {
            "tsConfig": [
              "src/tsconfig.prod.json",
              "src/tsconfig.prod.spec.json"
            ],
          }
        }
      }
    },
    "my-dev-proj": {
      "architect": {
        "build": {
          "options": {
            "main": "src/dev-main.ts",
            "tsConfig": "src/tsconfig.dev.json",
          }
        },
        "test": {
          "options": {
            "tsConfig": "src/tsconfig.dev.spec.json",
          }
        },
        "lint": {
          "options": {
            "tsConfig": [
              "src/tsconfig.dev.json",
              "src/tsconfig.dev.spec.json"
            ],
          }
        }
      }
    },
  },
  "defaultProject": "my-prod-proj",
}
Run Code Online (Sandbox Code Playgroud)

按名称运行项目

ng serve my-dev-proj // dev with mocks
ng serve             // prod (set as default in angular.json)
same goes for the build command
Run Code Online (Sandbox Code Playgroud)