ngrx / store-log-monitor

Log Monitor for @ngrx/store-devtools and Angular

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Not including monitor module in production mode

mattma opened this issue · comments

This is really a question, not an issue.

I have followed the readme setup to get it working. It is all good. But in production environment, I do not want to include the "monitor" ngModule, so that I use environment.production variable to check the current environment.

What I did in two different places.

1> setup an local typescript private variable 'private env: environment.production' so that I could use it in my template <ngrx-store-log-monitor *ngIf="env"></ngrx-store-log-monitor>

2> in app.module.ts file, I use the condition to check the current environment, to include the StoreLogMonitorModule and StoreDevtoolsModule.

But the problem is that in ES2015 import statement cannot be wrapped inside a condition. It will raise an error here.

if (environment.production) {
  import { StoreDevtoolsModule } from '@ngrx/store-devtools';
  import { StoreLogMonitorModule, useLogMonitor } from '@ngrx/store-log-monitor';
}

Is there a better way to handle building in production to not include the "development" related modules? ex: ng build -prod

Hi, I have the same question ;) Could you provide your current app.module.ts ? I am not quite sure how you add StoreLogMonitorModule & StoreDevtoolsModule based on the environment.

@Uter1007 I do not have a good solution at the moment. I am seeking for help as well. Currently, I was thinking to deploy the development monitor along with the production environment, only use CSS to hide its visual. Although it sounds bad, but it saved much time to commit file changes when deploy to prod.

commented

+1

This is my team approach:

  1. import store log/dev tools modules
  2. fill some local imports const with development/production modules
  3. fill another local devImports const with development modules only
  4. if dev environment detected, append devImports to imports
  5. register imports under app NgModule imports: property

Here's a code excerpt:

// ...
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { StoreLogMonitorModule, useLogMonitor } from '@ngrx/store-log-monitor';
// ...

let imports: any[] = [
  BrowserModule,
  HttpModule,
  StoreModule.provideStore(appReducer),
  // ...
];

const devImports: any[] = [
  // NOTE: instrument must come *after* importing StoreModule
  StoreDevtoolsModule.instrumentStore({
    maxAge: 7,
    monitor: useLogMonitor({
      visible: false,
      position: 'left',
      size: 0.20,
    }),
  }),
  StoreLogMonitorModule,
];

// enable logging and monitor only in development
if (NODE_ENV === 'development') {
  imports.push(devImports);
}

@NgModule({
  imports,
  // ...
})
export class AppModule {
}

Actually, devImports definition could also be brought under devevelopment if-branch

@BrainCrumbz

First of all, thank you for sharing your approach. I did something similar that manage an array of imports and then pass through NgModule imports property.

What we really want is, completely eliminate development modules in production environment. Even not import them in the Production env. Well, there are two problem in your approach.

First,

The template use <ngrx-store-log-monitor> tag. It is an Angular 2 directive. If you do not import the import { StoreDevtoolsModule } from '@ngrx/store-devtools';, it cannot compile the template because the directive is not imported. Even you add *ngIf="condition", directive is still missing.

@Component({
  selector: 'app',
  template: `
    <ngrx-store-log-monitor toggleCommand="ctrl-h" positionCommand="ctrl-m"></ngrx-store-log-monitor>
  `
})
export class AppComponent { }

Second,

You have imported the StoreDevtoolsModule in your code. Tree shaking cannot drop off from the dist script. We are still not saving the loading bits.

Re. first point:
After replying to this thread, later on, in my team we faced the same problem with production + AOT build. Please have a look at #20 where I replied to my own issue. Basically you declare a dummy substitute component, and add that to the declarations when needed.

Re. second point:
As you mentioned already, import instructions cannot be inserted in conditional branches. So they're either present or not in a single file, cannot be made optional. Thinking out loud, from this point of view the minimum level of "granularity" you can get is file-level, as you can include or not a file in your build chain.

Assuming that you're importing debug modules in some app.module.ts, which in turn is imported by some main.browser.ts entry point, you can create alternative files for production Vs development. So e.g. a main.browser-prod.ts, importing an app.module-prod.ts where the debug modules are not imported at all. I guess app.component.ts could stay the same, you just need the dummy replacement for ngrx-store-log-monitor node.

@brandonroberts This is a great solution. I love it. It works as expected.

@BrainCrumbz No more hacks. Simply remove it. :)