Best Practice: Remove `@ngrx/store-devtools` in production
If you are using `@ngrx/store-devtools` in your application, you should remove it in production.
In production @ngrx/store-devtools
should be completly removed from the bundle.
Let's see an example:
Start a new angular application
npx @angular/cli@latest new ngrx-remove-devtools --style css --routing false --minimal
Install @ngrx/store
and @ngrx/store-devtools
cd ngrx-remove-devtools
npx ng add @ngrx/store --skip-confirmation
npx ng add @ngrx/store-devtools@latest --skip-confirmation
Populate your state
app.module.ts
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot(
{
counter: () => 0,
},
{}
),
StoreDevtoolsModule.instrument({maxAge: 25, logOnly: !isDevMode()}),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Read-onlyExamine the state
If you have the Redux dev tools installed you can now examine your state.
ng serve
Problem examine state in Production
It's best to disable redux dev tools in production.
npx ng build
cd dist/ngrx-remove-devtools
npx http-server
Redux dev tools still works in production
Solution 1
If on production do not place the StoreDevtoolsModule.instrument
in the imports array.
npx ng generate environments
add a production
key to the environments files:
src/environments/environment.development.ts
export const environment = {
production: false,
};
Read-onlysrc/environments/environment.ts
export const environment = {
production: true,
};
Read-onlyapp.module.ts
import {environment} from '../environments/environment';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot(
{
counter: () => 0,
},
{}
),
!environment.production ? StoreDevtoolsModule.instrument({maxAge: 25, logOnly: !isDevMode()}) : [],
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Read-onlyProblem
@ngrx/store-devtools
is still in the bundle
npx ng build --source-map
npx source-map-explorer dist/ngrx-remove-devtools/main.4a92d461e97ce051.js
it will add around 16kb
of unused code to your bundle.
Replace app.module.ts
We can achieve the same result with fileReplacement
.
src/app/imports.common.ts
import {BrowserModule} from '@angular/platform-browser';
import {StoreModule} from '@ngrx/store';
export const commonImports = [
BrowserModule,
StoreModule.forRoot(
{
counter: () => 0,
},
{}
),
];
Read-onlysrc/app/imports.development.ts
import {StoreDevtoolsModule} from '@ngrx/store-devtools';
import {commonImports} from './imports.common';
import {isDevMode} from '@angular/core';
export const imports = [
...commonImports,
StoreDevtoolsModule.instrument({maxAge: 25, logOnly: !isDevMode()})
];
Read-onlysrc/app/imports.ts
import {commonImports} from './imports.common';
export const imports = [...commonImports];
Read-onlysrc/app/app.module.ts
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {imports} from './imports';
@NgModule({
declarations: [AppComponent],
imports: [...imports],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Read-only@ngrx/store-devtools
is completly removed from the bundle.
The source code is available here.