Skip to content

Commit 8ba05f7

Browse files
authored
Migration to Angular 6, RxJs 6 and Webpack 4 (#2019)
* AoT and JIT builds complete successfully * Upgraded @ngtools/webpack to latest beta. * Fixed warnings, removed deprecated plugins, replaced npm run clean:dist and clean:aot with direct rimraf calls to speed up the script execution * Govinda Alwani : Upgraded HtmlElementsPlugin to support webpack 4. * Updateing angular 6 and ficing webpack issues and rxjs issue. * using RXJS lettable * Update README.md * Updating Angular latest and webpack latest * Updated lock file * Corrected package-lock.json * Got rid of outdated ngcWebpackPlugin. Instead using native AngularCompilerPlugin directly. * Added RxJs TSLint rules * Clean-up, refactoring, re-enabled disabled TSLint rules * Partially reverting previous change as it causes one of e2e tests to fail for no apparent reason... Have to be investigated.
1 parent 8936c61 commit 8ba05f7

20 files changed

+6777
-20917
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ ___
2222
# Angular Webpack Starter [![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)
2323

2424

25-
> An Angular starter kit featuring [Angular 5](https://angular.io), [Ahead of Time Compile](https://angular.io/docs/ts/latest/cookbook/aot-compiler.html), [Router](https://angular.io/docs/ts/latest/guide/router.html), [Forms](https://angular.io/docs/ts/latest/guide/forms.html),
25+
> An Angular starter kit featuring [Angular 6](https://angular.io), [Ahead of Time Compile](https://angular.io/docs/ts/latest/cookbook/aot-compiler.html), [Router](https://angular.io/docs/ts/latest/guide/router.html), [Forms](https://angular.io/docs/ts/latest/guide/forms.html),
2626
[Http](https://angular.io/docs/ts/latest/guide/server-communication.html),
2727
[Services](https://gist.github.com/gdi2290/634101fec1671ee12b3e#_follow_@AngularClass_on_twitter),
2828
[Tests](https://angular.io/docs/ts/latest/guide/testing.html), [E2E](https://angular.github.io/protractor/#/faq#what-s-the-difference-between-karma-and-protractor-when-do-i-use-which-)), [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/), [@types](https://www.npmjs.com/~types), [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 [Tipe](https://tipe.io).
@@ -32,7 +32,7 @@ ___
3232
> If you're looking to learn TypeScript see [TypeStrong/learn-typescript](https://github.com/TypeStrong/learn-typescript)
3333
> If you're looking for something easier to get started with then see the angular-seed that I also maintain [gdi2290/angular-seed](https://github.com/gdi2290/angular-seed)
3434
35-
This seed repo serves as an Angular starter for anyone looking to get up and running with Angular and TypeScript fast. Using a [Webpack 3](https://webpack.js.org) 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.
35+
This seed repo serves as an Angular starter for anyone looking to get up and running with Angular and TypeScript fast. Using a [Webpack 4](https://webpack.js.org) 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.
3636
* Best practices in file and application organization for Angular.
3737
* Ready to go build system using Webpack for working with TypeScript.
3838
* Angular examples that are ready to go when experimenting with Angular.

config/html-elements-plugin/index.js

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,3 @@
1-
function HtmlElementsPlugin(locations) {
2-
this.locations = locations;
3-
}
4-
5-
HtmlElementsPlugin.prototype.apply = function(compiler) {
6-
var self = this;
7-
compiler.plugin('compilation', function(compilation) {
8-
compilation.options.htmlElements = compilation.options.htmlElements || {};
9-
10-
compilation.plugin('html-webpack-plugin-before-html-generation', function(htmlPluginData, callback) {
11-
const locations = self.locations;
12-
13-
if (locations) {
14-
const publicPath = htmlPluginData.assets.publicPath;
15-
16-
Object.getOwnPropertyNames(locations).forEach(function(loc) {
17-
compilation.options.htmlElements[loc] = getHtmlElementString(locations[loc], publicPath);
18-
});
19-
}
20-
21-
22-
callback(null, htmlPluginData);
23-
});
24-
});
25-
26-
};
27-
281
const RE_ENDS_WITH_BS = /\/$/;
292

303
/**
@@ -49,8 +22,10 @@ function createTag(tagName, attrMap, publicPath) {
4922
}
5023

5124
const attributes = Object.getOwnPropertyNames(attrMap)
52-
.filter(function(name) { return name[0] !== '='; } )
53-
.map(function(name) {
25+
.filter(function (name) {
26+
return name[0] !== '=';
27+
})
28+
.map(function (name) {
5429
var value = attrMap[name];
5530

5631
if (publicPath) {
@@ -98,16 +73,50 @@ function createTag(tagName, attrMap, publicPath) {
9873
*/
9974
function getHtmlElementString(dataSource, publicPath) {
10075
return Object.getOwnPropertyNames(dataSource)
101-
.map(function(name) {
76+
.map(function (name) {
10277
if (Array.isArray(dataSource[name])) {
103-
return dataSource[name].map(function(attrs) { return createTag(name, attrs, publicPath); } );
78+
return dataSource[name].map(function (attrs) {
79+
return createTag(name, attrs, publicPath);
80+
});
10481
} else {
105-
return [ createTag(name, dataSource[name], publicPath) ];
82+
return [createTag(name, dataSource[name], publicPath)];
10683
}
10784
})
108-
.reduce(function(arr, curr) {
85+
.reduce(function (arr, curr) {
10986
return arr.concat(curr);
11087
}, [])
11188
.join('\n\t');
11289
}
90+
91+
class HtmlElementsPlugin {
92+
constructor(locations) {
93+
this.locations = locations;
94+
}
95+
96+
/* istanbul ignore next: this would be integration tests */
97+
apply(compiler) {
98+
compiler.hooks.compilation.tap('HtmlElementsPlugin', compilation => {
99+
compilation.options.htmlElements = compilation.options.htmlElements || {};
100+
compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tapAsync('HtmlElementsPlugin',
101+
(htmlPluginData, callback) => {
102+
103+
const locations = this.locations;
104+
if (locations) {
105+
const publicPath = htmlPluginData.assets.publicPath;
106+
107+
Object.getOwnPropertyNames(locations).forEach(function (loc) {
108+
109+
compilation.options.htmlElements[loc] = getHtmlElementString(locations[loc], publicPath);
110+
});
111+
}
112+
113+
// return htmlPluginData;
114+
callback(null, htmlPluginData);
115+
}
116+
);
117+
});
118+
}
119+
}
120+
113121
module.exports = HtmlElementsPlugin;
122+

config/karma.conf.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ module.exports = function (config) {
113113
/**
114114
* enable / disable watching file and executing tests whenever any file changes
115115
*/
116-
autoWatch: false,
116+
autoWatch: true,
117117

118118
/**
119119
* start these browsers
@@ -134,7 +134,12 @@ module.exports = function (config) {
134134
* Continuous Integration mode
135135
* if true, Karma captures browsers, runs the tests and exits
136136
*/
137-
singleRun: true,
137+
singleRun: false,
138+
139+
client: {
140+
clearContext: false // leave Jasmine Spec Runner output visible in browser
141+
},
142+
138143
/**
139144
* For slower machines you may need to have a longer browser
140145
* wait time . Uncomment the line below if required.

config/spec-bundle.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ require('zone.js/dist/jasmine-patch'); // put here since zone.js 0.6.14
2424
require('zone.js/dist/async-test');
2525
require('zone.js/dist/fake-async-test');
2626

27-
/**
28-
* RxJS
29-
*/
30-
require('rxjs/Rx');
31-
3227
var testing = require('@angular/core/testing');
3328
var browser = require('@angular/platform-browser-dynamic/testing');
3429

config/webpack.common.js

Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@ const helpers = require('./helpers');
1010
* problem with copy-webpack-plugin
1111
*/
1212
const DefinePlugin = require('webpack/lib/DefinePlugin');
13-
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
1413
const CopyWebpackPlugin = require('copy-webpack-plugin');
1514
const HtmlElementsPlugin = require('./html-elements-plugin');
1615
const HtmlWebpackPlugin = require('html-webpack-plugin');
1716
const WebpackInlineManifestPlugin = require('webpack-inline-manifest-plugin');
18-
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
1917
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
20-
const ngcWebpack = require('ngc-webpack');
18+
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
2119

2220
const buildUtils = require('./build-utils');
2321

@@ -26,19 +24,19 @@ const buildUtils = require('./build-utils');
2624
*
2725
* See: https://webpack.js.org/configuration/
2826
*/
29-
module.exports = function (options) {
27+
module.exports = function(options) {
3028
const isProd = options.env === 'production';
3129
const APP_CONFIG = require(process.env.ANGULAR_CONF_FILE || (isProd ? './config.prod.json' : './config.dev.json'));
3230

33-
const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA,options.metadata || {});
31+
const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA, options.metadata || {});
3432
const GTM_API_KEY = process.env.GTM_API_KEY || APP_CONFIG.gtmKey;
3533

3634
const ngcWebpackConfig = buildUtils.ngcWebpackSetup(isProd, METADATA);
3735
const supportES2015 = buildUtils.supportES2015(METADATA.tsConfigPath);
3836

3937
const entry = {
4038
polyfills: './src/polyfills.browser.ts',
41-
main: './src/main.browser.ts'
39+
main: './src/main.browser.ts'
4240
};
4341

4442
Object.assign(ngcWebpackConfig.plugin, {
@@ -61,7 +59,7 @@ module.exports = function (options) {
6159
* See: https://webpack.js.org/configuration/resolve/
6260
*/
6361
resolve: {
64-
mainFields: [ ...(supportES2015 ? ['es2015'] : []), 'browser', 'module', 'main' ],
62+
mainFields: [...(supportES2015 ? ['es2015'] : []), 'browser', 'module', 'main'],
6563

6664
/**
6765
* An array of extensions that should be used to resolve modules.
@@ -103,7 +101,6 @@ module.exports = function (options) {
103101
* See: https://webpack.js.org/configuration/module/
104102
*/
105103
module: {
106-
107104
rules: [
108105
...ngcWebpackConfig.loaders,
109106

@@ -155,9 +152,7 @@ module.exports = function (options) {
155152
test: /\.(eot|woff2?|svg|ttf)([\?]?.*)$/,
156153
use: 'file-loader'
157154
}
158-
159-
],
160-
155+
]
161156
},
162157

163158
/**
@@ -177,40 +172,15 @@ module.exports = function (options) {
177172
*/
178173
// NOTE: when adding more properties make sure you include them in custom-typings.d.ts
179174
new DefinePlugin({
180-
'ENV': JSON.stringify(METADATA.ENV),
181-
'HMR': METADATA.HMR,
182-
'AOT': METADATA.AOT,
175+
ENV: JSON.stringify(METADATA.ENV),
176+
HMR: METADATA.HMR,
177+
AOT: METADATA.AOT,
183178
'process.env.ENV': JSON.stringify(METADATA.ENV),
184179
'process.env.NODE_ENV': JSON.stringify(METADATA.ENV),
185-
'process.env.HMR': METADATA.HMR,
180+
'process.env.HMR': METADATA.HMR
186181
// 'FIREBASE_CONFIG': JSON.stringify(APP_CONFIG.firebase),
187182
}),
188183

189-
/**
190-
* Plugin: CommonsChunkPlugin
191-
* Description: Shares common code between the pages.
192-
* It identifies common modules and put them into a commons chunk.
193-
*
194-
* See: https://webpack.js.org/plugins/commons-chunk-plugin/
195-
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
196-
*/
197-
new CommonsChunkPlugin({
198-
name: 'polyfills',
199-
chunks: ['polyfills']
200-
}),
201-
202-
new CommonsChunkPlugin({
203-
minChunks: Infinity,
204-
name: 'inline'
205-
}),
206-
new CommonsChunkPlugin({
207-
name: 'main',
208-
async: 'common',
209-
children: true,
210-
minChunks: 2
211-
}),
212-
213-
214184
/**
215185
* Plugin: CopyWebpackPlugin
216186
* Description: Copy files and directories in webpack.
@@ -219,11 +189,9 @@ module.exports = function (options) {
219189
*
220190
* See: https://www.npmjs.com/package/copy-webpack-plugin
221191
*/
222-
new CopyWebpackPlugin([
223-
{ from: 'src/assets', to: 'assets' },
224-
{ from: 'src/meta'}
225-
],
226-
isProd ? { ignore: [ 'mock-data/**/*' ] } : undefined
192+
new CopyWebpackPlugin(
193+
[{ from: 'src/assets', to: 'assets' }, { from: 'src/meta' }],
194+
isProd ? { ignore: ['mock-data/**/*'] } : undefined
227195
),
228196

229197
/*
@@ -237,22 +205,24 @@ module.exports = function (options) {
237205
new HtmlWebpackPlugin({
238206
template: 'src/index.html',
239207
title: METADATA.title,
240-
chunksSortMode: function (a, b) {
241-
const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];
208+
chunksSortMode: function(a, b) {
209+
const entryPoints = ['inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'main'];
242210
return entryPoints.indexOf(a.names[0]) - entryPoints.indexOf(b.names[0]);
243211
},
244212
metadata: METADATA,
245213
gtmKey: GTM_API_KEY,
246214
inject: 'body',
247215
xhtml: true,
248-
minify: isProd ? {
249-
caseSensitive: true,
250-
collapseWhitespace: true,
251-
keepClosingSlash: true
252-
} : false
216+
minify: isProd
217+
? {
218+
caseSensitive: true,
219+
collapseWhitespace: true,
220+
keepClosingSlash: true
221+
}
222+
: false
253223
}),
254224

255-
/**
225+
/**
256226
* Plugin: ScriptExtHtmlWebpackPlugin
257227
* Description: Enhances html-webpack-plugin functionality
258228
* with different deployment options for your scripts including:
@@ -292,22 +262,15 @@ module.exports = function (options) {
292262
headTags: require('./head-config.common')
293263
}),
294264

295-
/**
296-
* Plugin LoaderOptionsPlugin (experimental)
297-
*
298-
* See: https://gist.github.com/sokra/27b24881210b56bbaff7
299-
*/
300-
new LoaderOptionsPlugin({}),
301-
302-
new ngcWebpack.NgcWebpackPlugin(ngcWebpackConfig.plugin),
265+
new AngularCompilerPlugin(ngcWebpackConfig.plugin),
303266

304267
/**
305268
* Plugin: WebpackInlineManifestPlugin
306269
* Inline Webpack's manifest.js in index.html
307270
*
308271
* https://github.com/almothafar/webpack-inline-manifest-plugin
309272
*/
310-
new WebpackInlineManifestPlugin(),
273+
new WebpackInlineManifestPlugin()
311274
],
312275

313276
/**
@@ -324,6 +287,5 @@ module.exports = function (options) {
324287
clearImmediate: false,
325288
setImmediate: false
326289
}
327-
328290
};
329291
};

0 commit comments

Comments
 (0)