[DURACOM-234] Switch to standalone bootstrapping API

This commit is contained in:
Giuseppe Digilio
2024-03-26 20:52:26 +01:00
parent 0c3e9b1535
commit a8c3af097d
10 changed files with 189 additions and 202 deletions

View File

@@ -48,7 +48,7 @@ import { hasNoValue, hasValue } from './src/app/shared/empty.util';
import { UIServerConfig } from './src/config/ui-server-config.interface'; import { UIServerConfig } from './src/config/ui-server-config.interface';
import { ServerAppModule } from './src/main.server'; import bootstrap from './src/main.server';
import { buildAppConfig } from './src/config/config.server'; import { buildAppConfig } from './src/config/config.server';
import { APP_CONFIG, AppConfig } from './src/config/app-config.interface'; import { APP_CONFIG, AppConfig } from './src/config/app-config.interface';
@@ -130,7 +130,7 @@ export function app() {
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', (_, options, callback) => server.engine('html', (_, options, callback) =>
ngExpressEngine({ ngExpressEngine({
bootstrap: ServerAppModule, bootstrap,
providers: [ providers: [
{ {
provide: REQUEST, provide: REQUEST,
@@ -142,10 +142,10 @@ export function app() {
}, },
{ {
provide: APP_CONFIG, provide: APP_CONFIG,
useValue: environment useValue: environment,
} },
] ],
})(_, (options as any), callback) })(_, (options as any), callback),
); );
server.engine('ejs', ejs.renderFile); server.engine('ejs', ejs.renderFile);
@@ -162,7 +162,7 @@ export function app() {
server.get('/robots.txt', (req, res) => { server.get('/robots.txt', (req, res) => {
res.setHeader('content-type', 'text/plain'); res.setHeader('content-type', 'text/plain');
res.render('assets/robots.txt.ejs', { res.render('assets/robots.txt.ejs', {
'origin': req.protocol + '://' + req.headers.host 'origin': req.protocol + '://' + req.headers.host,
}); });
}); });
@@ -177,7 +177,7 @@ export function app() {
router.use('/sitemap**', createProxyMiddleware({ router.use('/sitemap**', createProxyMiddleware({
target: `${environment.rest.baseUrl}/sitemaps`, target: `${environment.rest.baseUrl}/sitemaps`,
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'), pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
changeOrigin: true changeOrigin: true,
})); }));
/** /**
@@ -186,7 +186,7 @@ export function app() {
router.use('/signposting**', createProxyMiddleware({ router.use('/signposting**', createProxyMiddleware({
target: `${environment.rest.baseUrl}`, target: `${environment.rest.baseUrl}`,
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'), pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
changeOrigin: true changeOrigin: true,
})); }));
/** /**
@@ -197,7 +197,7 @@ export function app() {
const RateLimit = require('express-rate-limit'); const RateLimit = require('express-rate-limit');
const limiter = new RateLimit({ const limiter = new RateLimit({
windowMs: (environment.ui as UIServerConfig).rateLimiter.windowMs, windowMs: (environment.ui as UIServerConfig).rateLimiter.windowMs,
max: (environment.ui as UIServerConfig).rateLimiter.max max: (environment.ui as UIServerConfig).rateLimiter.max,
}); });
server.use(limiter); server.use(limiter);
} }
@@ -325,7 +325,7 @@ function initCache() {
botCache = new LRU( { botCache = new LRU( {
max: environment.cache.serverSide.botCache.max, max: environment.cache.serverSide.botCache.max,
ttl: environment.cache.serverSide.botCache.timeToLive, ttl: environment.cache.serverSide.botCache.timeToLive,
allowStale: environment.cache.serverSide.botCache.allowStale allowStale: environment.cache.serverSide.botCache.allowStale,
}); });
} }
@@ -337,7 +337,7 @@ function initCache() {
anonymousCache = new LRU( { anonymousCache = new LRU( {
max: environment.cache.serverSide.anonymousCache.max, max: environment.cache.serverSide.anonymousCache.max,
ttl: environment.cache.serverSide.anonymousCache.timeToLive, ttl: environment.cache.serverSide.anonymousCache.timeToLive,
allowStale: environment.cache.serverSide.anonymousCache.allowStale allowStale: environment.cache.serverSide.anonymousCache.allowStale,
}); });
} }
} }
@@ -415,7 +415,7 @@ function checkCacheForRequest(cacheName: string, cache: LRU<string, any>, req, r
const key = getCacheKey(req); const key = getCacheKey(req);
// Check if this page is in our cache // Check if this page is in our cache
let cachedCopy = cache.get(key); const cachedCopy = cache.get(key);
if (cachedCopy) { if (cachedCopy) {
if (environment.cache.serverSide.debug) { console.log(`CACHE HIT FOR ${key} in ${cacheName} cache`); } if (environment.cache.serverSide.debug) { console.log(`CACHE HIT FOR ${key} in ${cacheName} cache`); }
@@ -529,7 +529,7 @@ function serverStarted() {
function createHttpsServer(keys) { function createHttpsServer(keys) {
const listener = createServer({ const listener = createServer({
key: keys.serviceKey, key: keys.serviceKey,
cert: keys.certificate cert: keys.certificate,
}, app).listen(environment.ui.port, environment.ui.host, () => { }, app).listen(environment.ui.port, environment.ui.host, () => {
serverStarted(); serverStarted();
}); });
@@ -597,7 +597,7 @@ function start() {
if (serviceKey && certificate) { if (serviceKey && certificate) {
createHttpsServer({ createHttpsServer({
serviceKey: serviceKey, serviceKey: serviceKey,
certificate: certificate certificate: certificate,
}); });
} else { } else {
console.warn('Disabling certificate validation and proceeding with a self-signed certificate. If this is a production server, it is recommended that you configure a valid certificate instead.'); console.warn('Disabling certificate validation and proceeding with a self-signed certificate. If this is a production server, it is recommended that you configure a valid certificate instead.');
@@ -606,7 +606,7 @@ function start() {
createCertificate({ createCertificate({
days: 1, days: 1,
selfSigned: true selfSigned: true,
}, (error, keys) => { }, (error, keys) => {
createHttpsServer(keys); createHttpsServer(keys);
}); });
@@ -627,7 +627,7 @@ function healthCheck(req, res) {
}) })
.catch((error) => { .catch((error) => {
res.status(error.response.status).send({ res.status(error.response.status).send({
error: error.message error: error.message,
}); });
}); });
} }

View File

@@ -35,6 +35,7 @@ import {
NativeWindowRef, NativeWindowRef,
NativeWindowService, NativeWindowService,
} from './core/services/window.service'; } from './core/services/window.service';
import { ThemedRootComponent } from './root/themed-root.component';
import { HostWindowResizeAction } from './shared/host-window.actions'; import { HostWindowResizeAction } from './shared/host-window.actions';
import { HostWindowService } from './shared/host-window.service'; import { HostWindowService } from './shared/host-window.service';
import { MenuService } from './shared/menu/menu.service'; import { MenuService } from './shared/menu/menu.service';
@@ -84,7 +85,6 @@ describe('App component', () => {
}, },
}), }),
], ],
declarations: [AppComponent], // declare the test component
providers: [ providers: [
{ provide: NativeWindowService, useValue: new NativeWindowRef() }, { provide: NativeWindowService, useValue: new NativeWindowRef() },
{ provide: MetadataService, useValue: new MetadataServiceMock() }, { provide: MetadataService, useValue: new MetadataServiceMock() },
@@ -109,7 +109,13 @@ describe('App component', () => {
// waitForAsync beforeEach // waitForAsync beforeEach
beforeEach(waitForAsync(() => { beforeEach(waitForAsync(() => {
return TestBed.configureTestingModule(getDefaultTestBedConf()); return TestBed.configureTestingModule(getDefaultTestBedConf()).overrideComponent(
AppComponent, {
remove: {
imports: [ ThemedRootComponent ],
},
},
);
})); }));
// synchronous beforeEach // synchronous beforeEach

View File

@@ -1,4 +1,5 @@
import { import {
AsyncPipe,
DOCUMENT, DOCUMENT,
isPlatformBrowser, isPlatformBrowser,
} from '@angular/common'; } from '@angular/common';
@@ -44,6 +45,7 @@ import {
NativeWindowService, NativeWindowService,
} from './core/services/window.service'; } from './core/services/window.service';
import { distinctNext } from './core/shared/distinct-next'; import { distinctNext } from './core/shared/distinct-next';
import { ThemedRootComponent } from './root/themed-root.component';
import { HostWindowResizeAction } from './shared/host-window.actions'; import { HostWindowResizeAction } from './shared/host-window.actions';
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component'; import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
import { CSSVariableService } from './shared/sass-helper/css-variable.service'; import { CSSVariableService } from './shared/sass-helper/css-variable.service';
@@ -55,6 +57,11 @@ import { ThemeService } from './shared/theme-support/theme.service';
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'], styleUrls: ['./app.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
ThemedRootComponent,
AsyncPipe,
],
}) })
export class AppComponent implements OnInit, AfterViewInit { export class AppComponent implements OnInit, AfterViewInit {
notificationOptions; notificationOptions;

View File

@@ -1,15 +1,11 @@
import { import {
APP_BASE_HREF, APP_BASE_HREF,
CommonModule,
DOCUMENT, DOCUMENT,
} from '@angular/common'; } from '@angular/common';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { import {
HTTP_INTERCEPTORS, ApplicationConfig,
HttpClientModule, importProvidersFrom,
} from '@angular/common/http';
import {
APP_ID,
NgModule,
} from '@angular/core'; } from '@angular/core';
import { import {
NoPreloading, NoPreloading,
@@ -31,7 +27,6 @@ import {
StoreModule, StoreModule,
USER_PROVIDED_META_REDUCERS, USER_PROVIDED_META_REDUCERS,
} from '@ngrx/store'; } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to'; import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
import { NgxMaskModule } from 'ngx-mask'; import { NgxMaskModule } from 'ngx-mask';
@@ -42,7 +37,6 @@ import {
import { StoreDevModules } from '../config/store/devtools'; import { StoreDevModules } from '../config/store/devtools';
import { environment } from '../environments/environment'; import { environment } from '../environments/environment';
import { EagerThemesModule } from '../themes/eager-themes.module'; import { EagerThemesModule } from '../themes/eager-themes.module';
import { AppComponent } from './app.component';
import { appEffects } from './app.effects'; import { appEffects } from './app.effects';
import { import {
appMetaReducers, appMetaReducers,
@@ -70,7 +64,6 @@ import { ClientCookieService } from './core/services/client-cookie.service';
import { ListableModule } from './core/shared/listable.module'; import { ListableModule } from './core/shared/listable.module';
import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor'; import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor';
import { RootModule } from './root.module'; import { RootModule } from './root.module';
import { ThemedRootComponent } from './root/themed-root.component';
import { AUTH_METHOD_FOR_DECORATOR_MAP } from './shared/log-in/methods/log-in.methods-decorator'; import { AUTH_METHOD_FOR_DECORATOR_MAP } from './shared/log-in/methods/log-in.methods-decorator';
import { METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP } from './shared/metadata-representation/metadata-representation.decorator'; import { METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP } from './shared/metadata-representation/metadata-representation.decorator';
import { import {
@@ -94,12 +87,12 @@ export function getMetaReducers(appConfig: AppConfig): MetaReducer<AppState>[] {
return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers; return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
} }
const IMPORTS = [ export const commonAppConfig: ApplicationConfig = {
CommonModule, providers: [
HttpClientModule, importProvidersFrom(
ScrollToModule.forRoot(), ScrollToModule.forRoot(),
NgbModule, NgbModule,
TranslateModule.forRoot(), // TranslateModule.forRoot(),
EffectsModule.forRoot(appEffects), EffectsModule.forRoot(appEffects),
StoreModule.forRoot(appReducers, storeModuleConfig), StoreModule.forRoot(appReducers, storeModuleConfig),
StoreRouterConnectingModule.forRoot(), StoreRouterConnectingModule.forRoot(),
@@ -107,9 +100,8 @@ const IMPORTS = [
EagerThemesModule, EagerThemesModule,
RootModule, RootModule,
ListableModule.withEntryComponents(), ListableModule.withEntryComponents(),
]; NgxMaskModule.forRoot(),
),
const PROVIDERS = [
provideRouter( provideRouter(
APP_ROUTES, APP_ROUTES,
withRouterConfig(APP_ROUTING_CONF), withRouterConfig(APP_ROUTING_CONF),
@@ -158,33 +150,16 @@ const PROVIDERS = [
}, },
// register the dynamic matcher used by form. MUST be provided by the app module // register the dynamic matcher used by form. MUST be provided by the app module
...DYNAMIC_MATCHER_PROVIDERS, ...DYNAMIC_MATCHER_PROVIDERS,
];
@NgModule({
declarations: [
AppComponent,
],
imports: [
...IMPORTS,
NgxMaskModule.forRoot(),
ThemedRootComponent,
],
providers: [
...PROVIDERS,
{ provide: APP_ID, useValue: 'dspace-angular' },
provideCore(), provideCore(),
], ],
bootstrap: [AppComponent], };
})
export class AppModule {
/* Use models object so all decorators are actually called */ /* Use models object so all decorators are actually called */
modelList = models; const modelList = models;
workflowTasks = WORKFLOW_TASK_OPTION_DECORATOR_MAP; const workflowTasks = WORKFLOW_TASK_OPTION_DECORATOR_MAP;
advancedWorfklowTasks = ADVANCED_WORKFLOW_TASK_OPTION_DECORATOR_MAP; const advancedWorfklowTasks = ADVANCED_WORKFLOW_TASK_OPTION_DECORATOR_MAP;
metadataRepresentations = METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP; const metadataRepresentations = METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP;
startsWithDecoratorMap = STARTS_WITH_DECORATOR_MAP; const startsWithDecoratorMap = STARTS_WITH_DECORATOR_MAP;
browseByDecoratorMap = BROWSE_BY_DECORATOR_MAP; const browseByDecoratorMap = BROWSE_BY_DECORATOR_MAP;
authMethodForDecoratorMap = AUTH_METHOD_FOR_DECORATOR_MAP; const authMethodForDecoratorMap = AUTH_METHOD_FOR_DECORATOR_MAP;
}

View File

@@ -3,15 +3,17 @@ import 'reflect-metadata';
import 'core-js/es/reflect'; import 'core-js/es/reflect';
import { enableProdMode } from '@angular/core'; import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { AppConfig } from './config/app-config.interface'; import { AppConfig } from './config/app-config.interface';
import { extendEnvironmentWithAppConfig } from './config/config.util'; import { extendEnvironmentWithAppConfig } from './config/config.util';
import { environment } from './environments/environment'; import { environment } from './environments/environment';
import { BrowserAppModule } from './modules/app/browser-app.module'; import { browserAppConfig } from './modules/app/browser-app.config';
const bootstrap = () => platformBrowserDynamic() /*const bootstrap = () => platformBrowserDynamic()
.bootstrapModule(BrowserAppModule, {}); .bootstrapModule(BrowserAppModule, {});*/
const bootstrap = () => bootstrapApplication(AppComponent, browserAppConfig);
/** /**
* We use this to determine have been serven SSR HTML or not. * We use this to determine have been serven SSR HTML or not.
@@ -33,9 +35,9 @@ const main = () => {
// Configuration must be fetched explicitly // Configuration must be fetched explicitly
return fetch('assets/config.json') return fetch('assets/config.json')
.then((response) => response.json()) .then((response) => response.json())
.then((appConfig: AppConfig) => { .then((config: AppConfig) => {
// extend environment with app config for browser when not prerendered // extend environment with app config for browser when not prerendered
extendEnvironmentWithAppConfig(environment, appConfig); extendEnvironmentWithAppConfig(environment, config);
return bootstrap(); return bootstrap();
}); });
} }

View File

@@ -7,14 +7,13 @@ import 'reflect-metadata';
*/ */
import '@angular/localize/init'; import '@angular/localize/init';
import { enableProdMode } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser';
import { environment } from './environments/environment'; import { AppComponent } from './app/app.component';
import { serverAppConfig } from './modules/app/server-app.config';
if (environment.production) { const bootstrap = () => bootstrapApplication(AppComponent, serverAppConfig);
enableProdMode();
}
export { ServerAppModule } from './modules/app/server-app.module';
export { renderModule } from '@angular/platform-server'; export { renderModule } from '@angular/platform-server';
export { ngExpressEngine } from '@nguniversal/express-engine'; export { ngExpressEngine } from '@nguniversal/express-engine';
export default bootstrap;

View File

@@ -1,14 +1,18 @@
import { import {
HttpClient, HttpClient,
HttpClientModule, provideHttpClient,
withInterceptorsFromDi,
} from '@angular/common/http'; } from '@angular/common/http';
import { import {
APP_ID, APP_ID,
ApplicationConfig,
importProvidersFrom,
makeStateKey, makeStateKey,
NgModule, mergeApplicationConfig,
TransferState, TransferState,
} from '@angular/core'; } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { provideClientHydration } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { EffectsModule } from '@ngrx/effects'; import { EffectsModule } from '@ngrx/effects';
import { import {
Action, Action,
@@ -26,8 +30,7 @@ import {
Angulartics2RouterlessModule, Angulartics2RouterlessModule,
} from 'angulartics2'; } from 'angulartics2';
import { AppComponent } from '../../app/app.component'; import { commonAppConfig } from '../../app/app.config';
import { AppModule } from '../../app/app.module';
import { storeModuleConfig } from '../../app/app.reducer'; import { storeModuleConfig } from '../../app/app.reducer';
import { AuthService } from '../../app/core/auth/auth.service'; import { AuthService } from '../../app/core/auth/auth.service';
import { AuthRequestService } from '../../app/core/auth/auth-request.service'; import { AuthRequestService } from '../../app/core/auth/auth-request.service';
@@ -66,13 +69,14 @@ export function getRequest(transferState: TransferState): any {
return transferState.get<any>(REQ_KEY, {}); return transferState.get<any>(REQ_KEY, {});
} }
@NgModule({ export const browserAppConfig: ApplicationConfig = mergeApplicationConfig({
bootstrap: [AppComponent], providers: [
imports: [ provideHttpClient(withInterceptorsFromDi()),
HttpClientModule, provideAnimations(),
provideClientHydration(),
importProvidersFrom(
// forRoot ensures the providers are only created once // forRoot ensures the providers are only created once
Angulartics2RouterlessModule.forRoot(), Angulartics2RouterlessModule.forRoot(),
BrowserAnimationsModule,
StoreModule.forFeature('core', coreReducers, storeModuleConfig as StoreConfig<CoreState, Action>), StoreModule.forFeature('core', coreReducers, storeModuleConfig as StoreConfig<CoreState, Action>),
EffectsModule.forFeature(coreEffects), EffectsModule.forFeature(coreEffects),
TranslateModule.forRoot({ TranslateModule.forRoot({
@@ -84,9 +88,7 @@ export function getRequest(transferState: TransferState): any {
missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MissingTranslationHelper }, missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MissingTranslationHelper },
useDefaultLang: true, useDefaultLang: true,
}), }),
AppModule, ),
],
providers: [
...BrowserInitService.providers(), ...BrowserInitService.providers(),
{ provide: APP_ID, useValue: 'dspace-angular' }, { provide: APP_ID, useValue: 'dspace-angular' },
{ {
@@ -143,6 +145,4 @@ export function getRequest(transferState: TransferState): any {
useClass: ClientMathService, useClass: ClientMathService,
}, },
], ],
}) }, commonAppConfig);
export class BrowserAppModule {
}

View File

@@ -1,12 +1,18 @@
import { XhrFactory } from '@angular/common'; import { XhrFactory } from '@angular/common';
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import {
HTTP_INTERCEPTORS,
provideHttpClient,
withInterceptorsFromDi,
} from '@angular/common/http';
import { import {
APP_ID, APP_ID,
NgModule, ApplicationConfig,
importProvidersFrom,
mergeApplicationConfig,
TransferState, TransferState,
} from '@angular/core'; } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { provideAnimations } from '@angular/platform-browser/animations';
import { ServerModule } from '@angular/platform-server'; import { provideServerRendering } from '@angular/platform-server';
import { EffectsModule } from '@ngrx/effects'; import { EffectsModule } from '@ngrx/effects';
import { import {
Action, Action,
@@ -23,8 +29,7 @@ import {
Angulartics2GoogleGlobalSiteTag, Angulartics2GoogleGlobalSiteTag,
} from 'angulartics2'; } from 'angulartics2';
import { AppComponent } from '../../app/app.component'; import { commonAppConfig } from '../../app/app.config';
import { AppModule } from '../../app/app.module';
import { storeModuleConfig } from '../../app/app.reducer'; import { storeModuleConfig } from '../../app/app.reducer';
import { AuthService } from '../../app/core/auth/auth.service'; import { AuthService } from '../../app/core/auth/auth.service';
import { AuthRequestService } from '../../app/core/auth/auth-request.service'; import { AuthRequestService } from '../../app/core/auth/auth-request.service';
@@ -57,10 +62,12 @@ export function createTranslateLoader(transferState: TransferState) {
return new TranslateServerLoader(transferState, 'dist/server/assets/i18n/', '.json'); return new TranslateServerLoader(transferState, 'dist/server/assets/i18n/', '.json');
} }
@NgModule({ export const serverAppConfig: ApplicationConfig = mergeApplicationConfig({
bootstrap: [AppComponent], providers: [
imports: [ provideHttpClient(withInterceptorsFromDi()),
NoopAnimationsModule, provideAnimations(),
provideServerRendering(),
importProvidersFrom(
StoreModule.forFeature('core', coreReducers, storeModuleConfig as StoreConfig<CoreState, Action>), StoreModule.forFeature('core', coreReducers, storeModuleConfig as StoreConfig<CoreState, Action>),
EffectsModule.forFeature(coreEffects), EffectsModule.forFeature(coreEffects),
TranslateModule.forRoot({ TranslateModule.forRoot({
@@ -70,10 +77,7 @@ export function createTranslateLoader(transferState: TransferState) {
deps: [TransferState], deps: [TransferState],
}, },
}), }),
AppModule, ),
ServerModule,
],
providers: [
...ServerInitService.providers(), ...ServerInitService.providers(),
{ provide: APP_ID, useValue: 'dspace-angular' }, { provide: APP_ID, useValue: 'dspace-angular' },
{ {
@@ -135,6 +139,4 @@ export function createTranslateLoader(transferState: TransferState) {
useClass: ServerMathService, useClass: ServerMathService,
}, },
], ],
}) }, commonAppConfig);
export class ServerAppModule {
}

View File

@@ -11,7 +11,6 @@ import { StoreModule } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to'; import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
import { AppModule } from '../../app/app.module';
import { RootModule } from '../../app/root.module'; import { RootModule } from '../../app/root.module';
import { AdminSidebarComponent } from './app/admin/admin-sidebar/admin-sidebar.component'; import { AdminSidebarComponent } from './app/admin/admin-sidebar/admin-sidebar.component';
import { EditBitstreamPageComponent } from './app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component'; import { EditBitstreamPageComponent } from './app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component';
@@ -185,7 +184,6 @@ const DECLARATIONS = [
@NgModule({ @NgModule({
imports: [ imports: [
AppModule,
RootModule, RootModule,
CommonModule, CommonModule,
DragDropModule, DragDropModule,

View File

@@ -10,7 +10,6 @@ import { StoreModule } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to'; import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
import { AppModule } from '../../app/app.module';
import { RootModule } from '../../app/root.module'; import { RootModule } from '../../app/root.module';
const DECLARATIONS = [ const DECLARATIONS = [
@@ -18,7 +17,6 @@ const DECLARATIONS = [
@NgModule({ @NgModule({
imports: [ imports: [
AppModule,
RootModule, RootModule,
CommonModule, CommonModule,
DragDropModule, DragDropModule,