Amplify cannot find module

Discussão em 'Angular' iniciado por webdad3, Abril 6, 2025.

  1. webdad3

    webdad3 Guest

    I'm trying Amplify to host my Angular app.. When I build this locally it works (of course) - but for some reason it can't find my AuthInterceptor.

    2025-04-07T01:51:44.297Z [INFO]: Prerendered 0 static routes.

    Application bundle generation failed. [13.660 seconds]

    2025-04-07T01:51:44.301Z [WARNING]: ✘ [ERROR] TS2307: Cannot find module './interceptor/AuthInterceptor' or its corresponding type declarations. [plugin angular-compiler]

    src/app/app.config.ts:8:32:
    8 │ import { AuthInterceptor } from './interceptor/AuthInterceptor';
    ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ✘ [ERROR] Could not resolve "./app/interceptor/AuthInterceptor"

    src/main.ts:7:32:
    7 │ import { AuthInterceptor } from './app/interceptor/AuthInterceptor';
    ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ✘ [ERROR] TS2307: Cannot find module './app/interceptor/AuthInterceptor' or its corresponding type declarations. [plugin angular-compiler]

    src/main.ts:7:32:
    7 │ import { AuthInterceptor } from './app/interceptor/AuthInterceptor';
    ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    2025-04-07T01:51:44.420Z [ERROR]: !!! Build failed


    this is the amplify.yml:

    version: 1
    applications:
    - appRoot: "APP_UI/src"
    frontend:
    phases:
    preBuild:
    commands:
    - nvm install 20.17.0
    - nvm use 20.17.0
    - npm install -g npm@11.0.0
    - npm ci --cache .npm --prefer-offline
    build:
    commands:
    - npm run build
    artifacts:
    baseDirectory: dist/app
    files:
    - '**/*'
    cache:
    paths:
    - .npm/**/*


    tsconfig.json:

    {
    "compileOnSave": false,
    "compilerOptions": {
    "outDir": "./dist/app",
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "strictPropertyInitialization": false,
    "sourceMap": true,
    "declaration": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": "bundler",
    "importHelpers": true,
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": [
    "ES2022",
    "dom"
    ],
    "baseUrl": "./src",
    "paths": {
    "@app/*": ["app/*"]
    }
    },
    "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true,
    "skipTemplateCodegen": true
    },
    "include": ["src/**/*"]
    }


    AuthInterceptor.ts (UI\src\app\interceptor):

    import { Injectable } from '@angular/core';
    import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
    import { Observable, throwError, of } from 'rxjs';
    import { catchError, retry, delay, switchMap } from 'rxjs/operators';
    import { ModalService } from '../services/modal.service';
    import { Router } from '@angular/router';
    import { MatSnackBar } from '@angular/material/snack-bar';
    import { LoginService } from '../services/loginService';

    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {
    constructor(
    private modalService: ModalService,
    private router: Router,
    private snackBar: MatSnackBar,
    private loginService: LoginService
    ) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = localStorage.getItem('authToken');
    const cloned = token ? req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`) }) : req;

    return next.handle(cloned).pipe(
    retry({
    delay: (retryCount) => of(retryCount).pipe(delay(retryCount * 1000)), // Incremental delay
    count: 3 // Retry 3 times
    }),
    catchError((error: HttpErrorResponse) => {
    if (error.status === 401) {
    // Avoid looping if already on authentication route
    if (this.router.url !== '/register') {
    this.snackBar.open('Credentials Incorrect or Session Expired. Please log in again.', 'OK', { duration: 3000 });

    return this.loginService.refreshToken().pipe(
    switchMap((newToken: string) => {
    localStorage.setItem('authToken', newToken);
    const newRequest = req.clone({
    setHeaders: {
    Authorization: `Bearer ${newToken}`
    }
    });
    return next.handle(newRequest);
    }),
    catchError(refreshError => {
    setTimeout(() => {
    this.router.navigate(['/login']);
    }, 3000); // Delay navigation to allow snackBar display
    return throwError(refreshError);
    })
    );
    }
    } else if (error.status >= 500) {
    this.snackBar.open('Server error. Redirecting...', 'OK', { duration: 3000 });
    setTimeout(() => {
    this.router.navigate(['/error']);
    }, 3000); // Delay navigation to allow snackBar display
    } else if (!navigator.onLine) {
    this.snackBar.open('No internet connection. Redirecting...', 'OK', { duration: 3000 });
    setTimeout(() => {
    this.router.navigate(['/error']);
    }, 3000); // Delay navigation to allow snackBar display
    } else if (error.status >= 400 && error.status < 500) {
    this.modalService.openModal(); // Use modal service only for client errors
    } else {
    this.snackBar.open('An unexpected error occurred. Please try again.', 'OK', { duration: 3000 });
    setTimeout(() => {
    this.router.navigate(['/error']);
    }, 3000); // Delay navigation to allow snackBar display
    }
    return throwError(() => new Error(error.message)); // Updated to new throwError syntax
    })
    );
    }
    }


    main.ts:

    import { importProvidersFrom } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { provideHttpClient, HTTP_INTERCEPTORS, withInterceptorsFromDi } from '@angular/common/http';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { RouterModule } from '@angular/router';
    import { AppComponent } from './app/app.component';
    import { AuthInterceptor } from './app/interceptor/AuthInterceptor';
    import { MatSnackBarModule } from '@angular/material/snack-bar';
    import { routes } from './app/app.routes';
    import { LoggerService } from './app/services/logger.service';

    bootstrapApplication(AppComponent, {
    providers: [
    importProvidersFrom(MatSnackBarModule, BrowserAnimationsModule, RouterModule.forRoot(routes)),
    provideHttpClient(withInterceptorsFromDi()),
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
    LoggerService
    ]
    });


    app.config:

    import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection } from '@angular/core';
    import { provideRouter } from '@angular/router';
    import { routes } from './app.routes';
    import { provideClientHydration } from '@angular/platform-browser';
    import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
    import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
    import { CommonModule } from '@angular/common';
    import { AuthInterceptor } from './interceptor/AuthInterceptor';
    import { AuthService } from './services/authService';
    import { AuthGuard } from './guards/AuthGuard';

    export const appConfig: ApplicationConfig = {
    providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    AuthService,
    AuthGuard,
    provideClientHydration(),
    provideAnimationsAsync(),
    importProvidersFrom(HttpClientModule, CommonModule),
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
    ]
    };


    I can provide whatever else you need but I don't know what else to provide.

    Continue reading...

Compartilhe esta Página