Skip to content

Commit 45eb9d2

Browse files
committed
feat: implement mvp
1 parent 925bd0d commit 45eb9d2

File tree

60 files changed

+1755
-40
lines changed

Some content is hidden

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

60 files changed

+1755
-40
lines changed

content/architecture/.category

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Architecture
3+
summary: This category summarizes best practices regarding architecture.
4+
---
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: Folder Structure
3+
---
4+
### Folder Structure
5+
6+
```ts
7+
const foo = (bar: string) => {
8+
return bar;
9+
};
10+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Smart and Dumb Components
3+
---
4+
### Smart and Dumb Components

content/performance/.category

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Performance
3+
summary: This category contains a list of practices which will help us boost the performance of our Angular applications. It covers different topics - from server-side pre-rendering and bundling of our applications, to runtime performance and optimization of the change detection performed by the framework.
4+
---

content/performance/bundling.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: Bundling
3+
source: https://github.com/mgechev/angular-performance-checklist
4+
author:
5+
name: Minko Gechev
6+
url: https://twitter.com/mgechev
7+
---
8+
### Bundling
9+
10+
Bundling is a standard practice aiming to reduce the number of requests that the browser needs to perform in order to deliver the application requested by the user. In essence, the bundler receives as an input a list of entry points and produces one or more bundles. This way, the browser can get the entire application by performing only a few requests, instead of requesting each individual resource separately.
11+
12+
As your application grows bundling everything into a single large bundle would again be counter productive. Explore Code Splitting techniques using Webpack.
13+
14+
**Additional http requests will not be a concern with HTTP/2 because of the server push feature.**
15+
16+
#### Tooling
17+
18+
Tools which allows us to bundle our applications efficiently are:
19+
20+
- [Angular CLI](https://github.com/angular/angular-cli) - A command line interface for Angular which makes it easy to create an application that already works, right out of the box. It already follows many best practices and focuses on performance.
21+
- [Webpack](https://webpack.js.org) - provides efficient bundling by performing [tree-shaking](#tree-shaking).
22+
- [Webpack Code Splitting](https://webpack.js.org/guides/code-splitting/) - Techniques to split your code.
23+
- [Webpack & http2](https://medium.com/webpack/webpack-http-2-7083ec3f3ce6#.46idrz8kb) - Need for splitting with http2.
24+
- [Rollup](https://github.com/rollup/rollup) - provides bundling by performing efficient tree-shaking, taking advantage of the static nature of the ES2015 modules.
25+
- [Google Closure Compiler](https://github.com/google/closure-compiler) - performs plenty of optimizations and provides bundling support. Originally written in Java, since recently it also has a [JavaScript version](https://www.npmjs.com/package/google-closure-compiler-js) which can be [found here](https://www.npmjs.com/package/google-closure-compiler-js).
26+
- [SystemJS Builder](https://github.com/systemjs/builder) - provides a single-file build for SystemJS of mixed-dependency module trees.
27+
- [Browserify](http://browserify.org/).
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: Remove Template Whitespace
3+
source: https://github.com/mgechev/angular-performance-checklist
4+
author:
5+
name: Minko Gechev
6+
url: https://twitter.com/mgechev
7+
---
8+
### Remove Template Whitespace
9+
10+
Although we don't see the whitespace character (a character matching the `\s` regex) it is still represented by bytes which are transfered over the network. If we reduce the whitespace from our templates to minimum we will be respectively able to drop the bundle size of the AoT code even further.
11+
12+
Thankfully, we don't have to do this manually. The `ComponentMetadata` interface provides the property `preserveWhitespaces` which by default has value `true`, because removing the whitespace always may influence the DOM layout. In case we set the property to `false` Angular will trim the unnecessary whitespace which will lead to further reduction of the bundle size.
13+
14+
- [preserveWhitespaces in the Angular docs](https://angular.io/api/core/Component#preserveWhitespaces)

content/rxjs/.category

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: RxJS
3+
summary: This category summarizes best practices regarding RxJS.
4+
---

content/rxjs/caching.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Caching
3+
---
4+
# Caching

content/rxjs/pipeable-operators.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Pipeable Operators
3+
---
4+
### Pipeable Operators

content/rxjs/subjects.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Subjects
3+
---
4+
### Subjects

content/rxjs/subscriptions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: Subscriptions
3+
---
4+
### Subscriptions

package.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,26 @@
1515
"private": true,
1616
"dependencies": {
1717
"@angular/animations": "^6.0.0",
18+
"@angular/cdk": "^6.0.2",
1819
"@angular/common": "^6.0.0",
1920
"@angular/compiler": "^6.0.0",
2021
"@angular/core": "^6.0.0",
2122
"@angular/forms": "^6.0.0",
2223
"@angular/http": "^6.0.0",
24+
"@angular/material": "^6.0.2",
2325
"@angular/platform-browser": "^6.0.0",
2426
"@angular/platform-browser-dynamic": "^6.0.0",
2527
"@angular/platform-server": "^6.0.0",
2628
"@angular/router": "^6.0.0",
29+
"@ngrx/router-store": "^6.0.0-beta.3",
30+
"@ngrx/store": "^6.0.0-beta.3",
31+
"@ngrx/store-devtools": "^6.0.0-beta.3",
32+
"@types/node": "^10.1.2",
2733
"core-js": "^2.5.4",
34+
"highlight.js": "^9.12.0",
35+
"immer": "^1.3.0",
36+
"ngrx-store-localstorage": "^5.0.0",
37+
"normalize.css": "^8.0.0",
2838
"rxjs": "^6.0.0",
2939
"zone.js": "^0.8.26"
3040
},
@@ -34,10 +44,13 @@
3444
"@angular/compiler-cli": "^6.0.0",
3545
"@angular/language-service": "^6.0.0",
3646
"@nguniversal/module-map-ngfactory-loader": "^6.0.0",
47+
"@types/highlight.js": "^9.12.2",
3748
"@types/jasmine": "~2.8.6",
3849
"@types/jasminewd2": "~2.0.3",
39-
"@types/node": "~8.9.4",
50+
"@types/markdown-it": "^0.0.4",
51+
"chalk": "^2.4.1",
4052
"codelyzer": "~4.2.1",
53+
"gray-matter": "^4.0.1",
4154
"http-server": "^0.11.1",
4255
"jasmine-core": "~2.99.1",
4356
"jasmine-spec-reporter": "~4.2.1",
@@ -46,7 +59,9 @@
4659
"karma-coverage-istanbul-reporter": "~1.4.2",
4760
"karma-jasmine": "~1.1.1",
4861
"karma-jasmine-html-reporter": "^0.2.2",
62+
"markdown-it": "^8.4.1",
4963
"protractor": "~5.3.0",
64+
"shorthash": "^0.0.2",
5065
"ts-node": "^6.0.3",
5166
"tslint": "~5.9.1",
5267
"typescript": "~2.7.2"

prerender.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import 'core-js/es6/reflect';
2+
import 'core-js/es7/reflect';
13
import 'zone.js/dist/zone-node';
2-
import 'reflect-metadata';
34

45
import { enableProdMode } from '@angular/core';
56
import { renderModuleFactory } from '@angular/platform-server';
67
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
78

89
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
910
import { join } from 'path';
11+
import execa = require('execa');
1012

1113
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require(`./dist/server/main`);
1214

@@ -15,6 +17,7 @@ enableProdMode();
1517
const ROUTES = ['/', '/checklist'];
1618
const DIST_FOLDER = join(process.cwd(), 'dist');
1719
const BROWSER_FOLDER = join(DIST_FOLDER, 'browser');
20+
const PORT = 4200;
1821

1922
const index = readFileSync(join(BROWSER_FOLDER, 'index.html'), 'utf8');
2023

src/app/app-routing.module.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { NgModule } from '@angular/core';
22
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';
3-
import { AppComponent } from './app.component';
43

54
const routes: Routes = [
65
{ path: '', loadChildren: './landing-page/landing-page.module#LandingPageModule', pathMatch: 'full' },
@@ -9,7 +8,7 @@ const routes: Routes = [
98
];
109

1110
@NgModule({
12-
imports: [RouterModule.forRoot(routes)],
11+
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
1312
exports: [RouterModule]
1413
})
1514
export class AppRoutingModule {}

src/app/app.module.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1+
import { HttpClientModule } from '@angular/common/http';
12
import { NgModule } from '@angular/core';
23
import { BrowserModule } from '@angular/platform-browser';
4+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
35
import { AppRoutingModule } from './app-routing.module';
46
import { AppComponent } from './app.component';
57

68
@NgModule({
7-
declarations: [
8-
AppComponent
9-
],
9+
declarations: [AppComponent],
1010
imports: [
1111
BrowserModule.withServerTransition({ appId: 'angular-checklist' }),
12-
AppRoutingModule
12+
BrowserAnimationsModule,
13+
AppRoutingModule,
14+
HttpClientModule,
1315
],
14-
providers: [],
1516
bootstrap: [AppComponent]
1617
})
17-
export class AppModule { }
18+
export class AppModule {}

src/app/app.server.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ import { AppModule } from './app.module';
1010
ServerModule,
1111
ModuleMapLoaderModule
1212
],
13-
bootstrap: [AppComponent],
13+
bootstrap: [AppComponent]
1414
})
1515
export class AppServerModule {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<ng-container *ngIf="item$ | async as item">
2+
<!-- <header>
3+
<a mat-icon-button routerLink="../">
4+
<mat-icon>
5+
arrow_back_ios
6+
</mat-icon>
7+
</a>
8+
<mat-checkbox color="primary" (click)="toggleItem(item)" [checked]="item.checked"></mat-checkbox>
9+
<h2>{{ item.title }}</h2>
10+
</header> -->
11+
<app-checklist-metadata [author]="item.author" [source]="item.source"></app-checklist-metadata>
12+
<main class="content" [innerHTML]="item.content"></main>
13+
</ng-container>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
@import '../../../scss/variables';
2+
@import '~@angular/material/theming';
3+
4+
header {
5+
display: flex;
6+
align-items: center;
7+
flex-wrap: wrap;
8+
border-bottom: 1px solid gainsboro;
9+
padding-bottom: 0.2rem;
10+
11+
.toolbar {
12+
display: flex;
13+
align-items: center;
14+
flex: 1 0 100%;
15+
}
16+
17+
a {
18+
margin-right: 1rem;
19+
}
20+
21+
mat-checkbox {
22+
margin-right: 0.7rem;
23+
}
24+
25+
mat-icon {
26+
padding-left: 13px;
27+
margin-right: 1rem;
28+
}
29+
30+
h2 {
31+
margin: 0;
32+
}
33+
}
34+
35+
app-checklist-metadata {
36+
justify-content: flex-end;
37+
margin: 10px 0;
38+
}
39+
40+
main {
41+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji',
42+
'Segoe UI Emoji', 'Segoe UI Symbol';
43+
font-size: 16px;
44+
line-height: 1.5;
45+
margin-top: 1.5rem;
46+
47+
::ng-deep {
48+
:not(pre) code {
49+
margin: 0;
50+
padding: 0.2em 0.4em;
51+
background-color: rgba(27, 31, 35, 0.05);
52+
border-radius: 3px;
53+
}
54+
55+
a {
56+
color: mat-color($primary);
57+
58+
&:hover {
59+
text-decoration: underline;
60+
}
61+
}
62+
}
63+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Component, OnInit } from '@angular/core';
2+
import { Store, select } from '@ngrx/store';
3+
import { ApplicationState } from '../state';
4+
import { Observable } from 'rxjs';
5+
import { ChecklistQueries } from '../state/checklist.reducer';
6+
import { ChecklistItem } from '../models/checklist';
7+
import { Toggle } from '../state/checklist.actions';
8+
9+
@Component({
10+
selector: 'app-checklist-detail-view',
11+
templateUrl: './checklist-detail-view.component.html',
12+
styleUrls: ['./checklist-detail-view.component.scss']
13+
})
14+
export class ChecklistDetailViewComponent implements OnInit {
15+
item$: Observable<any>;
16+
17+
constructor(private store: Store<ApplicationState>) {}
18+
19+
ngOnInit() {
20+
this.item$ = this.store.pipe(select(ChecklistQueries.getSelectedItem));
21+
}
22+
23+
toggleItem(item: ChecklistItem) {
24+
this.store.dispatch(new Toggle(item));
25+
}
26+
}

src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.css

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<p>
2+
checklist-favorites-view works!
3+
</p>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Component, OnInit } from '@angular/core';
2+
3+
@Component({
4+
selector: 'app-checklist-favorites-view',
5+
templateUrl: './checklist-favorites-view.component.html',
6+
styleUrls: ['./checklist-favorites-view.component.css']
7+
})
8+
export class ChecklistFavoritesViewComponent implements OnInit {
9+
10+
constructor() { }
11+
12+
ngOnInit() {
13+
}
14+
15+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<a class="info author" [href]="author.url" *ngIf="author">{{ author.name }}</a>
2+
<a class="info link" [href]="source" *ngIf="source">Source</a>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
@import '../../../scss/variables';
2+
@import '~@angular/material/theming';
3+
4+
:host {
5+
display: flex;
6+
font-size: 0.8rem;
7+
}
8+
9+
.info {
10+
display: flex;
11+
align-items: center;
12+
border: 1px solid mat-color($primary);
13+
color: mat-color($primary);
14+
padding: 4px 7px;
15+
transition: background-color 0.3s cubic-bezier(0.35, 0, 0.25, 1);
16+
17+
&:hover {
18+
background-color: mat-color($primary, lighter, 0.3);
19+
}
20+
21+
& + & {
22+
margin-left: 0.7rem;
23+
}
24+
25+
a {
26+
color: inherit;
27+
}
28+
}

0 commit comments

Comments
 (0)