├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── karma.conf.js ├── package.json ├── protractor.conf.js ├── spec-bundle.js ├── src ├── app │ ├── _theme.scss │ ├── about │ │ └── about.async.ts │ ├── app.e2e.ts │ ├── app.html │ ├── app.scss │ ├── app.spec.ts │ ├── app.ts │ ├── content │ │ ├── about-angularpages.yml │ │ ├── adaptive-design.yml │ │ ├── one-command-deploy.yml │ │ └── static-pages.yml │ ├── directives │ │ └── router-active.ts │ ├── feature │ │ ├── feature-cards.html │ │ ├── feature-cards.scss │ │ ├── feature-cards.ts │ │ ├── feature.mock.ts │ │ ├── feature.model.ts │ │ └── feature.service.ts │ ├── fire-start │ │ ├── fire-start.html │ │ └── fire-start.ts │ ├── home │ │ ├── directives │ │ │ ├── x-large.spec.ts │ │ │ └── x-large.ts │ │ ├── home.css │ │ ├── home.e2e.ts │ │ ├── home.html │ │ ├── home.spec.ts │ │ ├── home.ts │ │ └── services │ │ │ ├── title.spec.ts │ │ │ └── title.ts │ ├── markdown-static │ │ ├── markdown-static.md │ │ └── markdown-static.ts │ ├── nav.scss │ ├── release │ │ ├── release-list.html │ │ ├── release-list.scss │ │ ├── release-list.ts │ │ ├── release-split.pipe.ts │ │ ├── release.mock.ts │ │ ├── release.model.ts │ │ └── release.service.ts │ ├── route.config.ts │ ├── story │ │ ├── story.html │ │ ├── story.mock.ts │ │ ├── story.model.ts │ │ ├── story.scss │ │ ├── story.service.ts │ │ └── story.ts │ └── wrapper.scss ├── assets │ ├── css │ │ └── .gitkeep │ ├── data.json │ ├── humans.txt │ ├── icon │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-icon-114x114.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-144x144.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-180x180.png │ │ ├── apple-icon-57x57.png │ │ ├── apple-icon-60x60.png │ │ ├── apple-icon-72x72.png │ │ ├── apple-icon-76x76.png │ │ ├── apple-icon-precomposed.png │ │ ├── apple-icon.png │ │ ├── browserconfig.xml │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── manifest.json │ │ ├── ms-icon-144x144.png │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ └── ms-icon-70x70.png │ ├── img │ │ ├── angular-logo.png │ │ ├── angularclass-avatar.png │ │ └── angularclass-logo.png │ ├── manifest.json │ ├── robots.txt │ └── service-worker.js ├── custom_typings.d.ts ├── index.html ├── main.ts └── polyfills.ts ├── tsconfig.json ├── tslint.json ├── typedoc.json ├── typings.json ├── webpack.config.js ├── webpack.prod.config.js └── webpack.test.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # @AngularClass 2 | # http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | insert_final_newline = false 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # @AngularPages 2 | 3 | # Firebase 4 | 5 | firebase.json 6 | 7 | # @AngularClass 8 | 9 | # Logs 10 | logs 11 | *.log 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Compiled binary addons (http://nodejs.org/api/addons.html) 28 | build/Release 29 | 30 | # Users Environment Variables 31 | .lock-wscript 32 | 33 | # OS generated files # 34 | .DS_Store 35 | ehthumbs.db 36 | Icon? 37 | Thumbs.db 38 | 39 | # Node Files # 40 | /node_modules 41 | /bower_components 42 | 43 | # Coverage # 44 | /coverage/ 45 | 46 | # Typing # 47 | /src/typings/tsd/ 48 | /typings/ 49 | /tsd_typings/ 50 | 51 | # Dist # 52 | /dist 53 | /public/__build__/ 54 | /src/*/__build__/ 55 | /__build__/** 56 | /public/dist/ 57 | /src/*/dist/ 58 | /dist/** 59 | .webpack.json 60 | 61 | # Doc # 62 | /doc/ 63 | 64 | # IDE # 65 | .idea/ 66 | *.swp 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Manav Sehgal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | ======= 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AngularPages 2 | 3 | Rapidly Create and manage Angular 2 Pages. Deploy on Firebase and GitHub Pages. 4 | 5 | # Goals 6 | 7 | - Ease into Angular 2. 8 | - Reusable components, templates, styles. 9 | - Rapid creation of full-stack pages. 10 | - Static hosting friendly. 11 | - Firebase, GitHub Pages, ... 12 | - One-click deploy. 13 | 14 | # Friends and Family 15 | 16 | AngularPages contributes and builds on following awesome projects and resources. 17 | 18 | - [Angular 2.0][5] 19 | - [Angular 2 Webpack Starter][4] by @AngularClass 20 | - [CSS Tricks][6] 21 | 22 | # Features 23 | 24 | ## Styles and Layouts 25 | - [Flexbox][1] for layouts. 26 | - Modular component level [Sass][2] or CSS styles. 27 | - Browser auto prefixing using [PostCSS][3]. 28 | 29 | ## Content Management 30 | - Use [YAML](7) structure to render static pages within single component template. 31 | 32 | ## Reusable UI Components 33 | - List component [Releases List](8) 34 | - Card component [Feature Cards](9) 35 | 36 | [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes "Mozilla Flexbox docs" 37 | [2]: http://sass-lang.com/ "Sass language Website" 38 | [3]: https://github.com/postcss/postcss "PostCSS GitHub Repo" 39 | [4]: https://github.com/AngularClass/angular2-webpack-starter "Angular2 Webpack Starter GitHub Repo" 40 | [5]: https://angular.io/ "Angular2 Official Website" 41 | [6]: https://css-tricks.com/ "CSS Tricks Blog" 42 | [7]: http://www.yaml.org/start.html "Get Started with YAML" 43 | [8]: https://angularpages.firebaseapp.com/#/releases "AngularPages Releases Page" 44 | [9]: https://angularpages.firebaseapp.com "AngularPages Home Feature Cards" 45 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // @AngularClass 2 | var path = require('path'); 3 | 4 | module.exports = function(config) { 5 | var testWebpackConfig = require('./webpack.test.config.js'); 6 | config.set({ 7 | 8 | // base path that will be used to resolve all patterns (e.g. files, exclude) 9 | basePath: '', 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | // list of files to exclude 16 | exclude: [ ], 17 | 18 | // list of files / patterns to load in the browser 19 | // we are building the test environment in ./spec-bundle.js 20 | files: [ { pattern: 'spec-bundle.js', watched: false } ], 21 | 22 | // preprocess matching files before serving them to the browser 23 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 24 | preprocessors: { 'spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] }, 25 | 26 | // Webpack Config at ./webpack.test.config.js 27 | webpack: testWebpackConfig, 28 | 29 | coverageReporter: { 30 | dir : 'coverage/', 31 | reporters: [ 32 | { type: 'text' }, 33 | { type: 'json' }, 34 | { type: 'html' } 35 | ] 36 | }, 37 | 38 | // Webpack please don't spam the console when running in karma! 39 | webpackServer: { noInfo: true }, 40 | 41 | // test results reporter to use 42 | // possible values: 'dots', 'progress' 43 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 44 | reporters: [ 'progress', 'coverage' ], 45 | 46 | // web server port 47 | port: 9876, 48 | 49 | // enable / disable colors in the output (reporters and logs) 50 | colors: true, 51 | 52 | // level of logging 53 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 54 | logLevel: config.LOG_INFO, 55 | 56 | // enable / disable watching file and executing tests whenever any file changes 57 | autoWatch: false, 58 | 59 | // start these browsers 60 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 61 | browsers: [ 62 | // 'Chrome', 63 | 'PhantomJS' 64 | ], 65 | 66 | // Continuous Integration mode 67 | // if true, Karma captures browsers, runs the tests and exits 68 | singleRun: true 69 | }); 70 | 71 | }; 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-webpack-starter", 3 | "version": "0.0.0", 4 | "description": "An Angular 2 Webpack Starter kit featuring Angular 2 (Router, Http, Forms, Services, Tests, E2E, Coverage), Karma, Protractor, Jasmine, Istanbul, TypeScript, and Webpack by AngularClass", 5 | "author": "Patrick Stapleton ", 6 | "homepage": "https://github.com/angularclass/angular2-webpack-starter", 7 | "license": "MIT", 8 | "scripts": { 9 | "clean": "npm cache clean && rimraf node_modules doc typings coverage dist", 10 | "clean:dist": "rimraf dist", 11 | "preclean:install": "npm run clean", 12 | "clean:install": "npm set progress=false && npm install", 13 | "preclean:start": "npm run clean", 14 | "clean:start": "npm start", 15 | "watch": "npm run watch:dev", 16 | "watch:dev": "webpack --watch --progress --profile --colors --display-error-details --display-cached", 17 | "watch:test": "npm run test -- --auto-watch --no-single-run", 18 | "watch:prod": "webpack --watch --config webpack.prod.config.js --progress --profile --colors --display-error-details --display-cached", 19 | "build": "npm run build:dev", 20 | "prebuild:dev": "npm run clean:dist", 21 | "build:dev": "webpack --progress --profile --colors --display-error-details --display-cached", 22 | "prebuild:prod": "npm run clean:dist", 23 | "build:prod": "webpack --config webpack.prod.config.js --progress --profile --colors --display-error-details --display-cached", 24 | "server": "npm run server:dev", 25 | "server:dev": "webpack-dev-server --progress --profile --colors --display-error-details --display-cached --content-base src/", 26 | "server:prod": "http-server dist --cors", 27 | "webdriver:update": "webdriver-manager update", 28 | "webdriver:start": "webdriver-manager start", 29 | "lint": "tsconfig-lint", 30 | "pree2e": "npm run webdriver:update -- --standalone", 31 | "e2e": "ts-node node_modules/.bin/protractor --specs src/**/**.e2e.ts,src/**/*.e2e.ts", 32 | "e2e:live": "protractor --elementExplorer", 33 | "test": "karma start", 34 | "ci": "npm run e2e && npm run test", 35 | "docs": "typedoc --options typedoc.json --exclude **/*.spec.ts ./src/", 36 | "start": "npm run server:dev", 37 | "fix:rx": "node_modules/.bin/replace '5.0.0-beta.0' '5.0.0-beta.1' node_modules -r --exclude=node_modules/rxjs", 38 | "fix:rx-patch": "npm install rxjs@5.0.0-beta.1 --save --save-exact", 39 | "fix:ng2-clean": "node_modules/.bin/rimraf node_modules/angular2/manual_typings node_modules/angular2/typings node_modules/angular2/bundles/typings", 40 | "fix:ng2": "npm run fix:ng2-clean && npm run fix:rx && npm run fix:rx-patch", 41 | "pretypings-install": "npm run fix:ng2", 42 | "typings-install": "typings install", 43 | "postinstall": "npm run typings-install" 44 | }, 45 | "dependencies": { 46 | "angular2": "2.0.0-beta.2", 47 | "es6-promise": "^3.0.2", 48 | "es6-shim": "^0.33.3", 49 | "es7-reflect-metadata": "^1.5.5", 50 | "rxjs": "5.0.0-beta.1", 51 | "zone.js": "0.5.10" 52 | }, 53 | "devDependencies": { 54 | "compression-webpack-plugin": "^0.3.0", 55 | "copy-webpack-plugin": "^1.0.0", 56 | "css-loader": "^0.23.0", 57 | "es6-promise-loader": "^1.0.1", 58 | "exports-loader": "^0.6.2", 59 | "expose-loader": "^0.7.1", 60 | "file-loader": "^0.8.4", 61 | "html-loader": "^0.4.0", 62 | "html-webpack-plugin": "1.7.0", 63 | "http-server": "^0.8.5", 64 | "imports-loader": "^0.6.4", 65 | "istanbul-instrumenter-loader": "^0.1.3", 66 | "jade-loader": "^0.8.0", 67 | "json-loader": "^0.5.3", 68 | "karma": "^0.13.15", 69 | "karma-chrome-launcher": "^0.2.1", 70 | "karma-coverage": "^0.5.3", 71 | "karma-jasmine": "^0.3.6", 72 | "karma-phantomjs-launcher": "^0.2.1", 73 | "karma-sourcemap-loader": "^0.3.6", 74 | "karma-webpack": "1.7.0", 75 | "loader-utils": "*", 76 | "lodash": "^4.0.0", 77 | "markdown-loader": "^0.1.7", 78 | "minimatch": "*", 79 | "ncp": "^2.0.0", 80 | "node-dir": "*", 81 | "node-sass": "^3.4.2", 82 | "object-assign": "*", 83 | "once": "^1.3.3", 84 | "path-is-absolute": "^1.0.0", 85 | "phantomjs": "^1.9.18", 86 | "phantomjs-polyfill": "0.0.1", 87 | "phantomjs-prebuilt": "^2.1.3", 88 | "postcss-loader": "^0.8.0", 89 | "protractor": "^3.0.0", 90 | "raw-loader": "0.5.1", 91 | "reflect-metadata": "0.1.2", 92 | "remap-istanbul": "^0.5.1", 93 | "replace": "^0.3.0", 94 | "rimraf": "^2.4.4", 95 | "sass-loader": "^3.1.2", 96 | "semver": "*", 97 | "source-map-loader": "^0.1.5", 98 | "style-loader": "^0.13.0", 99 | "ts-helper": "0.0.1", 100 | "ts-loader": "^0.8.0", 101 | "ts-node": "^0.5.5", 102 | "tsconfig-lint": "^0.5.0", 103 | "tslint": "^3.2.0", 104 | "tslint-loader": "^2.1.0", 105 | "typedoc": "^0.3.12", 106 | "typescript": "^1.7.3", 107 | "typings": "^0.6.1", 108 | "url-loader": "^0.5.6", 109 | "webpack": "^1.12.9", 110 | "webpack-dev-server": "^1.12.1", 111 | "webpack-md5-hash": "0.0.4", 112 | "yaml-loader": "^0.1.0" 113 | }, 114 | "repository": { 115 | "type": "git", 116 | "url": "https://github.com/angularclass/angular2-webpack-starter.git" 117 | }, 118 | "bugs": { 119 | "url": "https://github.com/angularclass/angular2-webpack-starter/issues" 120 | }, 121 | "engines": { 122 | "node": ">= 4.2.1 <= 5", 123 | "npm": ">= 3" 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @AngularClass 2 | 3 | exports.config = { 4 | baseUrl: 'http://localhost:3000/', 5 | 6 | // use `npm run e2e` 7 | specs: [], 8 | exclude: [], 9 | 10 | framework: 'jasmine', 11 | 12 | allScriptsTimeout: 110000, 13 | 14 | jasmineNodeOpts: { 15 | showTiming: true, 16 | showColors: true, 17 | isVerbose: false, 18 | includeStackTrace: false, 19 | defaultTimeoutInterval: 400000 20 | }, 21 | directConnect: true, 22 | 23 | capabilities: { 24 | 'browserName': 'chrome', 25 | 'chromeOptions': { 26 | 'args': ['show-fps-counter=true'] 27 | } 28 | }, 29 | 30 | onPrepare: function() { 31 | browser.ignoreSynchronization = true; 32 | }, 33 | 34 | seleniumServerJar: "node_modules/protractor/selenium/selenium-server-standalone-2.48.2.jar", 35 | 36 | /** 37 | * Angular 2 configuration 38 | * 39 | * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching 40 | * `rootEl` 41 | * 42 | */ 43 | useAllAngular2AppRoots: true 44 | }; 45 | -------------------------------------------------------------------------------- /spec-bundle.js: -------------------------------------------------------------------------------- 1 | // @AngularClass 2 | /* 3 | * When testing with webpack and ES6, we have to do some extra 4 | * things get testing to work right. Because we are gonna write test 5 | * in ES6 to, we have to compile those as well. That's handled in 6 | * karma.conf.js with the karma-webpack plugin. This is the entry 7 | * file for webpack test. Just like webpack will create a bundle.js 8 | * file for our client, when we run test, it well compile and bundle them 9 | * all here! Crazy huh. So we need to do some setup 10 | */ 11 | Error.stackTraceLimit = Infinity; 12 | require('phantomjs-polyfill'); 13 | require('es6-promise'); 14 | require('es6-shim'); 15 | require('es7-reflect-metadata/dist/browser'); 16 | 17 | require('zone.js/lib/browser/zone-microtask.js'); 18 | require('zone.js/lib/browser/long-stack-trace-zone.js'); 19 | require('zone.js/dist/jasmine-patch.js'); 20 | 21 | 22 | var testing = require('angular2/testing'); 23 | var browser = require('angular2/platform/testing/browser'); 24 | testing.setBaseTestProviders( 25 | browser.TEST_BROWSER_PLATFORM_PROVIDERS, 26 | browser.TEST_BROWSER_APPLICATION_PROVIDERS); 27 | 28 | /* 29 | Ok, this is kinda crazy. We can use the the context method on 30 | require that webpack created in order to tell webpack 31 | what files we actually want to require or import. 32 | Below, context will be an function/object with file names as keys. 33 | using that regex we are saying look in ./src/app and ./test then find 34 | any file that ends with spec.js and get its path. By passing in true 35 | we say do this recursively 36 | */ 37 | var testContext = require.context('./src', true, /\.spec\.ts/); 38 | 39 | // get all the files, for each file, call the context function 40 | // that will require the file and load it up here. Context will 41 | // loop and require those spec files here 42 | testContext.keys().forEach(testContext); 43 | -------------------------------------------------------------------------------- /src/app/_theme.scss: -------------------------------------------------------------------------------- 1 | // CSS Color Reference: http://www.w3schools.com/cssref/css_colornames.asp 2 | 3 | // app 4 | $font-stack: Helvetica, sans-serif; 5 | 6 | // navigation 7 | $nav: lightcoral; 8 | 9 | $nav-hover: darken($nav, 2%); 10 | $nav-active: darken($nav, 5%); 11 | 12 | $nav-text: white; 13 | 14 | // wrapper 15 | $wrapper: goldenrod; 16 | 17 | $main: white; 18 | $header: lighten($wrapper, 40%); 19 | 20 | $aside-left: lighten($wrapper, 40%); 21 | $aside-right: lighten($wrapper, 30%); 22 | 23 | $footer: darken($wrapper, 10%); 24 | $footer-text: white; 25 | 26 | // feature cards 27 | $feature-card-even: lightseagreen; 28 | 29 | $feature-card-odd: lighten($feature-card-even, 10%); 30 | $feature-card-text: white; 31 | 32 | // release list 33 | $release-item-even: steelblue; 34 | 35 | $release-item-odd: lighten($release-item-even, 10%); 36 | $release-item-text: white; 37 | 38 | // story 39 | 40 | $summary: darkgray; 41 | $title: steelblue; 42 | $start: darken($summary, 20%); 43 | $mid: darken($summary, 20%); 44 | $end: darken($summary, 20%); 45 | -------------------------------------------------------------------------------- /src/app/about/about.async.ts: -------------------------------------------------------------------------------- 1 | import {Component} from 'angular2/core'; 2 | 3 | /* 4 | * We're loading this component asynchronously 5 | * We are using some magic with es6-promise-loader that will wrap the module with a Promise 6 | * see https://github.com/gdi2290/es6-promise-loader for more info 7 | */ 8 | 9 | console.log('`About` component loaded asynchronously'); 10 | 11 | @Component({ 12 | selector: 'about', 13 | template: `patrick@AngularClass.com` 14 | }) 15 | export class About { 16 | constructor() { 17 | 18 | } 19 | 20 | ngOnInit() { 21 | console.log('hello `About` component'); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/app/app.e2e.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * TODO: ES5 for now until I make a webpack plugin for protractor 3 | */ 4 | describe('App', () => { 5 | 6 | beforeEach(() => { 7 | browser.get('/'); 8 | }); 9 | 10 | 11 | it('should have a title', () => { 12 | let subject = browser.getTitle(); 13 | let result = 'Angular2 Webpack Starter by @gdi2990 from @AngularClass'; 14 | expect(subject).toEqual(result); 15 | }); 16 | 17 | it('should have
', () => { 18 | let subject = element(by.css('app header')).isPresent(); 19 | let result = true; 20 | expect(subject).toEqual(result); 21 | }); 22 | 23 | it('should have
', () => { 24 | let subject = element(by.css('app main')).isPresent(); 25 | let result = true; 26 | expect(subject).toEqual(result); 27 | }); 28 | 29 | it('should have