Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 - Bootstrap root component with dynamic Module

how is it possible to bootstrap a component with dynamic NgModule on pageload?

Background: I have a page called by "website.url" or by a subdomain like test.website.url in one app. When a subdomain was called I want to show a landingpage based on it's own NgModule (LpModule). Default module is AppModule.

I've tried to achieve this in main.ts as follows:

import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
    
import {AppModule} from './app/app.module';
import {environment} from './environments/environment';
import {LandingpageModule} from "./app-lp/components/landingpage.module";
    
if (environment.production) {
    enableProdMode();
}
    
const hostname = window.location.hostname;
const secondLevelDomain = hostname.split('.').reverse()[1];
    
// let module = AppModule;
// if(secondLevelDomain && secondLevelDomain !== 'www') {
//     module = LandingpageModule;
// }
    
let module = loadModuleByDomain();
    
platformBrowserDynamic().bootstrapModule(module);
    
function loadModuleByDomain() {
    const hostname = window.location.hostname;
    const secondLevelDomain = hostname.split('.').reverse()[1];
    
    if(secondLevelDomain && secondLevelDomain !== 'www') {
        return LandingpageModule;
    } else {
        return AppModule;
    }
}

It works when ng serve is listening but when I restart ng serve I receive the following error:

Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options. Error: Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.

at Object.resolveEntryModuleFromMain (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@ngtools\webpack\src\entry_resolver.js:128:11)
at AotPlugin._setupOptions (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@ngtools\webpack\src\plugin.js:142:50)
at new AotPlugin (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@ngtools\webpack\src\plugin.js:26:14)
at _createAotPlugin (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\models\webpack-configs\typescript.js:55:12)
at Object.exports.getNonAotConfig (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\models\webpack-configs\typescript.js:70:19)
at NgCliWebpackConfig.buildConfig (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\models\webpack-config.js:27:37)
at Class.run (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\tasks\serve.js:37:98)
at check_port_1.checkPort.then.port (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\commands\serve.js:103:26)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:169:7)

What can I do?

like image 487
Turbo Avatar asked Jun 18 '17 14:06

Turbo


1 Answers

After a long, long search I found a solution today:

https://github.com/angular/angular-cli/issues/2887#issuecomment-281168941

I've created an additional .ts file (main-lp.ts) and added the following code:

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {LandingpageModule} from "./app-lp/components/landingpage.module";
    
export function bootstrapLandingpageModule() {
    platformBrowserDynamic().bootstrapModule(LandingpageModule);
}

In main.ts I've used the following code and it works:

import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
    
import {environment} from './environments/environment';
import {AppModule} from './app/app.module';
import {bootstrapLandingpageModule} from "./main-lp";
    
if (environment.production) {
    enableProdMode();
}
    
if(!isSubDomain()) {
    platformBrowserDynamic().bootstrapModule(AppModule);
} else {
    bootstrapLandingpageModule();
}
    
function isSubDomain() {
    const hostname = window.location.hostname;
    const secondLevelDomain = hostname.split('.').reverse()[1];
    
    return !!(secondLevelDomain && secondLevelDomain !== 'www');
}
like image 63
Turbo Avatar answered Sep 27 '22 20:09

Turbo