Warning: budgets: initial exceeded maximum budget - optimization

I get the following error when I run npm build --prod:
Error: budgets: initial exceeded maximum budget. Budget 1.00 MB was not met by 500.42 kB with a total of 1.49 MB.
I also get this warning:
Warning: C:\Users\PATH_TO_FILE\socket.service.ts depends on 'socket.io-client'. CommonJS or AMD dependencies can cause optimization bailouts. For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
I'm also importing quite a few Angular Material modules. This is my app.module.ts (It's the only module in my whole project):
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { FontAwesomeModule } from '#fortawesome/angular-fontawesome';
import { AppComponent } from './app.component';
import { SocketService } from './services/socket.service';
import { AppRoutingModule } from './app-routing.module';
import { ClipboardModule } from '#angular/cdk/clipboard';
import { MatFormFieldModule } from '#angular/material/form-field';
import { MatInputModule } from '#angular/material/input';
import { MatButtonModule } from '#angular/material/button';
import { MatTooltipModule } from '#angular/material/tooltip';
import { MatIconModule } from '#angular/material/icon';
import { MatChipsModule } from '#angular/material/chips';
import { MatSliderModule } from '#angular/material/slider';
import { MatButtonToggleModule } from '#angular/material/button-toggle';
import { MatDialogModule } from '#angular/material/dialog';
import { AdminPanelComponent } from './components/admin-panel/admin-panel.component';
import { ChatMessageComponent } from './components/chat-message/chat-message.component';
import { ChatPanelComponent } from './components/chat-panel/chat-panel.component';
import { DrawingPanelComponent } from './components/drawing-panel/drawing-panel.component';
import { PlayerComponent } from './components/player/player.component';
import { PlayersPanelComponent } from './components/players-panel/players-panel.component';
import { ToolsPanelComponent } from './components/tools-panel/tools-panel.component';
import { ChatMessageDirective } from './directives/chat-message.directive';
import { PlayerDirective } from './directives/player.directive';
import { GameManagerComponent } from './components/game-manager/game-manager.component';
import { ArtistOptionsComponent } from './components/artist-options/artist-options.component';
import { InfoPanelComponent } from './components/info-panel/info-panel.component';
import { DialogComponent } from './components/dialog/dialog.component';
#NgModule({
declarations: [
AppComponent,
AdminPanelComponent,
PlayersPanelComponent,
DrawingPanelComponent,
ChatPanelComponent,
PlayersPanelComponent,
ToolsPanelComponent,
ChatMessageComponent,
ChatMessageDirective,
PlayerDirective,
PlayerComponent,
GameManagerComponent,
ArtistOptionsComponent,
InfoPanelComponent,
DialogComponent,
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
BrowserAnimationsModule,
FontAwesomeModule,
ClipboardModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatTooltipModule,
MatIconModule,
MatChipsModule,
MatSliderModule,
MatButtonToggleModule,
MatDialogModule
],
providers: [SocketService],
bootstrap: [AppComponent]
})
export class AppModule { }
How can I fix this issue of exceeding the maximum budget (I think it's the socket.io-client module)? As a side question: Can I optimize the app.module.ts file?

Those are configurations in your angular.json.
Locate it and then look for budgets.
Now you can change the values there to your need.
ex:
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
to
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
You can give values that fits you limit.

You can always increase the threshold by increasing the budget limit, but you should look for ways to reduce your initial budgets. You can use source-map-explorer to analyze each and every module in your application and determines what really need and not important to start the application.
For example, you can remove some of the dependencies and features from your app module which do not need to start the app and take those to a lazy loaded module. This would reduce your initial app loading time by reducing initial bundle size.
The below picture is an example of initial bundles which an angular app needs when it starts.
Refer this article if you need to setup source-map-explorer to your project.
https://dev.to/salimchemes/analyzing-angular-bundle-with-source-map-explorer-341

Related

Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle in react native

I can't figured out this warning . I examined import and exports but still I can't comprehend what warning means
Require cycle: src\components\index.ts -> src\components\LoadNavigation.tsx -> src\components\index.ts
//index.ts
export { default as LoadAssets } from "./LoadAssets";
export { default as Loading } from "./Loading";
export { default as LoadNavigation } from './LoadNavigation';
export { default as SafeAreaView } from "./SafeAreaView";
export { SocialIcon, SocialIconButton, SocialIcons } from "./SocialAuth";
//LoadNavigation.tsx
import { AuthenticationNavigator } from "../navigation/auth-navigation";
import { useTypedSelector } from "../redux";
import { Onboarding } from "../screens";
import { AppRoutes } from "../types/navigation-type";
import Loading from "./Loading";
import { useIsFirstLaunch } from "./../hooks/useIsFirstLaunch";
How can I fix this warning. Thanks for any help.

Angular 8 Local Library import issue

I have created one Angular custom Library which I need to use in multiple projects in different workspace. I will plan to publish Library to NPM once I test it properly locally. below is my Library code :
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { AppbuttonComponent } from './appbutton.component';
import { CRMMaterialModule } from '../../material.module';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { BrowserModule } from '#angular/platform-browser';
#NgModule({
declarations: [AppbuttonComponent],
imports: [
BrowserAnimationsModule,
CRMMaterialModule
],
exports: [AppbuttonComponent]
})
export class AppbuttonModule { }
And Library Public API is like
export * from './lib/components/appbutton/appbutton.module';
export * from './lib/components/appbutton/appbutton.component';
Then I link my application (in different workspace) to my library. below is my appModule.ts file code
imports: [
BrowserModule,
FormsModule,
BrowserAnimationsModule,
CoreModule,
AppbuttonModule,
RouterModule.forRoot(AppRoutes, { useHash: true })....
It builds proper but when I try to run application, it gives me below error:
Error: BrowserModule has already been loaded. If you need access to
common directives such as NgIf and NgFor from a lazy loaded module,
import CommonModule instead.
Can Anyone help for this ? I'm stuck in this since 3 days.

Angular 8 testing error Unexpected value 'DecoratorFactory' imported by the module 'DynamicTestModule'

I am trying to make Jasmine & Karma framework into the current angular application running in ver 8.2. But i am coming across this weird error inside the Karma test running window:
Failed: Unexpected value 'DecoratorFactory' imported by the module 'DynamicTestModule'. Please add a #NgModule annotation.
What is the problem?
My componenent.spec.ts looks like this:
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { HomeComponent } from './home.component';
import { NO_ERRORS_SCHEMA} from '#angular/core';
import {RouterTestingModule} from '#angular/router/testing';
import {HttpClientTestingModule} from '#angular/common/http/testing';
import { MsalService } from '#azure/msal-angular';
import { Store } from '#ngrx/store';
import { Pipe } from '#angular/core';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, HttpClientTestingModule, Pipe]
,declarations: [HomeComponent]
,schemas:[NO_ERRORS_SCHEMA]
,providers: [
{provide: MsalService, useFactory: '' },
{provide: Store, useFactory: '' }
]
})
.compileComponents();
}));
it('should have header text', async(() => {
const fixture = TestBed.createComponent(HomeComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
//expect(compiled.querySelector('.header-txt').textContent).toContain('Tax');
}));
});
I found the cause :-
export class MockStore<T> {
private state: BehaviorSubject<T> = new BehaviorSubject(undefined);
setState(data: T) { this.state.next(data); }
select(selector?: any): Observable<T> {
return this.state.asObservable();
}
pipe() {}
dispatch(action: any) { }
}
========================================================================
TestBed.configureTestingModule({
{provide: Store, useFactory: 'MockStore' }
..............
The useFactory property must be some custom class name. Now i mocked the store class.

How to not bootstrap Angular web elements for lazy loading

I'm trying to build an angular application to build web elements using #angular/elements module.
The root project will only be used for testing those components in a standard stand-alone app.
I created a project called "elements" which only purpose will be to create components and distribute them as web elements which works fine so far.
I am now trying to lazy load those elements. I only want the related bundles files when I'm really using the component.
Here is my app.module.ts which defines the web elements:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule, Injector, DoBootstrap, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { createCustomElement } from '#angular/elements';
import { CfLabelComponent } from './cf-label/cf-label.component';
import { CfAdslComponent } from './cf-adsl/cf-adsl.component';
#NgModule({
declarations: [],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [],
})
export class AppModule implements DoBootstrap {
constructor(private injector: Injector) { }
ngDoBootstrap() {
customElements.define('cf-label', createCustomElement(CfLabelComponent, { injector: this.injector }));
customElements.define('cf-adsl', createCustomElement(CfAdslComponent, { injector: this.injector }));
}
}
I understand that Angular needs something to bootstrap on.
I don't have the classic app.component.ts as I don't need it at the end of the day.
The previous code is working but bootstraps the components cf-label & cf-adsl inside the main.js which is understandable but this is not what I want.
Could you please suggest a way to approach this matter?

Using quill modules with vue2-editor and webpack mix

I'm currently using vue2-editor and importing quill modules and registering them as per documentation.But getting error window.Quill is undefined.
I've tried webpack plugin mix to include window.Quill and Quill but still error remains the same.
In my vue component
import { VueEditor } from "vue2-editor";
import { Quill } from "quill";
import { ImageDrop } from "quill-image-drop-module";
import { ImageResize } from "quill-image-resize-module";
Quill.register("modules/imageDrop", ImageDrop);
Quill.register("modules/imageResize", ImageResize);
And in my webpack mix
mix.extend('foo',new class{
webpackPlugins(){
return new webpack.ProvidePlugin({
"window.Quill": "quill/dist/quill.js",
Quill: "quill/dist/quill.js"
});
}
});
Uncaught TypeError: Cannot read property 'imports' of undefined
which is from window.Quill.imports
You need to get REALY working files from https://www.jsdelivr.com/package/npm/quill-image-resize-vue:
Just install npm i --save quill-image-resize-vue
and use another file:
import { VueEditor,Quill } from 'vue2-editor'
import ImageResize from 'quill-image-resize-vue';
import { ImageDrop } from 'quill-image-drop-module';
Quill.register("modules/imageDrop", ImageDrop);
Quill.register("modules/imageResize", ImageResize);
export default {
name: 'MainForm',
components: { VueEditor},
data() {
return {
content: '<h2>I am Example</h2>',
editorSettings: {
modules: {
imageDrop: true,
imageResize: {},
}
}
}
},
//........
}
For me got fixed after changing
import { ImageResize } from "quill-image-resize-module";
to
import ImageResize from "quill-image-resize-module";