diff --git a/angular.json b/angular.json index 4138e85df..e830b8d87 100644 --- a/angular.json +++ b/angular.json @@ -49,13 +49,19 @@ "scripts": [ "jquery/dist/jquery.min.js", "@ztree/ztree_v3/js/jquery.ztree.all.min.js", - "@ztree/ztree_v3/js/jquery.ztree.exhide.min.js", - "asciinema-player/dist/bundle/asciinema-player.min.js" + "@ztree/ztree_v3/js/jquery.ztree.exhide.min.js" ] }, "configurations": { "production": { - "optimization": true, + "optimization": { + "scripts": true, + "styles": { + "minify": true, + "inlineCritical": false + }, + "fonts": true + }, "outputHashing": "all", "baseHref": "/luna/", "outputPath": { @@ -68,8 +74,13 @@ "budgets": [ { "type": "initial", - "maximumWarning": "5mb", + "maximumWarning": "4mb", "maximumError": "6mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "200kb", + "maximumError": "300kb" } ], "fileReplacements": [ diff --git a/src/app/elements/replay/asciicast/asciicast.component.ts b/src/app/elements/replay/asciicast/asciicast.component.ts index 973f1e9c6..fd3ace477 100644 --- a/src/app/elements/replay/asciicast/asciicast.component.ts +++ b/src/app/elements/replay/asciicast/asciicast.component.ts @@ -5,8 +5,6 @@ import { formatTime } from '@app/utils/common'; import { HttpService } from '@app/services'; import { filter } from 'rxjs'; -declare const AsciinemaPlayer: any; - @Component({ standalone: false, selector: 'elements-replay-asciicast', @@ -29,6 +27,7 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { startTimeStamp = null; commands: Command[]; page = 0; + private AsciinemaPlayer: any; constructor( private route: ActivatedRoute, @@ -37,7 +36,10 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { this.startAt = 0; } - ngOnInit() { + async ngOnInit() { + // 动态加载 asciinema-player + await this.loadAsciinemaPlayer(); + this.commands = new Array(); const start = new Date(this.replay.date_start); const end = new Date(this.replay.date_end); @@ -62,18 +64,34 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { this.getCommands(this.page); } + private async loadAsciinemaPlayer() { + try { + // 动态导入 asciinema-player + const module = await import('asciinema-player'); + this.AsciinemaPlayer = module.default || module; + } catch (error) { + console.error('Failed to load asciinema-player:', error); + // 如果动态导入失败,尝试从全局变量获取(兼容性) + this.AsciinemaPlayer = (window as any).AsciinemaPlayer; + } + } + ngAfterViewInit() { - this.player = this.createPlayer(); - this.player.play(); - this.isPlaying = true; - this.createTimer(); + if (this.AsciinemaPlayer) { + this.player = this.createPlayer(); + this.player.play(); + this.isPlaying = true; + this.createTimer(); + } } @HostListener('window:resize', ['$event']) onResize(event: Event) { this.rows = Math.min(25, Math.floor((window.innerHeight - 120) / 16)); - this.currentTime = this.player.getCurrentTime(); - this.resetPlayer(); + if (this.player) { + this.currentTime = this.player.getCurrentTime(); + this.resetPlayer(); + } } speedDown() { @@ -81,19 +99,25 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { return; } this.speed--; - this.currentTime = this.player.getCurrentTime(); - this.resetPlayer(); - this.player.seek(this.currentTime); + if (this.player) { + this.currentTime = this.player.getCurrentTime(); + this.resetPlayer(); + this.player.seek(this.currentTime); + } } speedUp() { this.speed++; - this.currentTime = this.player.getCurrentTime(); - this.resetPlayer(); - this.player.seek(this.currentTime); + if (this.player) { + this.currentTime = this.player.getCurrentTime(); + this.resetPlayer(); + this.player.seek(this.currentTime); + } } toggle() { + if (!this.player) return; + clearInterval(this.timer); if (this.isPlaying) { this.player.pause(); @@ -126,7 +150,7 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { resetPlayer() { clearInterval(this.timer); - if (!this.player) { + if (!this.player || !this.AsciinemaPlayer) { return; } this.player.pause(); @@ -148,9 +172,13 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { } createPlayer() { + if (!this.AsciinemaPlayer) { + console.error('AsciinemaPlayer not loaded'); + return null; + } const el = document.getElementById('screen'); const opt = this.getPlayerOptions(); - return AsciinemaPlayer.create(this.replay.src, el, opt); + return this.AsciinemaPlayer.create(this.replay.src, el, opt); } getUserLang() { @@ -191,6 +219,8 @@ export class ElementReplayAsciicastComponent implements OnInit, AfterViewInit { } commandClick(item: Command) { + if (!this.player) return; + const startPlayTime = new Date(this.replay.date_start).getTime() / 1000; const instructStartTime = item.timestamp - 5 - startPlayTime; const time = instructStartTime > 0 ? instructStartTime : 0; diff --git a/src/app/plugins/ZorroModule.component.ts b/src/app/plugins/ZorroModule.component.ts index d481ffa04..0a0131103 100644 --- a/src/app/plugins/ZorroModule.component.ts +++ b/src/app/plugins/ZorroModule.component.ts @@ -30,6 +30,8 @@ import { NzPopconfirmModule } from 'ng-zorro-antd/popconfirm'; import { NzFloatButtonModule } from 'ng-zorro-antd/float-button'; import { NzInputNumberModule } from 'ng-zorro-antd/input-number'; import { NzDescriptionsModule } from 'ng-zorro-antd/descriptions'; +import { NzMessageModule } from 'ng-zorro-antd/message'; +import { NzNotificationModule } from 'ng-zorro-antd/notification'; @NgModule({ exports: [ @@ -63,7 +65,9 @@ import { NzDescriptionsModule } from 'ng-zorro-antd/descriptions'; NzPopconfirmModule, NzFloatButtonModule, NzInputNumberModule, - NzDescriptionsModule + NzDescriptionsModule, + NzMessageModule, + NzNotificationModule ] }) export class NgZorroAntdModule {} diff --git a/src/app/router.module.ts b/src/app/router.module.ts index b2cc20591..2436574da 100644 --- a/src/app/router.module.ts +++ b/src/app/router.module.ts @@ -2,31 +2,45 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { PageMainComponent } from './pages/main/main.component'; -import { PageSftpComponent } from './pages/sftp/sftp.component'; import { PagesBlankComponent } from './pages/blank/blank.component'; -import { PagesShareComponent } from './pages/share/share.component'; -import { PageDirectComponent } from './pages/direct/direct.component'; -import { PagesReplayComponent } from './pages/replay/replay.component'; -import { PagesConnectComponent } from './pages/connect/connect.component'; -import { PagesMonitorComponent } from './pages/monitor/monitor.component'; -import { PagesKubernetesComponent } from './pages/kubernetes/kubernetes.component'; +import { PagesShareComponent } from './pages/share/share.component'; const appRoutes: Routes = [ { path: '', component: PageMainComponent }, - { path: 'sftp', component: PageSftpComponent }, - { path: 'connect', component: PagesConnectComponent }, + { + path: 'sftp', + loadComponent: () => import('./pages/sftp/sftp.component').then(m => m.PageSftpComponent) + }, + { + path: 'connect', + loadComponent: () => + import('./pages/connect/connect.component').then(m => m.PagesConnectComponent) + }, { path: 'undefined', component: PagesBlankComponent }, { path: 'share/:id', component: PagesShareComponent }, - { path: 'replay/:sid', component: PagesReplayComponent }, - { path: 'admin-connect', component: PageDirectComponent }, - { path: 'monitor/:sid', component: PagesMonitorComponent }, - { path: 'k8s/:token', component: PagesKubernetesComponent }, + { + path: 'replay/:sid', + loadComponent: () => import('./pages/replay/replay.component').then(m => m.PagesReplayComponent) + }, + { + path: 'admin-connect', + loadComponent: () => import('./pages/direct/direct.component').then(m => m.PageDirectComponent) + }, + { + path: 'monitor/:sid', + loadComponent: () => + import('./pages/monitor/monitor.component').then(m => m.PagesMonitorComponent) + }, + { + path: 'k8s/:token', + loadComponent: () => + import('./pages/kubernetes/kubernetes.component').then(m => m.PagesKubernetesComponent) + } // { path: '**', component: PagesNotFoundComponent } ]; @NgModule({ imports: [RouterModule.forRoot(appRoutes, { enableTracing: false })], - exports: [RouterModule], + exports: [RouterModule] }) - export class AppRouterModule {} diff --git a/src/polyfills.ts b/src/polyfills.ts index ac3c33356..d5e289dc0 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -28,12 +28,12 @@ * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation **/ // import 'web-animations-js'; // Run `npm install --save web-animations-js`. + /*************************************************************************************************** * Zone JS is required by Angular itself. */ import 'zone.js'; // Included with Angular CLI. - /*************************************************************************************************** * APPLICATION IMPORTS */ @@ -47,5 +47,3 @@ import 'zone.js'; // Included with Angular CLI. * Need to import at least one locale-data with intl. */ // import 'intl/locale-data/jsonp/en'; - -(window as any).global = window; diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json index 38e5fe4ed..0cddcee30 100644 --- a/src/tsconfig.app.json +++ b/src/tsconfig.app.json @@ -3,12 +3,9 @@ "compilerOptions": { "outDir": "../out-tsc/app", "baseUrl": "./", - "module": "ES2015", + "module": "esnext", "target": "ES2022", "types": [] }, - "exclude": [ - "test.ts", - "**/*.spec.ts" - ] + "exclude": ["test.ts", "**/*.spec.ts"] } diff --git a/tsconfig.json b/tsconfig.json index 241a65e8f..06abb3304 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,12 +3,8 @@ "compilerOptions": { "baseUrl": "src", "paths": { - "@src/*": [ - "*" - ], - "@app/*": [ - "app/*" - ] + "@src/*": ["*"], + "@app/*": ["app/*"] }, "allowJs": true, "outDir": "./dist/out-tsc", @@ -19,14 +15,9 @@ "experimentalDecorators": true, "target": "es2020", "importHelpers": true, - "typeRoots": [ - "node_modules/@types" - ], - "lib": [ - "es2020", - "dom" - ], - "module": "es2015", + "typeRoots": ["node_modules/@types"], + "lib": ["es2020", "dom"], + "module": "esnext", "allowSyntheticDefaultImports": true } }