Skip to content

Commit

Permalink
feat: add NgRx example app
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonroberts committed Jun 23, 2020
1 parent c973294 commit 8f024e4
Show file tree
Hide file tree
Showing 146 changed files with 5,588 additions and 1 deletion.
119 changes: 119 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,125 @@
}
}
}
},
"example-app": {
"projectType": "application",
"schematics": {},
"root": "apps/example-app",
"sourceRoot": "apps/example-app/src",
"prefix": "reactiveangular",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/apps/example-app",
"index": "apps/example-app/src/index.html",
"main": "apps/example-app/src/main.ts",
"polyfills": "apps/example-app/src/polyfills.ts",
"tsConfig": "apps/example-app/tsconfig.app.json",
"aot": true,
"assets": [
"apps/example-app/src/favicon.ico",
"apps/example-app/src/assets"
],
"styles": ["apps/example-app/src/styles.css"],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/example-app/src/environments/environment.ts",
"with": "apps/example-app/src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "example-app:build"
},
"configurations": {
"production": {
"browserTarget": "example-app:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "example-app:build"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"apps/example-app/tsconfig.app.json",
"apps/example-app/tsconfig.spec.json"
],
"exclude": ["**/node_modules/**", "!apps/example-app/**/*"]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "apps/example-app/jest.config.js",
"tsConfig": "apps/example-app/tsconfig.spec.json",
"passWithNoTests": true,
"setupFile": "apps/example-app/src/test-setup.ts"
}
}
}
},
"example-app-e2e": {
"root": "apps/example-app-e2e",
"sourceRoot": "apps/example-app-e2e/src",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/example-app-e2e/cypress.json",
"tsConfig": "apps/example-app-e2e/tsconfig.e2e.json",
"devServerTarget": "example-app:serve"
},
"configurations": {
"production": {
"devServerTarget": "example-app:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": ["apps/example-app-e2e/tsconfig.e2e.json"],
"exclude": ["**/node_modules/**", "!apps/example-app-e2e/**/*"]
}
}
}
}
},
"cli": {
Expand Down
12 changes: 12 additions & 0 deletions apps/example-app-e2e/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"fileServerFolder": ".",
"fixturesFolder": "./src/fixtures",
"integrationFolder": "./src/integration",
"modifyObstructiveCode": false,
"pluginsFile": "./src/plugins/index",
"supportFile": "./src/support/index.ts",
"video": true,
"videosFolder": "../../dist/cypress/apps/example-app-e2e/videos",
"screenshotsFolder": "../../dist/cypress/apps/example-app-e2e/screenshots",
"chromeWebSecurity": false
}
4 changes: 4 additions & 0 deletions apps/example-app-e2e/src/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io"
}
13 changes: 13 additions & 0 deletions apps/example-app-e2e/src/integration/app.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { getGreeting } from '../support/app.po';

describe('example-app', () => {
beforeEach(() => cy.visit('/'));

it('should display welcome message', () => {
// Custom command example, see `../support/commands.ts` file
cy.login('my-email@something.com', 'myPassword');

// Function helper example, see `../support/app.po.ts` file
getGreeting().contains('Welcome to example-app!');
});
});
22 changes: 22 additions & 0 deletions apps/example-app-e2e/src/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor');

module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config

// Preprocess Typescript file using Nx helper
on('file:preprocessor', preprocessTypescript(config));
};
1 change: 1 addition & 0 deletions apps/example-app-e2e/src/support/app.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const getGreeting = () => cy.get('h1');
31 changes: 31 additions & 0 deletions apps/example-app-e2e/src/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
// eslint-disable-next-line @typescript-eslint/no-namespace
declare namespace Cypress {
interface Chainable<Subject> {
login(email: string, password: string): void;
}
}
//
// -- This is a parent command --
Cypress.Commands.add('login', (email, password) => {
console.log('Custom command example: Login', email, password);
});
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
17 changes: 17 additions & 0 deletions apps/example-app-e2e/src/support/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands';
9 changes: 9 additions & 0 deletions apps/example-app-e2e/tsconfig.e2e.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"outDir": "../../dist/out-tsc",
"allowJs": true
},
"include": ["src/**/*.ts", "src/**/*.js"]
}
7 changes: 7 additions & 0 deletions apps/example-app-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"types": ["cypress", "node"]
},
"include": ["**/*.ts", "**/*.js"]
}
5 changes: 5 additions & 0 deletions apps/example-app-e2e/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../tslint.json",
"linterOptions": { "exclude": ["!**/*"] },
"rules": {}
}
12 changes: 12 additions & 0 deletions apps/example-app/browserslist
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries

# You can see what browsers were selected by your queries by running:
# npx browserslist

> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
10 changes: 10 additions & 0 deletions apps/example-app/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
name: 'example-app',
preset: '../../jest.config.js',
coverageDirectory: '../../coverage/apps/example-app',
snapshotSerializers: [
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
'jest-preset-angular/build/AngularSnapshotSerializer.js',
'jest-preset-angular/build/HTMLCommentSerializer.js',
],
};
26 changes: 26 additions & 0 deletions apps/example-app/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AuthGuard } from '@example-app/auth/services';
import { NotFoundPageComponent } from '@example-app/core/containers';

export const routes: Routes = [
{ path: '', redirectTo: '/books', pathMatch: 'full' },
{
path: 'books',
loadChildren: () =>
import('@example-app/books/books.module').then((m) => m.BooksModule),
canActivate: [AuthGuard],
},
{
path: '**',
component: NotFoundPageComponent,
data: { title: 'Not found' },
},
];

@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})
export class AppRoutingModule {}
82 changes: 82 additions & 0 deletions apps/example-app/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreRouterConnectingModule, RouterState } from '@ngrx/router-store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';

import { AuthModule } from '@example-app/auth';

import { ROOT_REDUCERS, metaReducers } from '@example-app/reducers';

import { CoreModule } from '@example-app/core';
import { AppRoutingModule } from '@example-app/app-routing.module';
import { UserEffects, RouterEffects } from '@example-app/core/effects';
import { AppComponent } from '@example-app/core/containers';

@NgModule({
imports: [
CommonModule,
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
AuthModule,
AppRoutingModule,

/**
* StoreModule.forRoot is imported once in the root module, accepting a reducer
* function or object map of reducer functions. If passed an object of
* reducers, combineReducers will be run creating your application
* meta-reducer. This returns all providers for an @ngrx/store
* based application.
*/
StoreModule.forRoot(ROOT_REDUCERS, {
metaReducers,
runtimeChecks: {
// strictStateImmutability and strictActionImmutability are enabled by default
strictStateSerializability: true,
strictActionSerializability: true,
strictActionWithinNgZone: true,
strictActionTypeUniqueness: true,
},
}),

/**
* @ngrx/router-store keeps router state up-to-date in the store.
*/
StoreRouterConnectingModule.forRoot(),

/**
* Store devtools instrument the store retaining past versions of state
* and recalculating new states. This enables powerful time-travel
* debugging.
*
* To use the debugger, install the Redux Devtools extension for either
* Chrome or Firefox
*
* See: https://github.com/zalmoxisus/redux-devtools-extension
*/
StoreDevtoolsModule.instrument({
name: 'NgRx Book Store App',

// In a production build you would want to disable the Store Devtools
// logOnly: environment.production,
}),

/**
* EffectsModule.forRoot() is imported once in the root module and
* sets up the effects class to be initialized immediately when the
* application starts.
*
* See: https://ngrx.io/guide/effects#registering-root-effects
*/
EffectsModule.forRoot([UserEffects, RouterEffects]),
CoreModule,
],
bootstrap: [AppComponent],
})
export class AppModule {}

0 comments on commit 8f024e4

Please sign in to comment.