Skip to content
This repository was archived by the owner on Jun 25, 2019. It is now read-only.

Commit 741240a

Browse files
author
Felix Gladisch
committed
🚀 feat/chore: angular 4.3, tslint, aot, webpack 3 and more
1 parent fbf421f commit 741240a

25 files changed

+5618
-156
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Node files
88
/node_modules
99
npm-debug.log
10-
yarn.lock
10+
yarn-error.log
1111

1212
# OS generated files
1313
.DS_Store

README.md

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@
33
[![Build Status](https://travis-ci.org/fgladisch/angular2-webpack-seed.svg?branch=master)](https://travis-ci.org/fgladisch/angular2-webpack-seed)
44

55
This is a minimalistic Angular 2+ seed project, featuring:
6-
* [TypeScript 2.2](https://www.typescriptlang.org)
6+
* [Angular 4.3](https://www.typescriptlang.org)
7+
* [TypeScript 2.4](https://www.typescriptlang.org)
8+
* [Bootstrap 4 (Beta)](http://v4-alpha.getbootstrap.com)
9+
* [Ahead-of-Time Compilation](https://angular.io/guide/aot-compiler)
10+
* [Tree Shaking](https://webpack.js.org/guides/tree-shaking)
711
* [Sass](http://sass-lang.com)
8-
* [Bootstrap 4](http://v4-alpha.getbootstrap.com)
912
* [ng-bootstrap](https://github.com/ng-bootstrap/ng-bootstrap)
1013
* [ngx-translate](https://github.com/ngx-translate)
1114
* [webpack](https://webpack.github.io)
1215
* [Karma](https://karma-runner.github.io)
1316
* [Jasmine](http://jasmine.github.io)
1417
* [@types](https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files)
18+
* [TSLint](https://github.com/palantir/tslint)
19+
* [Codelyzer](https://github.com/mgechev/codelyzer)
1520

1621
This seed follows the [Angular Style Guide](https://angular.io/docs/ts/latest/guide/style-guide.html).
1722

@@ -21,30 +26,50 @@ This seed follows the [Angular Style Guide](https://angular.io/docs/ts/latest/gu
2126

2227
```bash
2328
npm install
29+
# or
30+
yarn
2431
```
2532

26-
### Run development server
33+
### Development server
2734

2835
Use the following command to start a local development server which will display the application at [http://localhost:3000](http://localhost:3000).
2936

3037
```bash
3138
npm start
39+
# or
40+
yarn start
3241
```
3342

34-
### Run tests
43+
### Test your code
3544

3645
The following command will run your unit tests with [Karma](https://karma-runner.github.io).
3746

3847
```bash
3948
npm test
49+
# or
50+
yarn test
51+
```
52+
53+
### Analyze your code with TSLint
54+
55+
Run [TSLint](https://github.com/palantir/tslint) with rules based on the [Angular Style Guide](https://angular.io/docs/ts/latest/guide/style-guide.html) with this command.
56+
57+
```bash
58+
npm run lint
59+
# or
60+
yarn lint
4061
```
4162

4263
### Build for production
4364

4465
Production files are located in `dist`.
4566

67+
This project uses [Ahead-of-Time Compilation](https://angular.io/guide/aot-compiler) and [Tree Shaking](https://webpack.js.org/guides/tree-shaking) for much smaller production files. Files over a threshold of 1KB are also gzipped, which results in approximately 150KB for all JS/HTML/CSS in this project.
68+
4669
```bash
4770
npm run build
71+
# or
72+
yarn build
4873
```
4974

5075
# License

config/helpers.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
const path = require('path');
2-
const _root = process.cwd();
1+
const path = require('path')
2+
const _root = process.cwd()
33

44
function root(args) {
5-
args = Array.prototype.slice.call(arguments, 0);
6-
return path.join.apply(path, [_root].concat(args));
5+
args = Array.prototype.slice.call(arguments, 0)
6+
return path.join.apply(path, [_root].concat(args))
77
}
88

9-
exports.root = root;
9+
exports.root = root

config/karma-shim.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,32 @@
1414
* file for our client, when we run test, it will compile and bundle them
1515
* all here! Crazy huh. So we need to do some setup
1616
*/
17-
Error.stackTraceLimit = Infinity;
17+
Error.stackTraceLimit = Infinity
1818

19-
require('core-js/es6');
20-
require('core-js/es7/reflect');
19+
require('core-js/es6')
20+
require('core-js/es7/reflect')
2121

2222
// Typescript emit helpers polyfill
23-
require('ts-helpers');
23+
require('ts-helpers')
2424

25-
require('zone.js/dist/zone');
26-
require('zone.js/dist/long-stack-trace-zone');
27-
require('zone.js/dist/proxy'); // since zone.js 0.6.15
28-
require('zone.js/dist/sync-test');
29-
require('zone.js/dist/jasmine-patch'); // put here since zone.js 0.6.14
30-
require('zone.js/dist/async-test');
31-
require('zone.js/dist/fake-async-test');
25+
require('zone.js/dist/zone')
26+
require('zone.js/dist/long-stack-trace-zone')
27+
require('zone.js/dist/proxy') // since zone.js 0.6.15
28+
require('zone.js/dist/sync-test')
29+
require('zone.js/dist/jasmine-patch') // put here since zone.js 0.6.14
30+
require('zone.js/dist/async-test')
31+
require('zone.js/dist/fake-async-test')
3232

3333
// RxJS
34-
require('rxjs/Rx');
34+
require('rxjs/Rx')
3535

36-
const testing = require('@angular/core/testing');
37-
const browser = require('@angular/platform-browser-dynamic/testing');
36+
const testing = require('@angular/core/testing')
37+
const browser = require('@angular/platform-browser-dynamic/testing')
3838

3939
testing.TestBed.initTestEnvironment(
4040
browser.BrowserDynamicTestingModule,
4141
browser.platformBrowserDynamicTesting()
42-
);
42+
)
4343

4444
/*
4545
* Ok, this is kinda crazy. We can use the context method on
@@ -50,16 +50,16 @@ testing.TestBed.initTestEnvironment(
5050
* any file that ends with spec.ts and get its path. By passing in true
5151
* we say do this recursively
5252
*/
53-
const testContext = require.context('../src', true, /\.spec\.ts/);
53+
const testContext = require.context('../src', true, /\.spec\.ts/)
5454

5555
/*
5656
* get all the files, for each file, call the context function
5757
* that will require the file and load it up here. Context will
5858
* loop and require those spec files here
5959
*/
6060
function requireAll(requireContext) {
61-
return requireContext.keys().map(requireContext);
61+
return requireContext.keys().map(requireContext)
6262
}
6363

6464
// requires and returns all modules that match
65-
const modules = requireAll(testContext);
65+
requireAll(testContext)

config/karma.conf.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ module.exports = function (config) {
99

1010
// Karma will require() these plugins
1111
plugins: [
12-
"karma-jasmine",
13-
"karma-mocha-reporter",
14-
"karma-phantomjs-launcher",
15-
"karma-sourcemap-loader",
16-
"karma-webpack"
12+
'karma-jasmine',
13+
'karma-mocha-reporter',
14+
'karma-phantomjs-launcher',
15+
'karma-sourcemap-loader',
16+
'karma-webpack'
1717
],
1818

1919
/*

config/webpack.common.js

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
const webpack = require('webpack');
2-
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
3-
const ExtractTextPlugin = require('extract-text-webpack-plugin');
4-
const CopyWebpackPlugin = require('copy-webpack-plugin');
5-
const HtmlWebpackPlugin = require('html-webpack-plugin');
6-
const helpers = require('./helpers');
1+
const webpack = require('webpack')
2+
const { AotPlugin } = require('@ngtools/webpack')
3+
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin')
4+
const ExtractTextPlugin = require('extract-text-webpack-plugin')
5+
const CopyWebpackPlugin = require('copy-webpack-plugin')
6+
const HtmlWebpackPlugin = require('html-webpack-plugin')
7+
const helpers = require('./helpers')
78

8-
module.exports = function() {
9+
module.exports = () => {
10+
11+
const isProd = process.env.ENV === 'production'
912

1013
return {
1114

15+
// Array of extensions that will be used to resolve modules
1216
resolve: {
1317
extensions: ['.ts', '.js', '.json'],
1418
modules: [
@@ -17,12 +21,11 @@ module.exports = function() {
1721
],
1822
},
1923

20-
// Entry points the bundles
24+
// The entry point for the bundle
2125
entry: {
2226
'polyfills': helpers.root('src', 'polyfills.ts'),
23-
'vendor': helpers.root('src', 'vendor.ts'),
2427
'app': [
25-
helpers.root('src', 'main.ts'),
28+
helpers.root('src', isProd ? 'main-aot.ts' : 'main-jit.ts'),
2629
helpers.root('src', 'assets', 'styles', 'main.scss')
2730
]
2831
},
@@ -32,14 +35,14 @@ module.exports = function() {
3235
// Compiles all .ts files
3336
{
3437
test: /\.ts$/,
35-
loaders: ['awesome-typescript-loader?silent=true', 'angular2-template-loader'],
38+
loaders: isProd ? ['@ngtools/webpack'] : ['awesome-typescript-loader?silent=true', 'angular2-template-loader'],
3639
exclude: /\.spec\.ts$/
3740
},
3841
// Injects all html templates into their components and loads referenced assets
3942
{
4043
test: /\.html$/,
4144
loader: 'html-loader',
42-
exclude: helpers.root('src/index.html')
45+
exclude: helpers.root('src', 'index.html')
4346
},
4447
// Copies all images and fonts into dist/assets
4548
{
@@ -67,19 +70,23 @@ module.exports = function() {
6770
},
6871

6972
plugins: [
73+
new AotPlugin({
74+
tsConfigPath: helpers.root('tsconfig-aot.json'),
75+
entryModule: helpers.root('src', 'app', 'app.module#AppModule')
76+
}),
7077
// File name for the extracted styles
71-
new ExtractTextPlugin('[name].css'),
78+
new ExtractTextPlugin(`[name]${isProd ? '.[hash]' : ''}.css`),
7279
// Identifies common modules and puts them into a commons chunk
7380
new webpack.optimize.CommonsChunkPlugin({
74-
name: ['app', 'vendor', 'polyfills']
81+
name: ['app', 'polyfills']
7582
}),
7683
// Provides context to Angular's use of System.import
7784
// See: https://github.com/AngularClass/angular2-webpack-starter/issues/993#issuecomment-283423040
7885
new ContextReplacementPlugin(
7986
/angular(\\|\/)core(\\|\/)@angular/,
8087
helpers.root('src')
8188
),
82-
// Generates an HTML5 file that includes all webpack bundles
89+
// Generates a HTML5 file that includes all webpack bundles
8390
new HtmlWebpackPlugin({
8491
template: helpers.root('src', 'index.html'),
8592
favicon: helpers.root('src', 'favicon.ico')
@@ -95,6 +102,6 @@ module.exports = function() {
95102
hints: false
96103
}
97104

98-
};
105+
}
99106

100-
};
107+
}

config/webpack.dev.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
const webpack = require('webpack');
2-
const webpackMerge = require('webpack-merge');
3-
const commonConfig = require('./webpack.common.js');
1+
const webpack = require('webpack')
2+
const webpackMerge = require('webpack-merge')
3+
const commonConfig = require('./webpack.common.js')
44

5-
const ENV = process.env.NODE_ENV = process.env.ENV = 'development';
5+
const ENV = process.env.NODE_ENV = process.env.ENV = 'development'
66

77
module.exports = webpackMerge(commonConfig(), {
88

@@ -28,4 +28,4 @@ module.exports = webpackMerge(commonConfig(), {
2828
})
2929
]
3030

31-
});
31+
})

config/webpack.prod.js

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,59 @@
1-
const webpack = require('webpack');
2-
const webpackMerge = require('webpack-merge');
3-
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
4-
const commonConfig = require('./webpack.common.js');
5-
const helpers = require('./helpers');
1+
const webpack = require('webpack')
2+
const webpackMerge = require('webpack-merge')
3+
const CompressionPlugin = require('compression-webpack-plugin');
4+
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin')
5+
const commonConfig = require('./webpack.common.js')
6+
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
7+
const helpers = require('./helpers')
68

7-
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
9+
const ENV = process.env.NODE_ENV = process.env.ENV = 'production'
810

911
module.exports = webpackMerge(commonConfig(), {
1012

1113
output: {
1214
path: helpers.root('dist'),
13-
filename: '[name].js',
14-
chunkFilename: '[id].chunk.js'
15+
filename: '[name].[hash].js',
16+
chunkFilename: '[id].[hash].chunk.js'
1517
},
1618

1719
plugins: [
20+
new LoaderOptionsPlugin({
21+
minimize: true,
22+
debug: false,
23+
options: {
24+
htmlLoader: {
25+
minimize: false
26+
}
27+
}
28+
}),
1829
new UglifyJsPlugin({
30+
beautify: false,
31+
output: {
32+
comments: false
33+
},
1934
mangle: {
20-
keep_fnames: true
21-
}
35+
screw_ie8: true
36+
},
37+
compress: {
38+
screw_ie8: true,
39+
warnings: false,
40+
conditionals: true,
41+
unused: true,
42+
comparisons: true,
43+
sequences: true,
44+
dead_code: true,
45+
evaluate: true,
46+
if_return: true,
47+
join_vars: true,
48+
negate_iife: false
49+
},
50+
}),
51+
new CompressionPlugin({
52+
asset: '[path].gz[query]',
53+
algorithm: 'gzip',
54+
test: /\.js$|\.css$|\.html$/,
55+
threshold: 10240,
56+
minRatio: 0.8
2257
}),
2358
new webpack.DefinePlugin({
2459
'process.env': {
@@ -27,4 +62,4 @@ module.exports = webpackMerge(commonConfig(), {
2762
})
2863
]
2964

30-
});
65+
})

0 commit comments

Comments
 (0)