Skip to content

Commit 286ad67

Browse files
feat(www): adds angular universal
1 parent e031591 commit 286ad67

File tree

107 files changed

+1250
-58
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+1250
-58
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

.yarn/install-state.gz

140 KB
Binary file not shown.

apps/www/project.json

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"executor": "@angular-devkit/build-angular:browser",
1010
"outputs": ["{options.outputPath}"],
1111
"options": {
12-
"outputPath": "dist/apps/www",
12+
"outputPath": "dist/apps/www/browser",
1313
"index": "apps/www/src/index.html",
1414
"main": "apps/www/src/main.ts",
1515
"polyfills": ["zone.js"],
@@ -83,6 +83,57 @@
8383
"codeCoverage": true
8484
}
8585
}
86+
},
87+
"server": {
88+
"dependsOn": ["build"],
89+
"executor": "@angular-devkit/build-angular:server",
90+
"options": {
91+
"outputPath": "dist/apps/www/server",
92+
"main": "apps/www/server.ts",
93+
"tsConfig": "apps/www/tsconfig.server.json"
94+
},
95+
"configurations": {
96+
"production": {
97+
"outputHashing": "media"
98+
},
99+
"development": {
100+
"optimization": false,
101+
"sourceMap": true,
102+
"extractLicenses": false
103+
}
104+
},
105+
"defaultConfiguration": "production"
106+
},
107+
"serve-ssr": {
108+
"executor": "@nguniversal/builders:ssr-dev-server",
109+
"configurations": {
110+
"development": {
111+
"browserTarget": "www:build:development",
112+
"serverTarget": "www:server:development"
113+
},
114+
"production": {
115+
"browserTarget": "www:build:production",
116+
"serverTarget": "www:server:production"
117+
}
118+
},
119+
"defaultConfiguration": "development"
120+
},
121+
"prerender": {
122+
"executor": "@nguniversal/builders:prerender",
123+
"options": {
124+
"routes": ["/"]
125+
},
126+
"configurations": {
127+
"development": {
128+
"browserTarget": "www:build:development",
129+
"serverTarget": "www:server:development"
130+
},
131+
"production": {
132+
"browserTarget": "www:build:production",
133+
"serverTarget": "www:server:production"
134+
}
135+
},
136+
"defaultConfiguration": "production"
86137
}
87138
},
88139
"tags": []

apps/www/server.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import 'zone.js/dist/zone-node';
2+
3+
import { APP_BASE_HREF } from '@angular/common';
4+
import { ngExpressEngine } from '@nguniversal/express-engine';
5+
import * as express from 'express';
6+
import { existsSync } from 'fs';
7+
import { join } from 'path';
8+
9+
import { AppServerModule } from './src/main.server';
10+
11+
// The Express app is exported so that it can be used by serverless Functions.
12+
export function app(): express.Express {
13+
const server = express();
14+
const distFolder = join(process.cwd(), 'dist/apps/www/browser');
15+
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
16+
? 'index.original.html'
17+
: 'index';
18+
19+
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
20+
server.engine(
21+
'html',
22+
ngExpressEngine({
23+
bootstrap: AppServerModule,
24+
})
25+
);
26+
27+
server.set('view engine', 'html');
28+
server.set('views', distFolder);
29+
30+
// Example Express Rest API endpoints
31+
// server.get('/api/**', (req, res) => { });
32+
// Serve static files from /browser
33+
server.get(
34+
'*.*',
35+
express.static(distFolder, {
36+
maxAge: '1y',
37+
})
38+
);
39+
40+
// All regular routes use the Universal engine
41+
server.get('*', (req, res) => {
42+
res.render(indexHtml, {
43+
req,
44+
providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }],
45+
});
46+
});
47+
48+
return server;
49+
}
50+
51+
function run(): void {
52+
const port = process.env['PORT'] || 4000;
53+
54+
// Start up the Node server
55+
const server = app();
56+
server.listen(port, () => {
57+
console.log(`Node Express server listening on http://localhost:${port}`);
58+
});
59+
}
60+
61+
// Webpack will replace 'require' with '__webpack_require__'
62+
// '__non_webpack_require__' is a proxy to Node 'require'
63+
// The below code is to ensure that the server is run only when not requiring the bundle.
64+
declare const __non_webpack_require__: NodeRequire;
65+
const mainModule = __non_webpack_require__.main;
66+
const moduleFilename = (mainModule && mainModule.filename) || '';
67+
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
68+
run();
69+
}
70+
71+
export * from './src/main.server';

apps/www/src/app/app.module.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import {NgModule} from '@angular/core';
2-
import {BrowserModule} from '@angular/platform-browser';
3-
import {RouterModule} from '@angular/router';
1+
import { NgModule } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { RouterModule } from '@angular/router';
44

5-
import {AppComponent} from './app.component';
6-
import {appRoutes} from './app.routes';
5+
import { AppComponent } from './app.component';
6+
import { appRoutes } from './app.routes';
77

88
@NgModule({
99
declarations: [AppComponent],
1010
imports: [
11-
BrowserModule,
12-
RouterModule.forRoot(appRoutes, {initialNavigation: 'enabledBlocking'}),
11+
BrowserModule.withServerTransition({ appId: 'serverApp' }),
12+
RouterModule.forRoot(appRoutes, { initialNavigation: 'enabledBlocking' }),
1313
],
1414
providers: [],
1515
bootstrap: [AppComponent],
1616
})
17-
export class AppModule {
18-
}
17+
export class AppModule {}

apps/www/src/app/app.server.module.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { NgModule } from '@angular/core';
2+
import { ServerModule } from '@angular/platform-server';
3+
4+
import { AppModule } from './app.module';
5+
import { AppComponent } from './app.component';
6+
7+
@NgModule({
8+
imports: [AppModule, ServerModule],
9+
bootstrap: [AppComponent],
10+
})
11+
export class AppServerModule {}

apps/www/src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
<link rel="icon" type="image/x-icon" href="favicon.ico" />
99
</head>
1010
<body>
11-
<angular-toolkit-root></angular-toolkit-root>
11+
<app-root></app-root>
1212
</body>
1313
</html>

apps/www/src/main.server.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/***************************************************************************************************
2+
* Initialize the server environment - for example, adding DOM built-in types to the global scope.
3+
*
4+
* NOTE:
5+
* This import must come before any imports (direct or transitive) that rely on DOM built-ins being
6+
* available, such as `@angular/elements`.
7+
*/
8+
import '@angular/platform-server/init';
9+
10+
export { renderModule } from '@angular/platform-server';
11+
export { AppServerModule } from './app/app.server.module';

apps/www/src/main.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
22

33
import { AppModule } from './app/app.module';
44

5-
platformBrowserDynamic()
6-
.bootstrapModule(AppModule)
7-
.catch((err) => console.error(err));
5+
function bootstrap() {
6+
platformBrowserDynamic()
7+
.bootstrapModule(AppModule)
8+
.catch((err) => console.error(err));
9+
}
10+
11+
if (document.readyState !== 'loading') {
12+
bootstrap();
13+
} else {
14+
document.addEventListener('DOMContentLoaded', bootstrap);
15+
}

apps/www/tsconfig.server.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
2+
{
3+
"extends": "./tsconfig.app.json",
4+
"compilerOptions": {
5+
"outDir": "../../out-tsc/server",
6+
"target": "es2019",
7+
"types": ["node"]
8+
},
9+
"files": ["src/main.server.ts", "server.ts"]
10+
}

nx.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"default": {
66
"runner": "nx/tasks-runners/default",
77
"options": {
8-
"cacheableOperations": ["build", "lint", "test", "e2e"]
8+
"cacheableOperations": ["build", "lint", "test", "e2e", "server"]
99
}
1010
}
1111
},

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
"@angular/forms": "~15.2.0",
1212
"@angular/platform-browser": "~15.2.0",
1313
"@angular/platform-browser-dynamic": "~15.2.0",
14+
"@angular/platform-server": "~15.2.0",
1415
"@angular/router": "~15.2.0",
16+
"@nguniversal/express-engine": "~15.1.0",
1517
"@nrwl/angular": "15.8.3",
1618
"rxjs": "~7.8.0",
1719
"tslib": "^2.3.0",
@@ -27,6 +29,7 @@
2729
"@angular/cli": "~15.2.0",
2830
"@angular/compiler-cli": "~15.2.0",
2931
"@angular/language-service": "~15.2.0",
32+
"@nguniversal/builders": "~15.1.0",
3033
"@nrwl/cypress": "15.8.3",
3134
"@nrwl/eslint-plugin-nx": "15.8.3",
3235
"@nrwl/jest": "15.8.3",

0 commit comments

Comments
 (0)