├── src
├── index.ts
├── components
│ ├── index.ts
│ └── hello-world
│ │ ├── HelloWorld.component.html
│ │ ├── HelloWorld.component.scss
│ │ ├── index.ts
│ │ ├── HelloWorld.component.ts
│ │ ├── README.md
│ │ ├── HelloWorld.module.ts
│ │ └── HelloWorld.spec.ts
├── polyfills.ts
├── vendor.ts
└── tsconfig.aot.json
├── .editorconfig
├── typedoc.json
├── tsconfig.json
├── CHANGELOG.md
├── README.md
├── gulpfile.js
├── .gitignore
├── protractor.conf.js
├── LICENSE
├── karma-shim.js
├── karma.conf.js
├── package.json
├── tslint.json
├── scripts
└── gulp
│ └── inline-resources.js
└── webpack.config.js
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components';
--------------------------------------------------------------------------------
/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './hello-world';
--------------------------------------------------------------------------------
/src/components/hello-world/HelloWorld.component.html:
--------------------------------------------------------------------------------
1 |
Hello World
--------------------------------------------------------------------------------
/src/components/hello-world/HelloWorld.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | h1 {
3 | color: red;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/hello-world/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Export all module and components
3 | */
4 | export {HelloWorldModule} from './HelloWorld.module';
5 | export {HelloWorldComponent} from './HelloWorld.component';
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | charset = utf-8
9 | indent_style = space
10 | indent_size = 2
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | import 'core-js/client/shim';
2 | import 'reflect-metadata';
3 | require('zone.js/dist/zone');
4 |
5 | import 'ts-helpers';
6 |
7 | if (process.env.ENV === 'build') {
8 | // Production
9 |
10 | } else {
11 | // Development
12 |
13 | Error['stackTraceLimit'] = Infinity;
14 |
15 | require('zone.js/dist/long-stack-trace-zone');
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/hello-world/HelloWorld.component.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * example of component
3 | *
4 | * @author Daniele Zurico
5 | */
6 | import {Component} from '@angular/core';
7 | @Component({
8 | selector: 'hello-world',
9 | templateUrl: './HelloWorld.component.html',
10 | styleUrls: ['./HelloWorld.component.scss']
11 | })
12 |
13 | export class HelloWorldComponent {
14 |
15 | }
--------------------------------------------------------------------------------
/src/vendor.ts:
--------------------------------------------------------------------------------
1 | // Angular 2
2 | import '@angular/platform-browser';
3 | import '@angular/platform-browser-dynamic';
4 | import '@angular/core';
5 | import '@angular/common';
6 | import '@angular/http';
7 | import '@angular/router';
8 |
9 | import 'rxjs';
10 | import '@angularclass/hmr';
11 |
12 | // Other vendors for example jQuery, Lodash or Bootstrap
13 | // You can import js, ts, css, sass, ...
14 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "mode": "modules",
3 | "out": "doc",
4 | "theme": "default",
5 | "ignoreCompilerErrors": "true",
6 | "experimentalDecorators": "true",
7 | "emitDecoratorMetadata": "true",
8 | "target": "ES5",
9 | "moduleResolution": "node",
10 | "preserveConstEnums": "true",
11 | "stripInternal": "true",
12 | "suppressExcessPropertyErrors": "true",
13 | "suppressImplicitAnyIndexErrors": "true",
14 | "module": "commonjs"
15 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES5",
4 | "module": "commonjs",
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "sourceMap": true,
8 | "noEmitHelpers": true,
9 | "lib": [
10 | "es6",
11 | "es2015",
12 | "dom"
13 | ]
14 | },
15 | "compileOnSave": false,
16 | "buildOnSave": false,
17 | "awesomeTypescriptLoaderOptions": {
18 | "forkChecker": true,
19 | "useWebpackText": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/hello-world/README.md:
--------------------------------------------------------------------------------
1 | #Hello World
2 |
3 | It is an example how to write components in the correct way. It display the message **Hello world**.
4 |
5 | To include Hello World in your project you have to:
6 | 1) In your Module include HelloWorldModule:
7 | ```javascript
8 | @NgModule({
9 | imports: [HelloWorldModule],
10 | declarations: [],
11 | exports: []
12 | })
13 | ```
14 |
15 | 2) In your html add:
16 | ```html
17 |
18 | ```
--------------------------------------------------------------------------------
/src/components/hello-world/HelloWorld.module.ts:
--------------------------------------------------------------------------------
1 | import {NgModule, ModuleWithProviders} from '@angular/core';
2 | import {HelloWorldComponent} from './HelloWorld.component';
3 | /**
4 | * The Hello World component is an example how to write components in the correct way.
5 | *
6 | * @author Daniele Zurico
7 | */
8 | @NgModule({
9 | declarations: [HelloWorldComponent],
10 | exports: [HelloWorldComponent]
11 | })
12 |
13 | export class HelloWorldModule {
14 | static forRoot(): ModuleWithProviders {
15 | return {ngModule: HelloWorldModule, providers: []};
16 | }
17 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | # 04 October 2016
4 |
5 | - Migrate to webpack 2
6 |
7 | # 18 September 2016
8 |
9 | - Using `awesome-typescript-loader` instead of `ts-loader`.
10 |
11 | # 5 September 2016
12 |
13 | - Migration to TS2 and @types
14 |
15 | ## 1 September 2016
16 |
17 | - Using RC6.
18 |
19 | ## 28 August 2016
20 |
21 | - Adding webpack-dashboard.
22 |
23 | ## 23 August 2016
24 |
25 | - Adding HMR support.
26 |
27 | ## 3 July 2016
28 |
29 | - Use html5mode instead of hash navigation.
30 |
31 | ## 24 June 2016
32 |
33 | - Be able to import Component's templates and styles without using require.
34 |
--------------------------------------------------------------------------------
/src/tsconfig.aot.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "emitDecoratorMetadata": true,
5 | "experimentalDecorators": true,
6 | "lib": [
7 | "es6",
8 | "es2015",
9 | "dom"
10 | ],
11 | "noImplicitAny": false,
12 | "target": "es5",
13 | "module": "es2015",
14 | "moduleResolution": "node",
15 | "sourceMap": true,
16 | "mapRoot": "",
17 | "outDir": "./../dist",
18 | "skipLibCheck": true,
19 | "baseUrl": ""
20 | },
21 | "exclude": [
22 | "**/*.spec.ts",
23 | "./vendor.ts",
24 | "./polyfills.ts"
25 | ],
26 | "angularCompilerOptions": {
27 | "skipTemplateCodegen": true,
28 | "debug": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/hello-world/HelloWorld.spec.ts:
--------------------------------------------------------------------------------
1 | import {
2 | async,
3 | TestBed
4 | } from '@angular/core/testing';
5 |
6 | import {HelloWorldComponent} from './HelloWorldComponent';
7 |
8 | describe('Testing Hello World Component', () => {
9 | beforeEach(() => {
10 | TestBed.configureTestingModule({
11 | providers: [],
12 | declarations: [HelloWorldComponent]
13 | });
14 | });
15 |
16 | it('Should contain hello world text', async(() => {
17 | const fixture = TestBed.createComponent(HelloWorldComponent);
18 | fixture.detectChanges();
19 |
20 | let compiled = fixture.debugElement.nativeElement;
21 |
22 | expect(compiled.querySelector('h1').textContent).toContain('Hello World');
23 | }));
24 | });
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #angular2-library
2 |
3 | this project show how to package a library using ngc.
4 |
5 | For more information please visit: http://www.dzurico.com/how-to-create-an-angular-library/
6 |
7 | ###how to install
8 | npm install
9 |
10 | ###how to package the library
11 | npm run build
12 |
13 | ###how to use the package in your project
14 | npm install ../angular2-library (specify the correct path)
15 |
16 | in your module include:
17 | ```
18 | import {HelloWorldModule} from 'angular2-sdk/dist';
19 |
20 | @NgModule({
21 | imports: [
22 | ...
23 | HelloWorldModule
24 | ],
25 | declarations: [
26 | ...
27 | ],
28 | providers: [
29 | ...
30 | ],
31 | bootstrap: [...]
32 | })
33 | ```
34 |
35 | in your view (html)
36 | ```
37 |
38 | ```
39 |
40 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var inlineResources = require('./scripts/gulp/inline-resources');
3 | var sass = require('gulp-sass');
4 |
5 |
6 | gulp.task('copy-and-inline-resource', copyHtml);
7 |
8 | function copyHtml() {
9 | gulp.src('src/components/**/*.html')
10 | .pipe(gulp.dest('./dist/components')).on('end', copyAssets);
11 | }
12 |
13 | function copyAssets () {
14 | gulp.src('./src/assets/**/*')
15 | .pipe(gulp.dest('./dist/assets')).on('end', copyScss);
16 | }
17 | function copyScss () {
18 | gulp.src('./src/components/**/*.scss')
19 | .pipe(gulp.dest('./dist/components')).on('end', inlineResource);
20 | }
21 |
22 | function inlineResource() {
23 | inlineResources('./dist/components');
24 | }
25 |
26 | gulp.task('default', ['copy-and-inline-resource']);
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # Compiled binary addons (http://nodejs.org/api/addons.html)
20 | build/Release
21 |
22 | # Users Environment Variables
23 | .lock-wscript
24 |
25 | # OS generated files #
26 | .DS_Store
27 | ehthumbs.db
28 | Icon?
29 | Thumbs.db
30 |
31 | # Node Files #
32 | /node_modules
33 | /bower_components
34 |
35 | # Coverage #
36 | /coverage/
37 |
38 | # Typing #
39 | /src/typings/tsd/
40 | /typings/
41 | /tsd_typings/
42 |
43 | # Dist #
44 | /dist
45 | /public/__build__/
46 | /src/*/__build__/
47 | __build__/**
48 | .webpack.json
49 |
50 | # Doc #
51 | /doc/
52 |
53 | # IDE #
54 | .idea/
55 | *.swp
56 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | baseUrl: 'http://localhost:8080/',
3 |
4 | specs: [
5 | 'src/**/*.e2e-spec.js'
6 | ],
7 | exclude: [],
8 |
9 | framework: 'jasmine2',
10 |
11 | allScriptsTimeout: 110000,
12 |
13 | jasmineNodeOpts: {
14 | showTiming: true,
15 | showColors: true,
16 | isVerbose: false,
17 | includeStackTrace: false,
18 | defaultTimeoutInterval: 400000
19 | },
20 | directConnect: true,
21 |
22 | capabilities: {
23 | 'browserName': 'chrome'
24 | },
25 |
26 | onPrepare: function () {
27 | var SpecReporter = require('jasmine-spec-reporter');
28 | // add jasmine spec reporter
29 | jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: true}));
30 |
31 | browser.ignoreSynchronization = true;
32 | },
33 |
34 |
35 | /**
36 | * Angular 2 configuration
37 | *
38 | * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching
39 | * `rootEl`
40 | *
41 | */
42 | useAllAngular2AppRoots: true
43 | };
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Preboot team
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/karma-shim.js:
--------------------------------------------------------------------------------
1 | Error.stackTraceLimit = Infinity;
2 |
3 | require('core-js/client/shim');
4 | require('reflect-metadata');
5 |
6 | require('ts-helpers');
7 |
8 | require('zone.js/dist/zone');
9 | require('zone.js/dist/long-stack-trace-zone');
10 | require('zone.js/dist/proxy');
11 | require('zone.js/dist/sync-test');
12 | require('zone.js/dist/jasmine-patch');
13 | require('zone.js/dist/async-test');
14 | require('zone.js/dist/fake-async-test');
15 |
16 | /*
17 | Ok, this is kinda crazy. We can use the the context method on
18 | require that webpack created in order to tell webpack
19 | what files we actually want to require or import.
20 | Below, context will be a function/object with file names as keys.
21 | using that regex we are saying look in client/app and find
22 | any file that ends with '.spec.ts' and get its path. By passing in true
23 | we say do this recursively
24 | */
25 | var appContext = require.context('./src', true, /\.spec\.ts/);
26 |
27 | // get all the files, for each file, call the context function
28 | // that will require the file and load it up here. Context will
29 | // loop and require those spec files here
30 | appContext.keys().forEach(appContext);
31 |
32 | // Select BrowserDomAdapter.
33 | // see https://github.com/AngularClass/angular2-webpack-starter/issues/124
34 | // Somewhere in the test setup
35 | var testing = require('@angular/core/testing');
36 | var browser = require('@angular/platform-browser-dynamic/testing');
37 |
38 | testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
39 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 |
3 | var webpackConfig = require('./webpack.config');
4 |
5 | var ENV = process.env.npm_lifecycle_event;
6 | var isTestWatch = ENV === 'test-watch';
7 |
8 | module.exports = function (config) {
9 | var _config = {
10 |
11 | // base path that will be used to resolve all patterns (eg. files, exclude)
12 | basePath: '',
13 |
14 | // frameworks to use
15 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
16 | frameworks: ['jasmine'],
17 |
18 | // list of files / patterns to load in the browser
19 | files: [
20 | { pattern: './karma-shim.js', watched: false }
21 | ],
22 |
23 | // list of files to exclude
24 | exclude: [],
25 |
26 | // preprocess matching files before serving them to the browser
27 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
28 | preprocessors: {
29 | './karma-shim.js': ['webpack', 'sourcemap']
30 | },
31 |
32 | webpack: webpackConfig,
33 |
34 | webpackMiddleware: {
35 | // webpack-dev-middleware configuration
36 | // i. e.
37 | stats: 'errors-only'
38 | },
39 |
40 | webpackServer: {
41 | noInfo: true // please don't spam the console when running in karma!
42 | },
43 |
44 | // test results reporter to use
45 | // possible values: 'dots', 'progress', 'mocha'
46 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
47 | reporters: ["mocha"],
48 |
49 | // web server port
50 | port: 9876,
51 |
52 | // enable / disable colors in the output (reporters and logs)
53 | colors: true,
54 |
55 | // level of logging
56 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
57 | logLevel: config.LOG_INFO,
58 |
59 | // enable / disable watching file and executing tests whenever any file changes
60 | autoWatch: false,
61 |
62 | // start these browsers
63 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
64 | browsers: isTestWatch ? ['Chrome'] : ['PhantomJS'],
65 |
66 | // Continuous Integration mode
67 | // if true, Karma captures browsers, runs the tests and exits
68 | singleRun: true
69 | };
70 |
71 | if (!isTestWatch) {
72 | _config.reporters.push("coverage");
73 |
74 | _config.coverageReporter = {
75 | dir: 'coverage/',
76 | reporters: [{
77 | type: 'json',
78 | dir: 'coverage',
79 | subdir: 'json',
80 | file: 'coverage-final.json'
81 | }]
82 | };
83 | }
84 |
85 | config.set(_config);
86 |
87 | };
88 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-sdk",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "lint": "tslint --force \"src/**/*.ts\"",
7 | "pretest": "npm run lint",
8 | "test": "karma start",
9 | "posttest": "remap-istanbul -i coverage/json/coverage-final.json -o coverage/html -t html",
10 | "test-watch": "karma start --no-single-run --auto-watch",
11 | "build": "rimraf dist && ngc -p src/tsconfig.aot.json && gulp"
12 | },
13 | "dependencies": {
14 | "@angular/common": "2.3.0",
15 | "@angular/compiler": "2.2.4",
16 | "@angular/compiler-cli": "2.3.0",
17 | "@angular/core": "2.3.0",
18 | "@angular/forms": "2.3.0",
19 | "@angular/http": "2.3.0",
20 | "@angular/platform-browser": "2.3.0",
21 | "@angular/platform-browser-dynamic": "2.3.0",
22 | "@angular/router": "3.2.4",
23 | "angular-router-loader": "^0.4.0",
24 | "core-js": "^2.4.1",
25 | "reflect-metadata": "^0.1.3",
26 | "rxjs": "5.0.0-rc.4",
27 | "zone.js": "^0.7.2"
28 | },
29 | "devDependencies": {
30 | "@angular-cli/ast-tools": "^1.0.9",
31 | "@angularclass/hmr": "^1.0.1",
32 | "@angularclass/hmr-loader": "^3.0.2",
33 | "@ngtools/webpack": "^1.1.6",
34 | "@types/jasmine": "^2.2.29",
35 | "@types/node": "^6.0.38",
36 | "@types/selenium-webdriver": "2.53.33",
37 | "angular2-template-loader": "^0.6.0",
38 | "autoprefixer": "^6.3.2",
39 | "awesome-typescript-loader": "^2.2.4",
40 | "codelyzer": "1.0.0-beta.3",
41 | "copy-webpack-plugin": "^4.0.0",
42 | "css-loader": "^0.25.0",
43 | "extract-text-webpack-plugin": "^2.0.0-beta.4",
44 | "file-loader": "^0.9.0",
45 | "gulp": "^3.9.1",
46 | "gulp-sass": "^2.3.2",
47 | "html-loader": "^0.4.0",
48 | "html-webpack-plugin": "^2.8.1",
49 | "istanbul-instrumenter-loader": "^0.2.0",
50 | "jasmine-core": "^2.3.4",
51 | "jasmine-spec-reporter": "^2.4.0",
52 | "json-loader": "^0.5.3",
53 | "karma": "1.3.0",
54 | "karma-chrome-launcher": "^2.0.0",
55 | "karma-coverage": "^1.0.0",
56 | "karma-jasmine": "^1.0.2",
57 | "karma-mocha-reporter": "^2.0.3",
58 | "karma-phantomjs-launcher": "^1.0.0",
59 | "karma-remap-istanbul": "0.2.1",
60 | "karma-sourcemap-loader": "^0.3.7",
61 | "karma-webpack": "1.8.0",
62 | "node-sass": "^3.4.2",
63 | "null-loader": "0.1.1",
64 | "phantomjs-prebuilt": "^2.1.4",
65 | "postcss-loader": "^1.1.0",
66 | "protractor": "^4.0.10",
67 | "raw-loader": "0.5.1",
68 | "remap-istanbul": "^0.6.4",
69 | "rimraf": "^2.5.1",
70 | "sass-loader": "^4.0.0",
71 | "shelljs": "^0.7.0",
72 | "style-loader": "^0.13.0",
73 | "ts-helpers": "^1.1.1",
74 | "tslint": "^3.4.0",
75 | "tslint-loader": "^2.1.0",
76 | "typedoc": "^0.5.1",
77 | "typescript": "2.0.6",
78 | "url-loader": "^0.5.6",
79 | "webpack": "^2.1.0-beta.28",
80 | "webpack-dev-server": "2.1.0-beta.9"
81 | },
82 | "files": [
83 | "dist"
84 | ]
85 | }
86 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "class-name": true,
7 | "comment-format": [
8 | true,
9 | "check-space"
10 | ],
11 | "curly": true,
12 | "eofline": true,
13 | "forin": true,
14 | "indent": [
15 | true,
16 | "spaces"
17 | ],
18 | "label-position": true,
19 | "label-undefined": true,
20 | "max-line-length": [
21 | true,
22 | 140
23 | ],
24 | "member-access": false,
25 | "member-ordering": [
26 | true,
27 | "static-before-instance",
28 | "variables-before-functions"
29 | ],
30 | "no-arg": true,
31 | "no-bitwise": true,
32 | "no-console": [
33 | true,
34 | "debug",
35 | "info",
36 | "time",
37 | "timeEnd",
38 | "trace"
39 | ],
40 | "no-construct": true,
41 | "no-debugger": true,
42 | "no-duplicate-key": true,
43 | "no-duplicate-variable": true,
44 | "no-empty": false,
45 | "no-eval": true,
46 | "no-inferrable-types": true,
47 | "no-shadowed-variable": true,
48 | "no-string-literal": false,
49 | "no-switch-case-fall-through": true,
50 | "no-trailing-whitespace": true,
51 | "no-unused-expression": true,
52 | "no-unused-variable": true,
53 | "no-unreachable": true,
54 | "no-use-before-declare": true,
55 | "no-var-keyword": true,
56 | "object-literal-sort-keys": false,
57 | "one-line": [
58 | true,
59 | "check-open-brace",
60 | "check-catch",
61 | "check-else",
62 | "check-whitespace"
63 | ],
64 | "quotemark": [
65 | true,
66 | "single"
67 | ],
68 | "radix": true,
69 | "semicolon": [
70 | "always"
71 | ],
72 | "triple-equals": [
73 | true,
74 | "allow-null-check"
75 | ],
76 | "typedef-whitespace": [
77 | true,
78 | {
79 | "call-signature": "nospace",
80 | "index-signature": "nospace",
81 | "parameter": "nospace",
82 | "property-declaration": "nospace",
83 | "variable-declaration": "nospace"
84 | }
85 | ],
86 | "variable-name": false,
87 | "whitespace": [
88 | true,
89 | "check-branch",
90 | "check-decl",
91 | "check-operator",
92 | "check-separator",
93 | "check-type"
94 | ],
95 |
96 | "directive-selector-name": [true, "camelCase"],
97 | "component-selector-name": [true, "kebab-case"],
98 | "directive-selector-type": [true, "attribute"],
99 | "component-selector-type": [true, "element"],
100 | "use-input-property-decorator": true,
101 | "use-output-property-decorator": true,
102 | "use-host-property-decorator": true,
103 | "no-input-rename": true,
104 | "no-output-rename": true,
105 | "use-life-cycle-interface": true,
106 | "use-pipe-transform-interface": true,
107 | "component-class-suffix": true,
108 | "directive-class-suffix": true,
109 | "directive-selector-prefix": [true, "my"],
110 | "component-selector-prefix": [true, "my"],
111 | "pipe-naming": [true, "camelCase", "my"]
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/scripts/gulp/inline-resources.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 | const fs = require('fs');
4 | const path = require('path');
5 | const glob = require('glob');
6 | /**
7 | * Simple Promiseify function that takes a Node API and return a version that supports promises.
8 | * We use promises instead of synchronized functions to make the process less I/O bound and
9 | * faster. It also simplify the code.
10 | */
11 | function promiseify(fn) {
12 | return function() {
13 | const args = [].slice.call(arguments, 0);
14 | return new Promise((resolve, reject) => {
15 | fn.apply(this, args.concat([function (err, value) {
16 | if (err) {
17 | reject(err);
18 | } else {
19 | resolve(value);
20 | }
21 | }]));
22 | });
23 | };
24 | }
25 | const readFile = promiseify(fs.readFile);
26 | const writeFile = promiseify(fs.writeFile);
27 | function inlineResources(globs) {
28 | if (typeof globs == 'string') {
29 | globs = [globs];
30 | }
31 | /**
32 | * For every argument, inline the templates and styles under it and write the new file.
33 | */
34 | return Promise.all(globs.map(pattern => {
35 | if (pattern.indexOf('*') < 0) {
36 | // Argument is a directory target, add glob patterns to include every files.
37 | pattern = path.join(pattern, '**', '*');
38 | }
39 | const files = glob.sync(pattern, {})
40 | .filter(name => /\.js$/.test(name)); // Matches only JavaScript files.
41 | // Generate all files content with inlined templates.
42 | return Promise.all(files.map(filePath => {
43 | return readFile(filePath, 'utf-8')
44 | .then(content => inlineResourcesFromString(content, url => {
45 | return path.join(path.dirname(filePath), url);
46 | }))
47 | .then(content => writeFile(filePath, content))
48 | .catch(err => {
49 | console.error('An error occured: ', err);
50 | });
51 | }));
52 | }));
53 | }
54 | /**
55 | * Inline resources from a string content.
56 | * @param content {string} The source file's content.
57 | * @param urlResolver {Function} A resolver that takes a URL and return a path.
58 | * @returns {string} The content with resources inlined.
59 | */
60 | function inlineResourcesFromString(content, urlResolver) {
61 | // Curry through the inlining functions.
62 | return [
63 | inlineTemplate,
64 | inlineStyle,
65 | removeModuleId
66 | ].reduce((content, fn) => fn(content, urlResolver), content);
67 | }
68 | if (require.main === module) {
69 | inlineResources(process.argv.slice(2));
70 | }
71 | /**
72 | * Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and
73 | * replace with `template: ...` (with the content of the file included).
74 | * @param content {string} The source file's content.
75 | * @param urlResolver {Function} A resolver that takes a URL and return a path.
76 | * @return {string} The content with all templates inlined.
77 | */
78 | function inlineTemplate(content, urlResolver) {
79 | return content.replace(/templateUrl:\s*'([^']+?\.html)'/g, function(m, templateUrl) {
80 | const templateFile = urlResolver(templateUrl);
81 | const templateContent = fs.readFileSync(templateFile, 'utf-8');
82 | const shortenedTemplate = templateContent
83 | .replace(/([\n\r]\s*)+/gm, ' ')
84 | .replace(/"/g, '\\"');
85 | return `template: "${shortenedTemplate}"`;
86 | });
87 | }
88 | /**
89 | * Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and
90 | * replace with `styles: [...]` (with the content of the file included).
91 | * @param urlResolver {Function} A resolver that takes a URL and return a path.
92 | * @param content {string} The source file's content.
93 | * @return {string} The content with all styles inlined.
94 | */
95 | function inlineStyle(content, urlResolver) {
96 | return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function(m, styleUrls) {
97 | const urls = eval(styleUrls);
98 | return 'styles: ['
99 | + urls.map(styleUrl => {
100 | const styleFile = urlResolver(styleUrl);
101 | const styleContent = fs.readFileSync(styleFile, 'utf-8');
102 | const shortenedStyle = styleContent
103 | .replace(/([\n\r]\s*)+/gm, ' ')
104 | .replace(/"/g, '\\"');
105 | return `"${shortenedStyle}"`;
106 | })
107 | .join(',\n')
108 | + ']';
109 | });
110 | }
111 | /**
112 | * Remove every mention of `moduleId: module.id`.
113 | * @param content {string} The source file's content.
114 | * @returns {string} The content with all moduleId: mentions removed.
115 | */
116 | function removeModuleId(content) {
117 | return content.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, '');
118 | }
119 | module.exports = inlineResources;
120 | module.exports.inlineResourcesFromString = inlineResourcesFromString;
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | // Helper: root() is defined at the bottom
2 | var path = require('path');
3 | var webpack = require('webpack');
4 |
5 | // Webpack Plugins
6 | var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
7 | var autoprefixer = require('autoprefixer');
8 | var HtmlWebpackPlugin = require('html-webpack-plugin');
9 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
10 | var CopyWebpackPlugin = require('copy-webpack-plugin');
11 | var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
12 |
13 | /**
14 | * Env
15 | * Get npm lifecycle event to identify the environment
16 | */
17 | var ENV = process.env.npm_lifecycle_event;
18 | var isTestWatch = ENV === 'test-watch';
19 | var isTest = ENV === 'test' || isTestWatch;
20 | var isProd = ENV === 'build';
21 |
22 | module.exports = function makeWebpackConfig() {
23 | /**
24 | * Config
25 | * Reference: http://webpack.github.io/docs/configuration.html
26 | * This is the object where all configuration gets set
27 | */
28 | var config = {};
29 |
30 | /**
31 | * Devtool
32 | * Reference: http://webpack.github.io/docs/configuration.html#devtool
33 | * Type of sourcemap to use per build type
34 | */
35 | if (isProd) {
36 | config.devtool = 'source-map';
37 | }
38 | else if (isTest) {
39 | config.devtool = 'inline-source-map';
40 | }
41 | else {
42 | config.devtool = 'eval-source-map';
43 | }
44 |
45 | /**
46 | * Entry
47 | * Reference: http://webpack.github.io/docs/configuration.html#entry
48 | */
49 | config.entry = isTest ? {} : {
50 | 'polyfills': './src/polyfills.ts',
51 | 'vendor': './src/vendor.ts',
52 | 'app': './src/main.ts' // our angular app
53 | };
54 |
55 | /**
56 | * Output
57 | * Reference: http://webpack.github.io/docs/configuration.html#output
58 | */
59 | config.output = isTest ? {} : {
60 | path: root('dist'),
61 | publicPath: isProd ? '/' : 'http://localhost:8080/',
62 | filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
63 | chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
64 | };
65 |
66 | /**
67 | * Resolve
68 | * Reference: http://webpack.github.io/docs/configuration.html#resolve
69 | */
70 | config.resolve = {
71 | // only discover files that have those extensions
72 | extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
73 | };
74 |
75 | var atlOptions = '';
76 | if (isTest && !isTestWatch) {
77 | // awesome-typescript-loader needs to output inlineSourceMap for code coverage to work with source maps.
78 | atlOptions = 'inlineSourceMap=true&sourceMap=false';
79 | }
80 |
81 | /**
82 | * Loaders
83 | * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
84 | * List: http://webpack.github.io/docs/list-of-loaders.html
85 | * This handles most of the magic responsible for converting modules
86 | */
87 | config.module = {
88 | rules: [
89 | // Support for .ts files.
90 | {
91 | test: /\.ts$/,
92 | loaders: ['awesome-typescript-loader?' + atlOptions, 'angular2-template-loader', '@angularclass/hmr-loader', 'angular-router-loader'],
93 | exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/]
94 | },
95 |
96 | // copy those assets to output
97 | {
98 | test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
99 | loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
100 | },
101 |
102 | // Support for *.json files.
103 | {test: /\.json$/, loader: 'json-loader'},
104 |
105 | // Support for CSS as raw text
106 | // use 'null' loader in test mode (https://github.com/webpack/null-loader)
107 | // all css in src/style will be bundled in an external css file
108 | {
109 | test: /\.css$/,
110 | exclude: root('src', 'app'),
111 | loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader']})
112 | },
113 | // all css required in src/app files will be merged in js files
114 | {test: /\.css$/, include: root('src', 'app'), loader: 'raw-loader!postcss-loader'},
115 |
116 | // support for .scss files
117 | // use 'null' loader in test mode (https://github.com/webpack/null-loader)
118 | // all css in src/style will be bundled in an external css file
119 | {
120 | test: /\.(scss|sass)$/,
121 | exclude: root('src', 'app'),
122 | loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader', 'sass-loader']})
123 | },
124 | // all css required in src/app files will be merged in js files
125 | {test: /\.(scss|sass)$/, exclude: root('src', 'style'), loader: 'raw-loader!postcss-loader!sass-loader'},
126 |
127 | // support for .html as raw text
128 | // todo: change the loader to something that adds a hash to images
129 | {test: /\.html$/, loader: 'raw-loader', exclude: root('src', 'public')}
130 | ]
131 | };
132 |
133 | if (isTest && !isTestWatch) {
134 | // instrument only testing sources with Istanbul, covers ts files
135 | config.module.rules.push({
136 | test: /\.ts$/,
137 | enforce: 'post',
138 | include: path.resolve('src'),
139 | loader: 'istanbul-instrumenter-loader',
140 | exclude: [/\.spec\.ts$/, /\.e2e\.ts$/, /node_modules/]
141 | });
142 | }
143 |
144 | if (!isTest || !isTestWatch) {
145 | // tslint support
146 | config.module.rules.push({
147 | test: /\.ts$/,
148 | enforce: 'pre',
149 | loader: 'tslint-loader'
150 | });
151 | }
152 |
153 | /**
154 | * Plugins
155 | * Reference: http://webpack.github.io/docs/configuration.html#plugins
156 | * List: http://webpack.github.io/docs/list-of-plugins.html
157 | */
158 | config.plugins = [
159 | // Define env variables to help with builds
160 | // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
161 | new webpack.DefinePlugin({
162 | // Environment helpers
163 | 'process.env': {
164 | ENV: JSON.stringify(ENV)
165 | }
166 | }),
167 |
168 | // Workaround needed for angular 2 angular/angular#11580
169 | new webpack.ContextReplacementPlugin(
170 | // The (\\|\/) piece accounts for path separators in *nix and Windows
171 | /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
172 | root('./src') // location of your src
173 | ),
174 |
175 | // Tslint configuration for webpack 2
176 | new webpack.LoaderOptionsPlugin({
177 | options: {
178 | /**
179 | * Apply the tslint loader as pre/postLoader
180 | * Reference: https://github.com/wbuchwalter/tslint-loader
181 | */
182 | tslint: {
183 | emitErrors: false,
184 | failOnHint: false
185 | },
186 | /**
187 | * Sass
188 | * Reference: https://github.com/jtangelder/sass-loader
189 | * Transforms .scss files to .css
190 | */
191 | sassLoader: {
192 | //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]
193 | },
194 | /**
195 | * PostCSS
196 | * Reference: https://github.com/postcss/autoprefixer-core
197 | * Add vendor prefixes to your css
198 | */
199 | postcss: [
200 | autoprefixer({
201 | browsers: ['last 2 version']
202 | })
203 | ]
204 | }
205 | })
206 | ];
207 |
208 | if (!isTest && !isTestWatch) {
209 | config.plugins.push(
210 | new ForkCheckerPlugin(),
211 |
212 | // Generate common chunks if necessary
213 | // Reference: https://webpack.github.io/docs/code-splitting.html
214 | // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
215 | new CommonsChunkPlugin({
216 | name: ['vendor', 'polyfills']
217 | }),
218 |
219 | // Inject script and link tags into html files
220 | // Reference: https://github.com/ampedandwired/html-webpack-plugin
221 | new HtmlWebpackPlugin({
222 | template: './src/public/index.html',
223 | chunksSortMode: 'dependency'
224 | }),
225 |
226 | // Extract css files
227 | // Reference: https://github.com/webpack/extract-text-webpack-plugin
228 | // Disabled when in test mode or not in build mode
229 | new ExtractTextPlugin({filename: 'css/[name].[hash].css', disable: !isProd})
230 | );
231 | }
232 |
233 | // Add build specific plugins
234 | if (isProd) {
235 | config.plugins.push(
236 | // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
237 | // Only emit files when there are no errors
238 | new webpack.NoErrorsPlugin(),
239 |
240 | // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
241 | // // Dedupe modules in the output
242 | // new webpack.optimize.DedupePlugin(),
243 |
244 | // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
245 | // Minify all javascript, switch loaders to minimizing mode
246 | new webpack.optimize.UglifyJsPlugin({sourceMap: true, mangle: { keep_fnames: true }}),
247 |
248 | // Copy assets from the public folder
249 | // Reference: https://github.com/kevlened/copy-webpack-plugin
250 | new CopyWebpackPlugin([{
251 | from: root('src/public')
252 | }])
253 | );
254 | }
255 |
256 | /**
257 | * Dev server configuration
258 | * Reference: http://webpack.github.io/docs/configuration.html#devserver
259 | * Reference: http://webpack.github.io/docs/webpack-dev-server.html
260 | */
261 | config.devServer = {
262 | contentBase: './src/public',
263 | historyApiFallback: true,
264 | quiet: true,
265 | stats: 'minimal' // none (or false), errors-only, minimal, normal (or true) and verbose
266 | };
267 |
268 | return config;
269 | }();
270 |
271 | // Helper functions
272 | function root(args) {
273 | args = Array.prototype.slice.call(arguments, 0);
274 | return path.join.apply(path, [__dirname].concat(args));
275 | }
276 |
--------------------------------------------------------------------------------