Initial commit.

This commit is contained in:
smartapant 2016-04-20 16:32:12 +03:00
commit 6558ee2fc4
92 changed files with 3193 additions and 0 deletions

16
.editorconfig Normal file
View file

@ -0,0 +1,16 @@
# @AngularClass
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

11
.github/CONTRIBUTING.md vendored Normal file
View file

@ -0,0 +1,11 @@
## Read and contribute to the Wiki
Make sure you read the Wiki
https://github.com/AngularClass/angular2-webpack-starter/wiki
## Submitting Pull Requests
If you're changing the structure of the repository please create an issue first
## Submitting bug reports
Make sure you are on latest changes and that you ran this command `npm run clean:install` after updating your local repository. If you can, please provide more infomation about your environment such as browser, operating system, node version, and npm version

36
.github/ISSUE_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,36 @@
**Note: for support questions, please use one of these channels:** [Chat: AngularClass.slack](http://angularclass.com/member-join/) or [Twitter: @AngularClass](https://twitter.com/AngularClass)
* **I'm submitting a ...**
[ ] bug report
[ ] feature request
[ ] question about the decisions made in the repository
* **Do you want to request a *feature* or report a *bug*?**
* **What is the current behavior?**
* **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem** via
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).
* **What is the expected behavior?**
* **What is the motivation / use case for changing the behavior?**
* **Please tell us about your environment:**
- Angular version: 2.0.0-beta.X
- Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

13
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,13 @@
* **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
* **What is the current behavior?** (You can also link to an open issue here)
* **What is the new behavior (if this is a feature change)?**
* **Other information**:

61
.gitignore vendored Normal file
View file

@ -0,0 +1,61 @@
# @AngularClass
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Users Environment Variables
.lock-wscript
# OS generated files #
.DS_Store
ehthumbs.db
Icon?
Thumbs.db
# Node Files #
/node_modules
/bower_components
npm-debug.log
# Coverage #
/coverage/
# Typing #
/src/typings/tsd/
/typings/
/tsd_typings/
# Dist #
/dist
/public/__build__/
/src/*/__build__/
/__build__/**
/public/dist/
/src/*/dist/
/dist/**
.webpack.json
# Doc #
/doc/
# IDE #
.idea/
*.swp

22
LICENSE Normal file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015-2016 AngularClass LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

347
README.md Normal file
View file

@ -0,0 +1,347 @@
[![taylor swift](https://img.shields.io/badge/secured%20by-taylor%20swift-brightgreen.svg)](https://twitter.com/SwiftOnSecurity)
[![volkswagen status](https://auchenberg.github.io/volkswagen/volkswargen_ci.svg?v=1)](https://github.com/auchenberg/volkswagen) [![GitHub version](https://badge.fury.io/gh/angularclass%2Fangular2-webpack-starter.svg)](https://badge.fury.io/gh/angularclass%2Fangular2-webpack-starter) [![Dependency Status](https://david-dm.org/angularclass/angular2-webpack-starter.svg)](https://david-dm.org/angularclass/angular2-webpack-starter)
[![Issue Stats](http://issuestats.com/github/angularclass/angular2-webpack-starter/badge/pr?style=flat)](http://issuestats.com/github/angularclass/angular2-webpack-starter)
[![Issue Stats](http://issuestats.com/github/angularclass/angular2-webpack-starter/badge/issue?style=flat)](http://issuestats.com/github/angularclass/angular2-webpack-starter) [![Stack Share](http://img.shields.io/badge/tech-stack-0690fa.svg?style=flat)](http://stackshare.io/angularclass/angular-2-webpack-starter)
<p align="center">
<a href="https://angularclass.com" target="_blank">
<img src="https://cloud.githubusercontent.com/assets/1016365/9863762/a84fed4a-5af7-11e5-9dde-d5da01e797e7.png" alt="Webpack and Angular 2" width="500" height="320"/>
</a>
</p>
# Angular2 Webpack Starter [![Join Slack](https://img.shields.io/badge/slack-join-brightgreen.svg)](https://angularclass.com/slack-join) [![Join the chat at https://gitter.im/angularclass/angular2-webpack-starter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/angularclass/angular2-webpack-starter?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
> An Angular 2 starter kit featuring [Angular 2](https://angular.io) ([Router](https://angular.io/docs/js/latest/api/router/), [Forms](https://angular.io/docs/js/latest/api/forms/),
[Http](https://angular.io/docs/js/latest/api/http/),
[Services](https://gist.github.com/gdi2290/634101fec1671ee12b3e#_follow_@AngularClass_on_twitter),
[Tests](https://angular.io/docs/js/latest/api/test/), [E2E](https://angular.github.io/protractor/#/faq#what-s-the-difference-between-karma-and-protractor-when-do-i-use-which-)), [Material](https://github.com/angular/material2), [Karma](https://karma-runner.github.io/), [Protractor](https://angular.github.io/protractor/), [Jasmine](https://github.com/jasmine/jasmine), [Istanbul](https://github.com/gotwarlost/istanbul), [TypeScript](http://www.typescriptlang.org/), [Typings](https://github.com/typings/typings), [TsLint](http://palantir.github.io/tslint/), [Codelyzer](https://github.com/mgechev/codelyzer), [Hot Module Replacement](https://webpack.github.io/docs/hot-module-replacement-with-webpack.html), and [Webpack](http://webpack.github.io/) by [AngularClass](https://angularclass.com).
> If you're looking for Angular 1.x please use [NG6-starter](https://github.com/angularclass/NG6-starter)
> If you're looking to learn about Webpack and ES6 Build Tools check out [ES6-build-tools](https://github.com/AngularClass/ES6-build-tools)
> If you're looking to learn TypeScript see [TypeStrong/learn-typescript](https://github.com/TypeStrong/learn-typescript)
> If you're looking for Webpack 2 version then see the experimental version [angular2-webpack2-starter](https://github.com/gdi2290/angular2-webpack2-starter) that will be merged
> If you're looking for something easier to get started with then see the offical angular2-seed that I also maintain [angular/angular2-seed](https://github.com/angular/angular2-seed)
This seed repo serves as an Angular 2 starter for anyone looking to get up and running with Angular 2 and TypeScript fast. Using a [Webpack](http://webpack.github.io/) for building our files and assisting with boilerplate. We're also using Protractor for our end-to-end story and Karma for our unit tests.
* Best practices in file and application organization for Angular 2.
* Ready to go build system using Webpack for working with TypeScript.
* Angular 2 examples that are ready to go when experimenting with Angular 2.
* A great Angular 2 seed repo for anyone who wants to start their project.
* Testing Angular 2 code with Jasmine and Karma.
* Coverage with Istanbul and Karma
* End-to-end Angular 2 code using Protractor.
* Type manager with Typings
* Hot Module Replacement with Webpack
* Material Design with [angular/material2](https://github.com/angular/material2)
### Quick start
**Make sure you have Node version >= 4.0 and NPM >= 3**
> Clone/Download the repo then edit `app.ts` inside [`/src/app/app.ts`](/src/app/app.ts)
```bash
# clone our repo
# --depth 1 removes all but one .git commit history
git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git
# change directory to our repo
cd angular2-webpack-starter
# add required global libraries
npm install typings webpack-dev-server rimraf webpack -g
# install the repo with npm
npm install
# start the server
npm start
# use Hot Module Replacement
npm run server:dev:hmr
# if you're in China use cnpm
# https://github.com/cnpm/cnpm
```
go to [http://0.0.0.0:3000](http://0.0.0.0:3000) or [http://localhost:3000](http://localhost:3000) in your browser
# Table of Contents
* [File Structure](#file-structure)
* [Getting Started](#getting-started)
* [Dependencies](#dependencies)
* [Installing](#installing)
* [Running the app](#running-the-app)
* [Configuration](#configuration)
* [Contributing](#contributing)
* [TypeScript](#typescript)
* [Typings](#typings)
* [Frequently asked questions](#frequently-asked-questions)
* [Support, Questions, or Feedback](#support-questions-or-feedback)
* [License](#license)
## File Structure
We use the component approach in our starter. This is the new standard for developing Angular apps and a great way to ensure maintainable code by encapsulation of our behavior logic. A component is basically a self contained app usually in a single file or a folder with each concern as a file: style, template, specs, e2e, and component class. Here's how it looks:
```
angular2-webpack-starter/
├──config/ * our configuration
| ├──helpers.js * helper functions for our configuration files
| ├──spec-bundle.js * ignore this magic that sets up our angular 2 testing environment
| ├──karma.conf.js * karma config for our unit tests
| ├──protractor.conf.js * protractor config for our end-to-end tests
│ ├──webpack.dev.js * our development webpack config
│ ├──webpack.prod.js * our production webpack config
│ └──webpack.test.js * our testing webpack config
├──src/ * our source files that will be compiled to javascript
| ├──main.browser.ts * our entry file for our browser environment
│ │
| ├──index.html * Index.html: where we generate our index page
│ │
| ├──polyfills.ts * our polyfills file
│ │
| ├──vendor.ts * our vendor file
│ │
│ ├──app/ * WebApp: folder
│ │ ├──app.spec.ts * a simple test of components in app.ts
│ │ ├──app.e2e.ts * a simple end-to-end test for /
│ │ └──app.ts * App.ts: a simple version of our App component components
│ │
│ └──assets/ * static assets are served here
│ ├──icon/ * our list of icons from www.favicon-generator.org
│ ├──service-worker.js * ignore this. Web App service worker that's not complete yet
│ ├──robots.txt * for search engines to crawl your website
│ └──human.txt * for humans to know who the developers are
├──tslint.json * typescript lint config
├──typedoc.json * typescript documentation generator
├──tsconfig.json * config that webpack uses for typescript
├──typings.json * our typings manager
└──package.json * what npm uses to manage it's dependencies
```
# Getting Started
## Dependencies
What you need to run this app:
* `node` and `npm` (`brew install node`)
* Ensure you're running the latest versions Node `v4.x.x`+ (or `v5.x.x`) and NPM `3.x.x`+
Once you have those, you should install these globals with `npm install --global`:
* `webpack` (`npm install --global webpack`)
* `webpack-dev-server` (`npm install --global webpack-dev-server`)
* `karma` (`npm install --global karma-cli`)
* `protractor` (`npm install --global protractor`)
* `typings` (`npm install --global typings`)
* `typescript` (`npm install --global typescript`)
## Installing
* `fork` this repo
* `clone` your fork
* `npm install` to install all dependencies
* `typings install` to install necessary typings
* `npm run server` to start the dev server in another tab
## Running the app
After you have installed all dependencies you can now run the app. Run `npm run server` to start a local server using `webpack-dev-server` which will watch, build (in-memory), and reload for you. The port will be displayed to you as `http://0.0.0.0:3000` (or if you prefer IPv6, if you're using `express` server, then it's `http://[::1]:3000/`).
### server
```bash
# development
npm run server
# production
npm run build:prod
npm run server:prod
```
## Other commands
### build files
```bash
# development
npm run build:dev
# production
npm run build:prod
```
### hot module replacement
```bash
npm run server:dev:hmr
```
### watch and build files
```bash
npm run watch
```
### run tests
```bash
npm run test
```
### watch and run our tests
```bash
npm run watch:test
```
### run end-to-end tests
```bash
# make sure you have your server running in another terminal
npm run e2e
```
### run webdriver (for end-to-end)
```bash
npm run webdriver:update
npm run webdriver:start
```
### run Protractor's elementExplorer (for end-to-end)
```bash
npm run webdriver:start
# in another terminal
npm run e2e:live
```
# Configuration
Configuration files live in `config/` we are currently using webpack, karma, and protractor for different stages of your application
# Contributing
You can include more examples as components but they must introduce a new concept such as `Home` component (separate folders), and Todo (services). I'll accept pretty much everything so feel free to open a Pull-Request
# TypeScript
> To take full advantage of TypeScript with autocomplete you would have to install it globally and use an editor with the correct TypeScript plugins.
## Use latest TypeScript compiler
TypeScript 1.7.x includes everything you need. Make sure to upgrade, even if you installed TypeScript previously.
```
npm install --global typescript
```
## Use a TypeScript-aware editor
We have good experience using these editors:
* [Visual Studio Code](https://code.visualstudio.com/)
* [Webstorm 10](https://www.jetbrains.com/webstorm/download/)
* [Atom](https://atom.io/) with [TypeScript plugin](https://atom.io/packages/atom-typescript)
* [Sublime Text](http://www.sublimetext.com/3) with [Typescript-Sublime-Plugin](https://github.com/Microsoft/Typescript-Sublime-plugin#installation)
# Typings
> When you include a module that doesn't include Type Definitions inside of the module you need to include external Type Definitions with Typings
## Use latest Typings module
```
npm install --global typings
```
## Custom Type Definitions
When including 3rd party modules you also need to include the type definition for the module
if they don't provide one within the module. You can try to install it with typings
```
typings install node --save
```
If you can't find the type definition in the registry we can make an ambient definition in
this file for now. For example
```typescript
declare module "my-module" {
export function doesSomething(value: string): string;
}
```
If you're prototyping and you will fix the types later you can also declare it as type any
```typescript
declare var assert: any;
```
If you're importing a module that uses Node.js modules which are CommonJS you need to import as
```typescript
import * as _ from 'lodash';
```
You can include your type definitions in this file until you create one for the typings registry
see [typings/registry](https://github.com/typings/registry)
# Frequently asked questions
* What's the current browser support for Angular 2 Beta?
* Please view the updated list of [browser support for Angular 2](https://github.com/angularclass/awesome-angular2#current-browser-support-for-angular-2)
* Why is my service, aka provider, is not injecting parameter correctly?
* Please use `@Injectable()` for your service for typescript to correctly attach the metadata (this is a TypeScript problem)
* How do I run protractor with node 0.12.x?
* please check out this repo to use the old version of protractor [#146](https://github.com/AngularClass/angular2-webpack-starter/pull/146/files)
* Where do I write my tests?
* You can write your tests next to your component files. See [`/src/app/home/home.spec.ts`](/src/app/home/home.spec.ts)
* How do I start the app when I get `EACCES` and `EADDRINUSE` errors?
* The `EADDRINUSE` error means the port `3000` is currently being used and `EACCES` is lack of permission for webpack to build files to `./dist/`
* How to use `sass` for css?
* `loaders: ['raw-loader','sass-loader']` and `@Component({ styles: [ require('./filename.scss') ] })` see issue [#136](https://github.com/AngularClass/angular2-webpack-starter/issues/136)
* How do I test a Service?
* See issue [#130](https://github.com/AngularClass/angular2-webpack-starter/issues/130#issuecomment-158872648)
* How do I add `vscode-chrome-debug` support?
* The VS Code chrome debug extension support can be done via `launch.json` see issue [#144](https://github.com/AngularClass/angular2-webpack-starter/issues/144#issuecomment-164063790)
* How do I make the repo work in a virtual machine?
* You need to use `0.0.0.0` so revert these changes [#205](https://github.com/AngularClass/angular2-webpack-starter/pull/205/files)
* What are the naming conventions for Angular 2?
* please see issue [#185](https://github.com/AngularClass/angular2-webpack-starter/issues/185) and PR [196](https://github.com/AngularClass/angular2-webpack-starter/pull/196)
* How do I include bootstrap or jQuery?
* please see issue [#215](https://github.com/AngularClass/angular2-webpack-starter/issues/215) and [#214](https://github.com/AngularClass/angular2-webpack-starter/issues/214#event-511768416)
* I'm getting an error about not finding my module that I installed?
* please see [How to include or create custom type definitions](https://github.com/AngularClass/angular2-webpack-starter/wiki/How-to-include-or-create-custom-type-definitions) and [custom-typings.d.ts](https://github.com/AngularClass/angular2-webpack-starter/blob/master/src/custom-typings.d.ts)
* How do I async load a component?
* see wiki [How-do-I-async-load-a-component-with-AsyncRoute](https://github.com/AngularClass/angular2-webpack-starter/wiki/How-do-I-async-load-a-component-with-AsyncRoute)
* Error: Cannot find module 'tapable'
* Remove `node_modules/` and run `npm cache clean` then `npm install`
* What about Webpack 2?
* If you're looking for Webpack 2 version then see the [experimental version](https://github.com/gdi2290/angular2-webpack2-starter) that will be merged soon.
* How do I turn on Hot Module Replacement
* Run `npm run server:dev:hmr`
* `RangeError: Maximum call stack size exceeded`
* This is a problem with minifying Angular 2 and it's recent JIT templates. If you set `mangle` to `false` then you should be good.
* Why is the size of my app larger in development?
* We are using inline source-maps and hot module replacement which will increase the bundle size.
* If you're in China
* check out https://github.com/cnpm/cnpm
# Support, Questions, or Feedback
> Contact us anytime for anything about this repo or Angular 2
* [Chat: AngularClass.slack](http://angularclass.com/member-join/)
* [Twitter: @AngularClass](https://twitter.com/AngularClass)
* [Gitter: AngularClass/angular2-webpack-starter](https://gitter.im/angularclass/angular2-webpack-starter)
# Quick Start Guides
## Nitrous
You can quickly create a free development environment to get started using this
starter kit in the cloud on [Nitrous](https://www.nitrous.io/):
<a href="https://www.nitrous.io/quickstart?repo=https://github.com/nitrous-io/angular2-webpack-starter">
<img src="https://nitrous-image-icons.s3.amazonaws.com/quickstart.png" alt="Nitrous Quickstart" width=142 height=34>
</a>
Simply run `HOST=0.0.0.0 npm start` from the terminal inside of
`~/code/angular2-webpack-starter` and access your site via the "Preview > 3000"
link in the IDE.
___
enjoy — **AngularClass**
<br><br>
[![AngularClass](https://cloud.githubusercontent.com/assets/1016365/9863770/cb0620fc-5af7-11e5-89df-d4b0b2cdfc43.png "Angular Class")](https://angularclass.com)
##[AngularClass](https://angularclass.com)
> Learn AngularJS, Angular 2, and Modern Web Development from the best.
> Looking for corporate Angular training, want to host us, or Angular consulting? patrick@angularclass.com
# License
[MIT](/LICENSE)

69
config/helpers.js Normal file
View file

@ -0,0 +1,69 @@
/**
* @author: @AngularClass
*/
var path = require('path');
// Helper functions
var _root = path.resolve(__dirname, '..');
console.log('root directory:', root());
function hasProcessFlag(flag) {
return process.argv.join('').indexOf(flag) > -1;
}
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
function rootNode(args) {
args = Array.prototype.slice.call(arguments, 0);
return root.apply(path, ['node_modules'].concat(args));
}
function prependExt(extensions, args) {
args = args || [];
if (!Array.isArray(args)) { args = [args] }
return extensions.reduce(function(memo, val) {
return memo.concat(val, args.map(function(prefix) {
return prefix + val;
}));
}, ['']);
}
function packageSort(packages) {
// packages = ['polyfills', 'vendor', 'main']
var len = packages.length - 1;
var first = packages[0];
var last = packages[len];
return function sort(a, b) {
// polyfills always first
if (a.names[0] === first) {
return -1;
}
// main always last
if (a.names[0] === last) {
return 1;
}
// vendor before app
if (a.names[0] !== first && b.names[0] === last) {
return -1;
} else {
return 1;
}
}
}
function reverse(arr) {
return arr.reverse();
}
exports.reverse = reverse;
exports.hasProcessFlag = hasProcessFlag;
exports.root = root;
exports.rootNode = rootNode;
exports.prependExt = prependExt;
exports.prepend = prependExt;
exports.packageSort = packageSort;

90
config/karma.conf.js Normal file
View file

@ -0,0 +1,90 @@
/**
* @author: @AngularClass
*/
module.exports = function(config) {
var testWebpackConfig = require('./webpack.test.js');
config.set({
// base path that will be used to resolve all patterns (e.g. files, exclude)
basePath: '',
/*
* Frameworks to use
*
* available frameworks: https://npmjs.org/browse/keyword/karma-adapter
*/
frameworks: ['jasmine'],
// list of files to exclude
exclude: [ ],
/*
* list of files / patterns to load in the browser
*
* we are building the test environment in ./spec-bundle.js
*/
files: [ { pattern: './config/spec-bundle.js', watched: false } ],
/*
* preprocess matching files before serving them to the browser
* available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
*/
preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },
// Webpack Config at ./webpack.test.js
webpack: testWebpackConfig,
coverageReporter: {
dir : 'coverage/',
reporters: [
{ type: 'text-summary' },
{ type: 'json' },
{ type: 'html' }
]
},
// Webpack please don't spam the console when running in karma!
webpackServer: { noInfo: true },
/*
* test results reporter to use
*
* possible values: 'dots', 'progress'
* available reporters: https://npmjs.org/browse/keyword/karma-reporter
*/
reporters: [ 'mocha', 'coverage' ],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
/*
* level of logging
* possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
*/
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
/*
* start these browsers
* available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
*/
browsers: [
// 'Chrome',
'PhantomJS'
],
/*
* Continuous Integration mode
* if true, Karma captures browsers, runs the tests and exits
*/
singleRun: true
});
};

51
config/protractor.conf.js Normal file
View file

@ -0,0 +1,51 @@
/**
* @author: @AngularClass
*/
require('ts-node/register');
var helpers = require('./helpers');
exports.config = {
baseUrl: 'http://localhost:3000/',
// use `npm run e2e`
specs: [
helpers.root('src/**/**.e2e.ts'),
helpers.root('src/**/*.e2e.ts')
],
exclude: [],
framework: 'jasmine2',
allScriptsTimeout: 110000,
jasmineNodeOpts: {
showTiming: true,
showColors: true,
isVerbose: false,
includeStackTrace: false,
defaultTimeoutInterval: 400000
},
directConnect: true,
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': ['show-fps-counter=true']
}
},
onPrepare: function() {
browser.ignoreSynchronization = true;
},
seleniumServerJar: 'node_modules/protractor/selenium/selenium-server-standalone-2.52.0.jar',
/**
* Angular 2 configuration
*
* useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching
* `rootEl`
*/
useAllAngular2AppRoots: true
};

59
config/spec-bundle.js Normal file
View file

@ -0,0 +1,59 @@
/**
* @author: @AngularClass
*/
/*
* When testing with webpack and ES6, we have to do some extra
* things get testing to work right. Because we are gonna write test
* in ES6 to, we have to compile those as well. That's handled in
* karma.conf.js with the karma-webpack plugin. This is the entry
* file for webpack test. Just like webpack will create a bundle.js
* file for our client, when we run test, it well compile and bundle them
* all here! Crazy huh. So we need to do some setup
*/
Error.stackTraceLimit = Infinity;
require('core-js');
// Typescript emit helpers polyfill
require('ts-helpers');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/jasmine-patch');
// RxJS
require('rxjs/Rx');
var testing = require('angular2/testing');
var browser = require('angular2/platform/testing/browser');
testing.setBaseTestProviders(
browser.TEST_BROWSER_PLATFORM_PROVIDERS,
browser.TEST_BROWSER_APPLICATION_PROVIDERS
);
Object.assign(global, testing);
/*
* Ok, this is kinda crazy. We can use the the context method on
* require that webpack created in order to tell webpack
* what files we actually want to require or import.
* Below, context will be an function/object with file names as keys.
* using that regex we are saying look in ./src/app and ./test then find
* any file that ends with spec.js and get its path. By passing in true
* we say do this recursively
*/
var testContext = require.context('../src', true, /\.spec\.ts/);
/*
* get all the files, for each file, call the context function
* that will require the file and load it up here. Context will
* loop and require those spec files here
*/
function requireAll(requireContext) {
return requireContext.keys().map(requireContext);
}
// requires and returns all modules that match
var modules = requireAll(testContext);

255
config/webpack.common.js Normal file
View file

@ -0,0 +1,255 @@
/**
* @author: @AngularClass
*/
const webpack = require('webpack');
const helpers = require('./helpers');
/*
* Webpack Plugins
*/
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
/*
* Webpack Constants
*/
const METADATA = {
title: 'Angular2 Webpack Starter by @gdi2290 from @AngularClass',
baseUrl: '/'
};
/*
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = {
/*
* Static metadata for index.html
*
* See: (custom attribute)
*/
metadata: METADATA,
/*
* Cache generated modules and chunks to improve performance for multiple incremental builds.
* This is enabled by default in watch mode.
* You can pass false to disable it.
*
* See: http://webpack.github.io/docs/configuration.html#cache
* cache: false,
*
* The entry point for the bundle
* Our Angular.js app
*
* See: http://webpack.github.io/docs/configuration.html#entry
*/
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'main': './src/main.browser.ts'
},
/*
* Options affecting the resolving of modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve
*/
resolve: {
/*
* An array of extensions that should be used to resolve modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
*/
extensions: ['', '.ts', '.js'],
// Make sure root is src
root: helpers.root('src'),
// remove other default values
modulesDirectories: ['node_modules']
},
/*
* Options affecting the normal modules.
*
* See: http://webpack.github.io/docs/configuration.html#module
*/
module: {
/*
* An array of applied pre and post loaders.
*
* See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders
*/
preLoaders: [
/*
* Tslint loader support for *.ts files
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
// { test: /\.ts$/, loader: 'tslint-loader', exclude: [ helpers.root('node_modules') ] },
/*
* Source map loader support for *.js files
* Extracts SourceMaps for source files that as added as sourceMappingURL comment.
*
* See: https://github.com/webpack/source-map-loader
*/
{
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
// these packages have problems with their sourcemaps
helpers.root('node_modules/rxjs'),
helpers.root('node_modules/@angular2-material')
]
}
],
/*
* An array of automatically applied loaders.
*
* IMPORTANT: The loaders here are resolved relative to the resource which they are applied to.
* This means they are not resolved relative to the configuration file.
*
* See: http://webpack.github.io/docs/configuration.html#module-loaders
*/
loaders: [
/*
* Typescript loader support for .ts and Angular 2 async routes via .async.ts
*
* See: https://github.com/s-panferov/awesome-typescript-loader
*/
{
test: /\.ts$/,
loader: 'awesome-typescript-loader',
exclude: [/\.(spec|e2e)\.ts$/]
},
/*
* Json loader support for *.json files.
*
* See: https://github.com/webpack/json-loader
*/
{
test: /\.json$/,
loader: 'json-loader'
},
/*
* Raw loader support for *.css files
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{
test: /\.css$/,
loader: 'raw-loader'
},
/* Raw loader support for *.html
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{
test: /\.html$/,
loader: 'raw-loader',
exclude: [helpers.root('src/index.html')]
}
]
},
/*
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
/*
* Plugin: ForkCheckerPlugin
* Description: Do type checking in a separate process, so webpack don't need to wait.
*
* See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
*/
new ForkCheckerPlugin(),
/*
* Plugin: OccurenceOrderPlugin
* Description: Varies the distribution of the ids to get the smallest id length
* for often used ids.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin
* See: https://github.com/webpack/docs/wiki/optimization#minimize
*/
new webpack.optimize.OccurenceOrderPlugin(true),
/*
* Plugin: CommonsChunkPlugin
* Description: Shares common code between the pages.
* It identifies common modules and put them into a commons chunk.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
*/
new webpack.optimize.CommonsChunkPlugin({
name: helpers.reverse(['polyfills', 'vendor'])
}),
/*
* Plugin: CopyWebpackPlugin
* Description: Copy files and directories in webpack.
*
* Copies project static assets.
*
* See: https://www.npmjs.com/package/copy-webpack-plugin
*/
new CopyWebpackPlugin([{
from: 'src/assets',
to: 'assets'
}]),
/*
* Plugin: HtmlWebpackPlugin
* Description: Simplifies creation of HTML files to serve your webpack bundles.
* This is especially useful for webpack bundles that include a hash in the filename
* which changes every compilation.
*
* See: https://github.com/ampedandwired/html-webpack-plugin
*/
new HtmlWebpackPlugin({
template: 'src/index.html',
chunksSortMode: helpers.packageSort(['polyfills', 'vendor', 'main'])
})
],
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: 'window',
crypto: 'empty',
module: false,
clearImmediate: false,
setImmediate: false
}
};

162
config/webpack.dev.js Normal file
View file

@ -0,0 +1,162 @@
/**
* @author: @AngularClass
*/
const helpers = require('./helpers');
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
/**
* Webpack Plugins
*/
const DefinePlugin = require('webpack/lib/DefinePlugin');
/**
* Webpack Constants
*/
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const HMR = helpers.hasProcessFlag('hot');
const METADATA = webpackMerge(commonConfig.metadata, {
host: 'localhost',
port: 3000,
ENV: ENV,
HMR: HMR
});
/**
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = webpackMerge(commonConfig, {
/**
* Merged metadata from webpack.common.js for index.html
*
* See: (custom attribute)
*/
metadata: METADATA,
/**
* Switch loaders to debug mode.
*
* See: http://webpack.github.io/docs/configuration.html#debug
*/
debug: true,
/**
* Developer tool to enhance debugging
*
* See: http://webpack.github.io/docs/configuration.html#devtool
* See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps
*/
devtool: 'cheap-module-eval-source-map',
/**
* Options affecting the output of the compilation.
*
* See: http://webpack.github.io/docs/configuration.html#output
*/
output: {
/**
* The output directory as absolute path (required).
*
* See: http://webpack.github.io/docs/configuration.html#output-path
*/
path: helpers.root('dist'),
/**
* Specifies the name of each output file on disk.
* IMPORTANT: You must not specify an absolute path here!
*
* See: http://webpack.github.io/docs/configuration.html#output-filename
*/
filename: '[name].bundle.js',
/**
* The filename of the SourceMaps for the JavaScript files.
* They are inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename
*/
sourceMapFilename: '[name].map',
/** The filename of non-entry chunks as relative path
* inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-chunkfilename
*/
chunkFilename: '[id].chunk.js'
},
plugins: [
/**
* Plugin: DefinePlugin
* Description: Define free variables.
* Useful for having development builds with debug logging or adding global constants.
*
* Environment helpers
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
*/
// NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
new DefinePlugin({
'ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'process.env': {
'ENV': JSON.stringify(METADATA.ENV),
'NODE_ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
}
})
],
/**
* Static analysis linter for TypeScript advanced options configuration
* Description: An extensible linter for the TypeScript language.
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: 'src'
},
/**
* Webpack Development Server configuration
* Description: The webpack-dev-server is a little node.js Express server.
* The server emits information about the compilation state to the client,
* which reacts to those events.
*
* See: https://webpack.github.io/docs/webpack-dev-server.html
*/
devServer: {
port: METADATA.port,
host: METADATA.host,
historyApiFallback: true,
watchOptions: {
aggregateTimeout: 300,
poll: 1000
}
},
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: 'window',
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
});

230
config/webpack.prod.js Normal file
View file

@ -0,0 +1,230 @@
/**
* @author: @AngularClass
*/
const helpers = require('./helpers');
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
/**
* Webpack Plugins
*/
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const CompressionPlugin = require('compression-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
/**
* Webpack Constants
*/
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 8080;
const METADATA = webpackMerge(commonConfig.metadata, {
host: HOST,
port: PORT,
ENV: ENV,
HMR: false
});
module.exports = webpackMerge(commonConfig, {
/**
* Switch loaders to debug mode.
*
* See: http://webpack.github.io/docs/configuration.html#debug
*/
debug: false,
/**
* Developer tool to enhance debugging
*
* See: http://webpack.github.io/docs/configuration.html#devtool
* See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps
*/
devtool: 'source-map',
/**
* Options affecting the output of the compilation.
*
* See: http://webpack.github.io/docs/configuration.html#output
*/
output: {
/**
* The output directory as absolute path (required).
*
* See: http://webpack.github.io/docs/configuration.html#output-path
*/
path: helpers.root('dist'),
/**
* Specifies the name of each output file on disk.
* IMPORTANT: You must not specify an absolute path here!
*
* See: http://webpack.github.io/docs/configuration.html#output-filename
*/
filename: '[name].[chunkhash].bundle.js',
/**
* The filename of the SourceMaps for the JavaScript files.
* They are inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename
*/
sourceMapFilename: '[name].[chunkhash].bundle.map',
/**
* The filename of non-entry chunks as relative path
* inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-chunkfilename
*/
chunkFilename: '[id].[chunkhash].chunk.js'
},
/**
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
/**
* Plugin: WebpackMd5Hash
* Description: Plugin to replace a standard webpack chunkhash with md5.
*
* See: https://www.npmjs.com/package/webpack-md5-hash
*/
new WebpackMd5Hash(),
/**
* Plugin: DedupePlugin
* Description: Prevents the inclusion of duplicate code into your bundle
* and instead applies a copy of the function at runtime.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
* See: https://github.com/webpack/docs/wiki/optimization#deduplication
*/
new DedupePlugin(),
/**
* Plugin: DefinePlugin
* Description: Define free variables.
* Useful for having development builds with debug logging or adding global constants.
*
* Environment helpers
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
*/
// NOTE: when adding more properties make sure you include them in custom-typings.d.ts
new DefinePlugin({
'ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'process.env': {
'ENV': JSON.stringify(METADATA.ENV),
'NODE_ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
}
}),
/**
* Plugin: UglifyJsPlugin
* Description: Minimize all JavaScript output of chunks.
* Loaders are switched into minimizing mode.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
*/
// NOTE: To debug prod builds uncomment //debug lines and comment //prod lines
new UglifyJsPlugin({
// beautify: true, //debug
// mangle: false, //debug
// dead_code: false, //debug
// unused: false, //debug
// deadCode: false, //debug
// compress: {
// screw_ie8: true,
// keep_fnames: true,
// drop_debugger: false,
// dead_code: false,
// unused: false
// }, // debug
// comments: true, //debug
beautify: false, //prod
mangle: {
screw_ie8 : true,
keep_fnames: true
}, //prod
compress: {
screw_ie8: true
}, //prod
comments: false //prod
}),
/**
* Plugin: CompressionPlugin
* Description: Prepares compressed versions of assets to serve
* them with Content-Encoding
*
* See: https://github.com/webpack/compression-webpack-plugin
*/
new CompressionPlugin({
regExp: /\.css$|\.html$|\.js$|\.map$/,
threshold: 2 * 1024
})
],
/**
* Static analysis linter for TypeScript advanced options configuration
* Description: An extensible linter for the TypeScript language.
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
tslint: {
emitErrors: true,
failOnHint: true,
resourcePath: 'src'
},
/**
* Html loader advanced options
*
* See: https://github.com/webpack/html-loader#advanced-options
*/
// TODO: Need to workaround Angular 2's html syntax => #id [bind] (event) *ngFor
htmlLoader: {
minimize: true,
removeAttributeQuotes: false,
caseSensitive: true,
customAttrSurround: [
[/#/, /(?:)/],
[/\*/, /(?:)/],
[/\[?\(?/, /(?:)/]
],
customAttrAssign: [/\)?\]?=/]
},
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: 'window',
crypto: 'empty',
process: false,
module: false,
clearImmediate: false,
setImmediate: false
}
});

233
config/webpack.test.js Normal file
View file

@ -0,0 +1,233 @@
/**
* @author: @AngularClass
*/
const helpers = require('./helpers');
/**
* Webpack Plugins
*/
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
/**
* Webpack Constants
*/
const ENV = process.env.ENV = process.env.NODE_ENV = 'test';
/**
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = {
/**
* Source map for Karma from the help of karma-sourcemap-loader & karma-webpack
*
* Do not change, leave as is or it wont work.
* See: https://github.com/webpack/karma-webpack#source-maps
*/
devtool: 'inline-source-map',
/**
* Options affecting the resolving of modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve
*/
resolve: {
/**
* An array of extensions that should be used to resolve modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
*/
extensions: ['', '.ts', '.js'],
/**
* Make sure root is src
*/
root: helpers.root('src'),
},
/**
* Options affecting the normal modules.
*
* See: http://webpack.github.io/docs/configuration.html#module
*/
module: {
/**
* An array of applied pre and post loaders.
*
* See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders
*/
preLoaders: [
/**
* Tslint loader support for *.ts files
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
{
test: /\.ts$/,
loader: 'tslint-loader',
exclude: [helpers.root('node_modules')]
},
/**
* Source map loader support for *.js files
* Extracts SourceMaps for source files that as added as sourceMappingURL comment.
*
* See: https://github.com/webpack/source-map-loader
*/
{
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
// these packages have problems with their sourcemaps
helpers.root('node_modules/rxjs'),
helpers.root('node_modules/@angular2-material')
]}
],
/**
* An array of automatically applied loaders.
*
* IMPORTANT: The loaders here are resolved relative to the resource which they are applied to.
* This means they are not resolved relative to the configuration file.
*
* See: http://webpack.github.io/docs/configuration.html#module-loaders
*/
loaders: [
/**
* Typescript loader support for .ts and Angular 2 async routes via .async.ts
*
* See: https://github.com/s-panferov/awesome-typescript-loader
*/
{
test: /\.ts$/,
loader: 'awesome-typescript-loader',
query: {
compilerOptions: {
// Remove TypeScript helpers to be injected
// below by DefinePlugin
removeComments: true
}
},
exclude: [/\.e2e\.ts$/]
},
/**
* Json loader support for *.json files.
*
* See: https://github.com/webpack/json-loader
*/
{ test: /\.json$/, loader: 'json-loader', exclude: [helpers.root('src/index.html')] },
/**
* Raw loader support for *.css files
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{ test: /\.css$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] },
/**
* Raw loader support for *.html
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{ test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] }
],
/**
* An array of applied pre and post loaders.
*
* See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders
*/
postLoaders: [
/**
* Instruments JS files with Istanbul for subsequent code coverage reporting.
* Instrument only testing sources.
*
* See: https://github.com/deepsweet/istanbul-instrumenter-loader
*/
{
test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader',
include: helpers.root('src'),
exclude: [
/\.(e2e|spec)\.ts$/,
/node_modules/
]
}
]
},
/**
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
/**
* Plugin: DefinePlugin
* Description: Define free variables.
* Useful for having development builds with debug logging or adding global constants.
*
* Environment helpers
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
*/
// NOTE: when adding more properties make sure you include them in custom-typings.d.ts
new DefinePlugin({
'ENV': JSON.stringify(ENV),
'HMR': false,
'process.env': {
'ENV': JSON.stringify(ENV),
'NODE_ENV': JSON.stringify(ENV),
'HMR': false,
}
}),
],
/**
* Static analysis linter for TypeScript advanced options configuration
* Description: An extensible linter for the TypeScript language.
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: 'src'
},
/**
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: 'window',
process: false,
crypto: 'empty',
module: false,
clearImmediate: false,
setImmediate: false
}
};

6
karma.conf.js Normal file
View file

@ -0,0 +1,6 @@
/**
* @author: @AngularClass
*/
// Look in ./config for karma.conf.js
module.exports = require('./config/karma.conf.js');

144
package.json Normal file
View file

@ -0,0 +1,144 @@
{
"name": "angular2-webpack-starter",
"version": "5.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",
"author": "Patrick Stapleton <patrick@angularclass.com>",
"homepage": "https://github.com/angularclass/angular2-webpack-starter",
"license": "MIT",
"scripts": {
"rimraf": "rimraf",
"tslint": "tslint",
"typedoc": "typedoc",
"typings": "typings",
"webpack": "webpack",
"webpack-dev-server": "webpack-dev-server",
"webdriver-manager": "webdriver-manager",
"protractor": "protractor",
"clean": "npm cache clean && npm run rimraf -- node_modules doc typings coverage dist",
"clean:dist": "npm run rimraf -- dist",
"preclean:install": "npm run clean",
"clean:install": "npm set progress=false && npm install",
"preclean:start": "npm run clean",
"clean:start": "npm start",
"watch": "npm run watch:dev",
"watch:dev": "npm run build:dev -- --watch",
"watch:dev:hmr": "npm run watch:dev -- --hot",
"watch:test": "npm run test -- --auto-watch --no-single-run",
"watch:prod": "npm run build:prod -- --watch",
"build": "npm run build:dev",
"prebuild:dev": "npm run clean:dist",
"build:dev": "webpack --config config/webpack.dev.js --progress --profile --colors --display-error-details --display-cached",
"prebuild:prod": "npm run clean:dist",
"build:prod": "webpack --config config/webpack.prod.js --progress --profile --colors --display-error-details --display-cached --bail",
"server": "npm run server:dev",
"server:dev": "webpack-dev-server --config config/webpack.dev.js --inline --progress --profile --colors --watch --display-error-details --display-cached --content-base src/",
"server:dev:hmr": "npm run server:dev -- --hot",
"server:prod": "http-server dist --cors",
"webdriver:update": "npm run webdriver-manager update",
"webdriver:start": "npm run webdriver-manager start",
"lint": "npm run tslint 'src/**/*.ts'",
"pree2e": "npm run webdriver:update -- --standalone",
"e2e": "npm run protractor",
"e2e:live": "npm run e2e -- --elementExplorer",
"test": "node --max-old-space-size=4096 node_modules/karma/bin/karma start",
"ci": "npm run e2e && npm run test",
"docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
"start": "npm run server:dev",
"start:hmr": "npm run server:dev:hmr",
"postinstall": "npm run typings -- install",
"preversion": "npm test",
"version": "npm run build",
"postversion": "git push && git push --tags"
},
"dependencies": {
"@angular2-material/button": "2.0.0-alpha.2",
"@angular2-material/card": "2.0.0-alpha.2",
"@angular2-material/checkbox": "2.0.0-alpha.2",
"@angular2-material/core": "2.0.0-alpha.2",
"@angular2-material/input": "2.0.0-alpha.2",
"@angular2-material/list": "2.0.0-alpha.2",
"@angular2-material/progress-circle": "2.0.0-alpha.2",
"@angular2-material/radio": "2.0.0-alpha.2",
"@angular2-material/sidenav": "2.0.0-alpha.2",
"@angular2-material/toolbar": "2.0.0-alpha.2",
"angular2": "2.0.0-beta.15",
"core-js": "^2.2.2",
"normalize.css": "^4.1.1",
"rxjs": "5.0.0-beta.2",
"zone.js": "~0.6.11"
},
"devDependencies": {
"angular2-hmr": "~0.5.5",
"awesome-typescript-loader": "~0.16.2",
"codelyzer": "0.0.12",
"compression-webpack-plugin": "^0.3.1",
"copy-webpack-plugin": "^1.1.1",
"css-loader": "^0.23.1",
"es6-promise": "^3.1.2",
"es6-promise-loader": "^1.0.1",
"es6-shim": "^0.35.0",
"es7-reflect-metadata": "^1.6.0",
"exports-loader": "^0.6.3",
"expose-loader": "^0.7.1",
"file-loader": "^0.8.5",
"html-webpack-plugin": "^2.15.0",
"http-server": "^0.9.0",
"imports-loader": "^0.6.5",
"istanbul-instrumenter-loader": "^0.2.0",
"json-loader": "^0.5.4",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-coverage": "^0.5.5",
"karma-jasmine": "^0.3.8",
"karma-mocha-reporter": "^2.0.0",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "1.7.0",
"parse5": "^2.1.5",
"phantomjs-polyfill": "0.0.2",
"phantomjs-prebuilt": "^2.1.7",
"protractor": "^3.2.2",
"raw-loader": "0.5.1",
"remap-istanbul": "^0.5.1",
"rimraf": "^2.5.2",
"source-map-loader": "^0.1.5",
"style-loader": "^0.13.1",
"ts-helpers": "1.1.0",
"ts-node": "^0.7.1",
"tslint": "^3.7.1",
"tslint-loader": "^2.1.3",
"typedoc": "^0.3.12",
"typescript": "~1.8.9",
"typings": "^0.7.12",
"url-loader": "^0.5.7",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1",
"webpack-md5-hash": "^0.0.5",
"webpack-merge": "^0.8.4"
},
"repository": {
"type": "git",
"url": "https://github.com/angularclass/angular2-webpack-starter.git"
},
"bugs": {
"url": "https://github.com/angularclass/angular2-webpack-starter/issues"
},
"engines": {
"node": ">= 4.2.1",
"npm": ">= 3"
}
}

6
protractor.conf.js Normal file
View file

@ -0,0 +1,6 @@
/**
* @author: @AngularClass
*/
// look in ./config for protractor.conf.js
exports.config = require('./config/protractor.conf.js').config;

View file

@ -0,0 +1,55 @@
import {Component} from 'angular2/core';
/*
* We're loading this component asynchronously
* We are using some magic with es6-promise-loader that will wrap the module with a Promise
* see https://github.com/gdi2290/es6-promise-loader for more info
*/
console.log('`About` component loaded asynchronously');
@Component({
selector: 'about',
styles: [`
h1 {
font-family: Arial, Helvetica, sans-serif
}
`],
template: `
<md-card>
<h1>
patrick@AngularClass.com
</h1>
</md-card>
`
})
export class About {
constructor() {
}
ngOnInit() {
console.log('hello `About` component');
// static data that is bundled
// var mockData = require('assets/mock-data/mock-data.json');
// console.log('mockData', mockData);
// if you're working with mock data you can also use http.get('assets/mock-data/mock-data.json')
// this.asyncDataWithWebpack();
}
asyncDataWithWebpack() {
// you can also async load mock data with 'es6-promise-loader'
// you would do this if you don't want the mock-data bundled
// remember that 'es6-promise-loader' is a promise
// var asyncMockDataPromiseFactory = require('es6-promise!assets/mock-data/mock-data.json');
// setTimeout(() => {
//
// let asyncDataPromise = asyncMockDataPromiseFactory();
// asyncDataPromise.then(json => {
// console.log('async mockData', json);
// });
//
// });
}
}

View file

@ -0,0 +1,29 @@
import {
it,
inject,
injectAsync,
describe,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
// Load the implementations that should be tested
import {About} from './about.component';
describe('About', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
About
]);
it('should log ngOnInit', inject([ About ], (about) => {
spyOn(console, 'log');
expect(console.log).not.toHaveBeenCalled();
about.ngOnInit();
expect(console.log).toHaveBeenCalled();
}));
});

1
src/app/about/index.ts Normal file
View file

@ -0,0 +1 @@
export * from './about.component';

99
src/app/app.component.ts Normal file
View file

@ -0,0 +1,99 @@
/*
* Angular 2 decorators and services
*/
import {Component, ViewEncapsulation} from 'angular2/core';
import {RouteConfig, Router} from 'angular2/router';
import {Home} from './home';
import {AppState} from './app.service';
import {RouterActive} from './router-active';
/*
* App Component
* Top Level Component
*/
@Component({
selector: 'app',
pipes: [ ],
providers: [ ],
directives: [ RouterActive ],
encapsulation: ViewEncapsulation.None,
styles: [
require('normalize.css'),
`
md-toolbar ul {
display: inline;
list-style-type: none;
margin: 0;
padding: 0;
width: 60px;
}
md-toolbar li {
display: inline;
}
md-toolbar li.active {
background-color: lightgray;
}
`],
template: `
<header>
<md-toolbar color="primary">
<span>{{ name }}</span>
<nav>
<ul>
<li router-active>
<a [routerLink]=" ['Index'] ">Index</a>
</li>
|
<li router-active>
<a [routerLink]=" ['Home'] ">Home</a>
</li>
|
<li router-active>
<a [routerLink]=" ['About'] ">About</a>
</li>
</ul>
</nav>
</md-toolbar>
</header>
<main>
<router-outlet></router-outlet>
</main>
<pre>this.appState.state = {{ appState.state | json }}</pre>
<footer>
WebPack Angular 2 Starter by <a [href]="url">@AngularClass</a>
<div>
<img [src]="angularclassLogo" width="10%">
</div>
</footer>
`
})
@RouteConfig([
{ path: '/', name: 'Index', component: Home, useAsDefault: true },
{ path: '/home', name: 'Home', component: Home },
// Async load a component using Webpack's require with es6-promise-loader and webpack `require`
{ path: '/about', name: 'About', loader: () => require('es6-promise!./about')('About') }
])
export class App {
angularclassLogo = 'assets/img/angularclass-avatar.png';
name = 'Angular 2 Webpack Starter';
url = 'https://twitter.com/AngularClass';
constructor(public appState: AppState) {}
ngOnInit() {
console.log('Initial App State', this.appState.state);
}
}
/*
* Please review the https://github.com/AngularClass/angular2-examples/ repo for
* more angular app examples that you may copy/paste
* (The examples may not be updated as quickly. Please open an issue on github for us to update it)
* For help or questions please contact us at @AngularClass on twitter
* or our chat on Slack at https://AngularClass.com/slack-join
*/

32
src/app/app.e2e.ts Normal file
View file

@ -0,0 +1,32 @@
describe('App', () => {
beforeEach(() => {
browser.get('/');
});
it('should have a title', () => {
let subject = browser.getTitle();
let result = 'Angular2 Webpack Starter by @gdi2290 from @AngularClass';
expect(subject).toEqual(result);
});
it('should have <header>', () => {
let subject = element(by.css('app header')).isPresent();
let result = true;
expect(subject).toEqual(result);
});
it('should have <main>', () => {
let subject = element(by.css('app main')).isPresent();
let result = true;
expect(subject).toEqual(result);
});
it('should have <footer>', () => {
let subject = element(by.css('app footer')).getText();
let result = 'WebPack Angular 2 Starter by @AngularClass';
expect(subject).toEqual(result);
});
});

39
src/app/app.service.ts Normal file
View file

@ -0,0 +1,39 @@
import {Injectable} from 'angular2/core';
import {HmrState} from 'angular2-hmr';
@Injectable()
export class AppState {
// HmrState uis used by HMR to track the any state during reloading
@HmrState() _state = {};
constructor() {
}
// already return a clone of the current state
get state() {
return this._state = this._clone(this._state);
}
// never allow mutation
set state(value) {
throw new Error('do not mutate the `.state` directly');
}
get(prop?: any) {
// use our state getter for the clone
const state = this.state;
return state[prop] || state;
}
set(prop: string, value: any) {
// internally mutate our state
return this._state[prop] = value;
}
_clone(object) {
// simple object clone
return JSON.parse(JSON.stringify( object ));
}
}

24
src/app/app.spec.ts Normal file
View file

@ -0,0 +1,24 @@
import {
it,
inject,
injectAsync,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
// Load the implementations that should be tested
import {App} from './app.component';
import {AppState} from './app.service';
describe('App', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
AppState,
App
]);
it('should have a url', inject([ App ], (app) => {
expect(app.url).toEqual('https://twitter.com/AngularClass');
}));
});

View file

@ -0,0 +1,46 @@
import {Component} from 'angular2/core';
import {AppState} from '../app.service';
import {Title} from './title';
import {XLarge} from './x-large';
@Component({
// The selector is what angular internally uses
// for `document.querySelectorAll(selector)` in our index.html
// where, in this case, selector is the string 'home'
selector: 'home', // <home></home>
// We need to tell Angular's Dependency Injection which providers are in our app.
providers: [
Title
],
// We need to tell Angular's compiler which directives are in our template.
// Doing so will allow Angular to attach our behavior to an element
directives: [
XLarge
],
// We need to tell Angular's compiler which custom pipes are in our template.
pipes: [ ],
// Our list of styles in our component. We may add more to compose many styles together
styles: [ require('./home.css') ],
// Every Angular template is first compiled by the browser before Angular runs it's compiler
template: require('./home.html')
})
export class Home {
// Set our default values
localState = { value: '' };
// TypeScript public modifiers
constructor(public appState: AppState, public title: Title) {
}
ngOnInit() {
console.log('hello `Home` component');
// this.title.getData().subscribe(data => this.data = data);
}
submitState(value) {
console.log('submitState', value);
this.appState.set('value', value);
}
}

0
src/app/home/home.css Normal file
View file

22
src/app/home/home.e2e.ts Normal file
View file

@ -0,0 +1,22 @@
describe('App', () => {
beforeEach(() => {
// change hash depending on router LocationStrategy
browser.get('/#/home');
});
it('should have a title', () => {
let subject = browser.getTitle();
let result = 'Angular2 Webpack Starter by @gdi2290 from @AngularClass';
expect(subject).toEqual(result);
});
it('should have `your content here` x-large', () => {
let subject = element(by.css('[x-large]')).getText();
let result = 'Your Content Here';
expect(subject).toEqual(result);
});
});

31
src/app/home/home.html Normal file
View file

@ -0,0 +1,31 @@
<md-card>
<md-card-content>
<span x-large>Your Content Here</span>
<form (ngSubmit)="submitState(localState.value)" autocomplete="off">
<md-input
placeholder="Submit Local State to App State"
[value]="localState.value"
(input)="localState.value = $event.target.value"
autofocus>
</md-input>
<button md-raised-button color="primary">Submit Value</button>
</form>
<!--
<input type="text" [value]="localState.value" (input)="localState.value = $event.target.value" autofocus>
Rather than wiring up two-way data-binding ourselves with [value] and (input)
we can use Angular's [(ngModel)] syntax
<input type="text" [(ngModel)]="localState.value" autofocus>
-->
<md-card>
For hot module reloading run
<pre>npm run start:hmr</pre>
</md-card>
<hr>
<pre>this.localState = {{ localState | json }}</pre>
</md-card-content>
</md-card>

52
src/app/home/home.spec.ts Normal file
View file

@ -0,0 +1,52 @@
import {
it,
inject,
injectAsync,
describe,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
// Load the implementations that should be tested
import {Home} from './home.component';
import {Title} from './title';
import {AppState} from '../app.service';
describe('Home', () => {
// provide our implementations or mocks to the dependency injector
beforeEachProviders(() => [
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: function(backend, defaultOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
}),
AppState,
Title,
Home
]);
it('should have default data', inject([ Home ], (home) => {
expect(home.localState).toEqual({ value: '' });
}));
it('should have a title', inject([ Home ], (home) => {
expect(!!home.title).toEqual(true);
}));
it('should log ngOnInit', inject([ Home ], (home) => {
spyOn(console, 'log');
expect(console.log).not.toHaveBeenCalled();
home.ngOnInit();
expect(console.log).toHaveBeenCalled();
}));
});

1
src/app/home/index.ts Normal file
View file

@ -0,0 +1 @@
export * from './home.component';

View file

@ -0,0 +1 @@
export * from './title.service';

View file

@ -0,0 +1,20 @@
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
@Injectable()
export class Title {
value = 'Angular 2';
constructor(public http: Http) {
}
getData() {
console.log('Title#getData(): Get Data');
// return this.http.get('/assets/data.json')
// .map(res => res.json());
return {
value: 'AngularClass'
};
}
}

View file

@ -0,0 +1,44 @@
import {
it,
inject,
injectAsync,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
import {Title} from './title.service';
describe('Title', () => {
beforeEachProviders(() => [
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: function(backend, defaultOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
}),
Title
]);
it('should have http', inject([ Title ], (title) => {
expect(!!title.http).toEqual(true);
}));
it('should get data from the server', inject([ Title ], (title) => {
spyOn(console, 'log');
expect(console.log).not.toHaveBeenCalled();
title.getData();
expect(console.log).toHaveBeenCalled();
expect(title.getData()).toEqual({ value: 'AngularClass' });
}));
});

View file

@ -0,0 +1 @@
export * from './x-large.directive';

View file

@ -0,0 +1,18 @@
import {Directive, Component, ElementRef, Renderer} from 'angular2/core';
/*
* Directive
* XLarge is a simple directive to show how one is made
*/
@Directive({
selector: '[x-large]' // using [ ] means selecting attributes
})
export class XLarge {
constructor(element: ElementRef, renderer: Renderer) {
// simple DOM manipulation to set font size to x-large
// `nativeElement` is the direct reference to the DOM element
// element.nativeElement.style.fontSize = 'x-large';
// for server/webworker support use the renderer
renderer.setElementStyle(element.nativeElement, 'fontSize', 'x-large');
}
}

View file

@ -0,0 +1,34 @@
import {
it,
inject,
injectAsync,
describe,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {BaseRequestOptions, Http} from 'angular2/http';
import {MockBackend} from 'angular2/http/testing';
// Load the implementations that should be tested
import {XLarge} from './x-large.directive';
describe('x-large directive', () => {
// Create a test component to test directives
@Component({
template: '',
directives: [ XLarge ]
})
class TestComponent {}
it('should sent font-size to x-large', injectAsync([TestComponentBuilder], (tcb) => {
return tcb.overrideTemplate(TestComponent, '<div x-large>Content</div>')
.createAsync(TestComponent).then((fixture: any) => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement.children[0];
expect(compiled.style.fontSize).toBe('x-large');
});
}));
});

10
src/app/index.ts Normal file
View file

@ -0,0 +1,10 @@
// App
export * from './app.component';
export * from './app.service';
import {AppState} from './app.service';
// Application wide providers
export const APP_PROVIDERS = [
AppState
];

View file

@ -0,0 +1,2 @@
// Application level directive
export * from './router-active.directive';

View file

@ -0,0 +1,73 @@
import {Router} from 'angular2/router';
import {isPresent} from 'angular2/src/facade/lang';
import {
Directive,
Query,
QueryList,
Attribute,
ElementRef,
Renderer,
Optional,
Input
} from 'angular2/core';
import {Instruction, RouterLink} from 'angular2/router';
/**
* RouterActive dynamically finds the first element with routerLink and toggles the active class
*
* ## Use
*
* ```
* <li router-active="active"><a [routerLink]=" ['/Home'] ">Home</a></li>
* <li [routerActive]=" activeStringValue "><a [routerLink]=" ['/Home'] ">Home</a></li>
* ```
*/
@Directive({
selector: '[router-active]'
})
export class RouterActive {
@Input() routerActive: string = undefined;
routerActiveAttr: string = 'active';
constructor(
public router: Router,
public element: ElementRef,
public renderer: Renderer,
@Query(RouterLink) public routerLink: QueryList<RouterLink>,
@Optional() @Attribute('router-active') routerActiveAttr?: string) {
this.routerActiveAttr = this._defaultAttrValue(routerActiveAttr);
}
ngOnInit() {
this.routerLink.changes.subscribe(() => {
if (this.routerLink.first) {
this._updateClass();
this._findRootRouter().subscribe(() => {
this._updateClass();
});
}
});
}
private _findRootRouter(): Router {
let router: Router = this.router;
while (isPresent(router.parent)) {
router = router.parent;
}
return router;
}
private _updateClass() {
let active = this.routerLink.first.isRouteActive;
this.renderer.setElementClass(this.element.nativeElement, this._attrOrProp(), active);
}
private _defaultAttrValue(attr?: string) {
return this.routerActiveAttr = attr || this.routerActiveAttr;
}
private _attrOrProp() {
return isPresent(this.routerActive) ? this.routerActive : this.routerActiveAttr;
}
}

1
src/assets/css/.gitkeep Normal file
View file

@ -0,0 +1 @@
@AngularClass

3
src/assets/data.json Normal file
View file

@ -0,0 +1,3 @@
{
"value": "AngularClass"
}

17
src/assets/humans.txt Normal file
View file

@ -0,0 +1,17 @@
# humanstxt.org/
# The humans responsible & technology colophon
# TEAM
<name> -- <role> -- <twitter>
# THANKS
<name>
PatrickJS -- @gdi2290
AngularClass -- @AngularClass
# TECHNOLOGY COLOPHON
HTML5, CSS3
Angular2, TypeScript, Webpack

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
src/assets/icon/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

41
src/assets/manifest.json Normal file
View file

@ -0,0 +1,41 @@
{
"name": "App",
"icons": [
{
"src": "/assets/icon/android-icon-36x36.png",
"sizes": "36x36",
"type": "image/png",
"density": 0.75
},
{
"src": "/assets/icon/android-icon-48x48.png",
"sizes": "48x48",
"type": "image/png",
"density": 1.0
},
{
"src": "/assets/icon/android-icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"density": 1.5
},
{
"src": "/assets/icon/android-icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"density": 2.0
},
{
"src": "/assets/icon/android-icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"density": 3.0
},
{
"src": "/assets/icon/android-icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"density": 4.0
}
]
}

View file

@ -0,0 +1,3 @@
[
{"res": "data"}
]

3
src/assets/robots.txt Normal file
View file

@ -0,0 +1,3 @@
# robotstxt.org
User-agent: *

View file

@ -0,0 +1 @@
// This file is intentionally without code.

119
src/custom-typings.d.ts vendored Normal file
View file

@ -0,0 +1,119 @@
/*
* Custom Type Definitions
* When including 3rd party modules you also need to include the type definition for the module
* if they don't provide one within the module. You can try to install it with typings
typings install node --save
* If you can't find the type definition in the registry we can make an ambient definition in
* this file for now. For example
declare module "my-module" {
export function doesSomething(value: string): string;
}
*
* If you're prototying and you will fix the types later you can also declare it as type any
*
declare var assert: any;
*
* If you're importing a module that uses Node.js modules which are CommonJS you need to import as
*
import * as _ from 'lodash'
* You can include your type definitions in this file until you create one for the typings registry
* see https://github.com/typings/registry
*
*/
// Extra variables that live on Global that will be replaced by webpack DefinePlugin
declare var ENV: string;
declare var HMR: boolean;
interface GlobalEnvironment {
ENV;
HMR;
}
interface WebpackModule {
hot: {
data?: any,
idle: any,
accept(dependencies?: string | string[], callback?: (updatedDependencies?: any) => void): void;
decline(dependencies?: string | string[]): void;
dispose(callback?: (data?: any) => void): void;
addDisposeHandler(callback?: (data?: any) => void): void;
removeDisposeHandler(callback?: (data?: any) => void): void;
check(autoApply?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
apply(options?: any, callback?: (err?: Error, outdatedModules?: any[]) => void): void;
status(callback?: (status?: string) => void): void | string;
removeStatusHandler(callback?: (status?: string) => void): void;
};
}
interface WebpackRequire {
context(file: string, flag?: boolean, exp?: RegExp): any;
}
interface ErrorStackTraceLimit {
stackTraceLimit: number;
}
// Extend typings
interface NodeRequire extends WebpackRequire {}
interface ErrorConstructor extends ErrorStackTraceLimit {}
interface NodeModule extends WebpackModule {}
interface Global extends GlobalEnvironment {}
declare namespace Reflect {
function decorate(decorators: ClassDecorator[], target: Function): Function;
function decorate(
decorators: (PropertyDecorator | MethodDecorator)[],
target: Object,
targetKey: string | symbol,
descriptor?: PropertyDescriptor): PropertyDescriptor;
function metadata(metadataKey: any, metadataValue: any): {
(target: Function): void;
(target: Object, propertyKey: string | symbol): void;
};
function defineMetadata(metadataKey: any, metadataValue: any, target: Object): void;
function defineMetadata(
metadataKey: any,
metadataValue: any,
target: Object,
targetKey: string | symbol): void;
function hasMetadata(metadataKey: any, target: Object): boolean;
function hasMetadata(metadataKey: any, target: Object, targetKey: string | symbol): boolean;
function hasOwnMetadata(metadataKey: any, target: Object): boolean;
function hasOwnMetadata(metadataKey: any, target: Object, targetKey: string | symbol): boolean;
function getMetadata(metadataKey: any, target: Object): any;
function getMetadata(metadataKey: any, target: Object, targetKey: string | symbol): any;
function getOwnMetadata(metadataKey: any, target: Object): any;
function getOwnMetadata(metadataKey: any, target: Object, targetKey: string | symbol): any;
function getMetadataKeys(target: Object): any[];
function getMetadataKeys(target: Object, targetKey: string | symbol): any[];
function getOwnMetadataKeys(target: Object): any[];
function getOwnMetadataKeys(target: Object, targetKey: string | symbol): any[];
function deleteMetadata(metadataKey: any, target: Object): boolean;
function deleteMetadata(metadataKey: any, target: Object, targetKey: string | symbol): boolean;
}
// We need this here since there is a problem with Zone.js typings
interface Thenable<T> {
then<U>(
onFulfilled?: (value: T) => U | Thenable<U>,
onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
then<U>(
onFulfilled?: (value: T) => U | Thenable<U>,
onRejected?: (error: any) => void): Thenable<U>;
catch<U>(onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
}

63
src/index.html Normal file
View file

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="">
<head>
<title><%= webpackConfig.metadata.title %></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="<%= webpackConfig.metadata.title %>">
<!-- use http://www.favicon-generator.org/ to replace files in public/icon-->
<link rel="apple-touch-icon" sizes="57x57" href="/assets/icon/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/assets/icon/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/assets/icon/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/assets/icon/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/assets/icon/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/assets/icon/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/assets/icon/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/assets/icon/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icon/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/assets/icon/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/assets/icon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icon/favicon-16x16.png">
<link rel="manifest" href="/assets/manifest.json">
<meta name="msapplication-TileColor" content="#00bcd4">
<meta name="msapplication-TileImage" content="/assets/icon/ms-icon-144x144.png">
<meta name="theme-color" content="#00bcd4">
<!-- end favicon -->
<!-- base url -->
<base href="<%= webpackConfig.metadata.baseUrl %>">
</head>
<body>
<app>
Loading...
</app>
<!-- Google Analytics: change UA-71073175-1 to be your site's ID -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-71073175-1', 'auto');
ga('send', 'pageview');
</script>
<% if (webpackConfig.metadata.ENV === 'development') { %>
<!-- Webpack Dev Server reload -->
<script src="/webpack-dev-server.js"></script>
<% } %>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</body>
</html>

58
src/main.browser.ts Normal file
View file

@ -0,0 +1,58 @@
/*
* Providers provided by Angular
*/
import {bootstrap} from 'angular2/platform/browser';
/*
* Platform and Environment
* our providers/directives/pipes
*/
import {DIRECTIVES, PIPES, PROVIDERS} from './platform/browser';
import {ENV_PROVIDERS} from './platform/environment';
/*
* App Component
* our top level component that holds all of our components
*/
import {App, APP_PROVIDERS} from './app';
/*
* Bootstrap our Angular app with a top level component `App` and inject
* our Services and Providers into Angular's dependency injection
*/
export function main(initialHmrState?: any): Promise<any> {
return bootstrap(App, [
...PROVIDERS,
...ENV_PROVIDERS,
...DIRECTIVES,
...PIPES,
...APP_PROVIDERS
])
.catch(err => console.error(err));
}
/*
* Vendors
* For vendors for example jQuery, Lodash, angular2-jwt just import them anywhere in your app
* You can also import them in vendors to ensure that they are bundled in one file
* Also see custom-typings.d.ts as you also need to do `typings install x` where `x` is your module
*/
/*
* Hot Module Reload
* experimental version by @gdi2290
*/
if ('development' === ENV && HMR === true) {
// activate hot module reload
let ngHmr = require('angular2-hmr');
ngHmr.hotModuleReplacement(main, module);
} else {
// bootstrap when documetn is ready
document.addEventListener('DOMContentLoaded', () => main());
}

View file

@ -0,0 +1,37 @@
import {MdButton, MdAnchor} from '@angular2-material/button';
import {MD_CARD_DIRECTIVES} from '@angular2-material/card';
import {MdCheckbox} from '@angular2-material/checkbox';
import {MD_SIDENAV_DIRECTIVES} from '@angular2-material/sidenav';
import {MD_INPUT_DIRECTIVES} from '@angular2-material/input';
import {MD_LIST_DIRECTIVES} from '@angular2-material/list';
import {MdRadioGroup, MdRadioButton, MdRadioDispatcher} from '@angular2-material/radio';
import {MdSpinner, MdProgressCircle} from '@angular2-material/progress-circle';
import {MdToolbar} from '@angular2-material/toolbar';
/*
* we are grouping the module so we only need to manage the imports in one location
*/
export const MATERIAL_PIPES = [
];
export const MATERIAL_DIRECTIVES = [
...MD_SIDENAV_DIRECTIVES,
...[
MdAnchor,
MdButton,
MdToolbar,
MdCheckbox,
MdRadioButton,
MdSpinner,
MdProgressCircle
],
...MD_INPUT_DIRECTIVES,
...MD_LIST_DIRECTIVES,
...MD_CARD_DIRECTIVES
];
export const MATERIAL_PROVIDERS = [
MdRadioDispatcher
];

View file

@ -0,0 +1,22 @@
/*
* These are globally available directives in any template
*/
import {provide, PLATFORM_DIRECTIVES} from 'angular2/core';
// Angular 2 Router
import {ROUTER_DIRECTIVES} from 'angular2/router';
// Angular 2 Material 2
// TODO(gdi2290): replace with @angular2-material/all
import {MATERIAL_DIRECTIVES} from './angular2-material2';
// application_directives: directives that are global through out the application
export const APPLICATION_DIRECTIVES = [
...ROUTER_DIRECTIVES,
...MATERIAL_DIRECTIVES
];
export const DIRECTIVES = [
provide(PLATFORM_DIRECTIVES, { multi: true, useValue: APPLICATION_DIRECTIVES })
];

View file

@ -0,0 +1,3 @@
export * from './directives';
export * from './pipes';
export * from './providers';

View file

@ -0,0 +1,14 @@
/*
* These are globally available pipes in any template
*/
import {provide, PLATFORM_PIPES} from 'angular2/core';
// application_pipes: pipes that are global through out the application
export const APPLICATION_PIPES = [
];
export const PIPES = [
provide(PLATFORM_PIPES, { multi: true, useValue: APPLICATION_PIPES })
];

View file

@ -0,0 +1,34 @@
/*
* These are globally available services in any component or any other service
*/
import {provide} from 'angular2/core';
// Angular 2
import {FORM_PROVIDERS} from 'angular2/common';
// Angular 2 Http
import {HTTP_PROVIDERS} from 'angular2/http';
// Angular 2 Router
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
// Angular 2 Material
// TODO(gdi2290): replace with @angular2-material/all
import {MATERIAL_PROVIDERS} from './angular2-material2';
/*
* Application Providers/Directives/Pipes
* providers/directives/pipes that only live in our browser environment
*/
export const APPLICATION_PROVIDERS = [
...FORM_PROVIDERS,
...HTTP_PROVIDERS,
...MATERIAL_PROVIDERS,
...ROUTER_PROVIDERS,
provide(LocationStrategy, { useClass: HashLocationStrategy })
];
export const PROVIDERS = [
...APPLICATION_PROVIDERS
];

View file

@ -0,0 +1,34 @@
// Angular 2 browser
import {
ELEMENT_PROBE_PROVIDERS,
ELEMENT_PROBE_PROVIDERS_PROD_MODE
} from 'angular2/platform/browser';
// Angular 2
import {enableProdMode} from 'angular2/core';
// Environment Providers
let PROVIDERS = [];
if ('production' === ENV) {
// Production
enableProdMode();
PROVIDERS = [
...PROVIDERS,
ELEMENT_PROBE_PROVIDERS_PROD_MODE
];
} else {
// Development
PROVIDERS = [
...PROVIDERS,
ELEMENT_PROBE_PROVIDERS
];
}
export const ENV_PROVIDERS = [
...PROVIDERS
];

28
src/polyfills.ts Normal file
View file

@ -0,0 +1,28 @@
// Polyfills
// (these modules are what are in 'angular2/bundles/angular2-polyfills' so don't use that here)
// import 'ie-shim'; // Internet Explorer
// import 'es6-shim';
// import 'es6-promise';
// import 'es7-reflect-metadata';
// Prefer CoreJS over the polyfills above
import 'core-js/es6';
import 'core-js/es7/reflect';
require('zone.js/dist/zone');
// Typescript emit helpers polyfill
import 'ts-helpers';
if ('production' === ENV) {
// Production
} else {
// Development
Error.stackTraceLimit = Infinity;
require('zone.js/dist/long-stack-trace-zone');
}

36
src/vendor.ts Normal file
View file

@ -0,0 +1,36 @@
// For vendors for example jQuery, Lodash, angular2-jwt just import them here unless you plan on
// chunking vendors files for async loading. You would need to import the async loaded vendors
// at the entry point of the async loaded file. Also see custom-typings.d.ts as you also need to
// run `typings install x` where `x` is your module
// Angular 2
import 'angular2/platform/browser';
import 'angular2/platform/common_dom';
import 'angular2/core';
import 'angular2/common';
import 'angular2/http';
import 'angular2/router';
// RxJS
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
// Angular 2 Material 2
// TODO(gdi2290): uncomment when material is fixed
// import '@angular2-material/sidenav';
// import '@angular2-material/toolbar';
// import '@angular2-material/button';
// import '@angular2-material/checkbox';
// import '@angular2-material/radio';
// import '@angular2-material/progress-circle';
// import '@angular2-material/card';
// look in platform/directives and platform/providers
if ('production' === ENV) {
// Production
} else {
// Development
}

29
tsconfig.json Normal file
View file

@ -0,0 +1,29 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"noEmitHelpers": true
},
"exclude": [
"node_modules",
"typings/main.d.ts",
"typings/main"
],
"filesGlob": [
"./src/**/*.ts",
"./test/**/*.ts",
"!./node_modules/**/*.ts",
"src/custom-typings.d.ts",
"typings/browser.d.ts"
],
"awesomeTypescriptLoaderOptions": {
"resolveGlobs": true,
"forkChecker": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
}

151
tslint.json Normal file
View file

@ -0,0 +1,151 @@
{
"rulesDirectory": [
"node_modules/codelyzer/dist/src"
],
"rules": {
"member-access": false,
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-inferrable-types": false,
"no-internal-module": true,
"no-var-requires": false,
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "space",
"index-signature": "space",
"parameter": "space",
"property-declaration": "space",
"variable-declaration": "space"
}
],
"ban": false,
"curly": false,
"forin": true,
"label-position": true,
"label-undefined": true,
"no-arg": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-null-keyword": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
"no-unreachable": true,
"no-unused-expression": true,
"no-unused-variable": false,
"no-use-before-declare": true,
"no-var-keyword": true,
"radix": true,
"switch-default": true,
"triple-equals": [
true,
"allow-null-check"
],
"use-strict": [
true,
"check-module"
],
"eofline": true,
"indent": [
true,
"spaces"
],
"max-line-length": [
true,
100
],
"no-require-imports": false,
"no-trailing-whitespace": true,
"object-literal-sort-keys": false,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"align": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"interface-name": false,
"jsdoc-format": true,
"no-consecutive-blank-lines": false,
"no-constructor-vars": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-finally",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"semicolon": [true, "always"],
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
],
"directive-selector-name": [true, "kebab-case"],
"component-selector-name": [true, "kebab-case"],
"directive-selector-type": [true, "attribute"],
"component-selector-type": [true, "element"],
"directive-selector-prefix": false,
"component-selector-prefix": false,
"host-parameter-decorator": true,
"input-parameter-decorator": true,
"output-parameter-decorator": true,
"attribute-parameter-decorator": false,
"input-property-directive": true,
"output-property-directive": true,
"call-forward-ref":true
}
}

15
typedoc.json Normal file
View file

@ -0,0 +1,15 @@
{
"mode": "modules",
"out": "doc",
"theme": "default",
"ignoreCompilerErrors": "true",
"experimentalDecorators": "true",
"emitDecoratorMetadata": "true",
"target": "ES5",
"moduleResolution": "node",
"preserveConstEnums": "true",
"stripInternal": "true",
"suppressExcessPropertyErrors": "true",
"suppressImplicitAnyIndexErrors": "true",
"module": "commonjs"
}

15
typings.json Normal file
View file

@ -0,0 +1,15 @@
{
"dependencies": {
"zone.js": "github:gdi2290/typed-zone.js#66ea8a3451542bb7798369306840e46be1d6ec89"
},
"devDependencies": {},
"ambientDependencies": {
"angular-protractor": "github:DefinitelyTyped/DefinitelyTyped/angular-protractor/angular-protractor.d.ts#64b25f63f0ec821040a5d3e049a976865062ed9d",
"core-js": "registry:dt/core-js#0.0.0+20160317120654",
"hammerjs": "github:DefinitelyTyped/DefinitelyTyped/hammerjs/hammerjs.d.ts#74a4dfc1bc2dfadec47b8aae953b28546cb9c6b7",
"jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#4b36b94d5910aa8a4d20bdcd5bd1f9ae6ad18d3c",
"node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#8cf8164641be73e8f1e652c2a5b967c7210b6729",
"selenium-webdriver": "github:DefinitelyTyped/DefinitelyTyped/selenium-webdriver/selenium-webdriver.d.ts#a83677ed13add14c2ab06c7325d182d0ba2784ea",
"webpack": "github:DefinitelyTyped/DefinitelyTyped/webpack/webpack.d.ts#95c02169ba8fa58ac1092422efbd2e3174a206f4"
}
}

19
webpack.config.js Normal file
View file

@ -0,0 +1,19 @@
/**
* @author: @AngularClass
*/
// Look in ./config folder for webpack.dev.js
switch (process.env.NODE_ENV) {
case 'prod':
case 'production':
module.exports = require('./config/webpack.prod');
break;
case 'test':
case 'testing':
module.exports = require('./config/webpack.test');
break;
case 'dev':
case 'development':
default:
module.exports = require('./config/webpack.dev');
}