Как не включать макет услуг в пакет Angular2

При создании приложения angular 2 для производства мы используем

ng build --prod --w --aot 

Но наши макетные услуги также попадают в связку и минимизируются, вероятно, потому что у нас

import {XMockService} from "./xxx-mock.service";

что не позволяет дрожанию дерева отбрасывать неиспользуемую службу. Вот наш упрощенный 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 {}

Ответ 1

Итак, согласно одному из основных участников, решение для вашей проблемы будет выглядеть примерно так:

// 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
};

Так что это очень похоже на мой предыдущий ответ, разница в том, что вы будете использовать разные файлы окружения вместо разных основных файлов.

Предыдущий ответ

Недавно открыла проблему на 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);

И затем вы импортируете свои mocks на 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 {}

Единственный недостаток в том, чтобы делать это таким образом, заключается в том, что вам нужно будет синхронизировать ваши AppModule и AppDevModule.

Что вы могли бы решить, создав третий файл, что-то вроде 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
];

И затем на вашем AppModule.ts или AppDevModule.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 {}

Итак, пока эта функция не будет реализована, у меня нет лучшего решения для решения вашей проблемы.

Ответ 2

Пример условной сборки (Webpack):

export default class XMockService {

  ...

}

if(environment.mock)
{
    let XMockService = System.import('./x.mock.service');
    importedModules.push(
       {provide: XService, useClass: XMockService}
    );
}

Он создаст дополнительный фрагмент, например 0.chunk.js.