Skip to content

Commit

Permalink
Migration to Angular 6, RxJs 6 and Webpack 4 (PatrickJS#2019)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
lanovoy authored Jul 9, 2018
1 parent 8936c61 commit 8ba05f7
Show file tree
Hide file tree
Showing 20 changed files with 6,777 additions and 20,917 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ___
# 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)


> 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),
> 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),
[Http](https://angular.io/docs/ts/latest/guide/server-communication.html),
[Services](https://gist.github.com/gdi2290/634101fec1671ee12b3e#_follow_@AngularClass_on_twitter),
[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).
Expand All @@ -32,7 +32,7 @@ ___
> If you're looking to learn TypeScript see [TypeStrong/learn-typescript](https://github.com/TypeStrong/learn-typescript)
> 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)
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.
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.
* Best practices in file and application organization for Angular.
* Ready to go build system using Webpack for working with TypeScript.
* Angular examples that are ready to go when experimenting with Angular.
Expand Down
75 changes: 42 additions & 33 deletions config/html-elements-plugin/index.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
function HtmlElementsPlugin(locations) {
this.locations = locations;
}

HtmlElementsPlugin.prototype.apply = function(compiler) {
var self = this;
compiler.plugin('compilation', function(compilation) {
compilation.options.htmlElements = compilation.options.htmlElements || {};

compilation.plugin('html-webpack-plugin-before-html-generation', function(htmlPluginData, callback) {
const locations = self.locations;

if (locations) {
const publicPath = htmlPluginData.assets.publicPath;

Object.getOwnPropertyNames(locations).forEach(function(loc) {
compilation.options.htmlElements[loc] = getHtmlElementString(locations[loc], publicPath);
});
}


callback(null, htmlPluginData);
});
});

};

const RE_ENDS_WITH_BS = /\/$/;

/**
Expand All @@ -49,8 +22,10 @@ function createTag(tagName, attrMap, publicPath) {
}

const attributes = Object.getOwnPropertyNames(attrMap)
.filter(function(name) { return name[0] !== '='; } )
.map(function(name) {
.filter(function (name) {
return name[0] !== '=';
})
.map(function (name) {
var value = attrMap[name];

if (publicPath) {
Expand Down Expand Up @@ -98,16 +73,50 @@ function createTag(tagName, attrMap, publicPath) {
*/
function getHtmlElementString(dataSource, publicPath) {
return Object.getOwnPropertyNames(dataSource)
.map(function(name) {
.map(function (name) {
if (Array.isArray(dataSource[name])) {
return dataSource[name].map(function(attrs) { return createTag(name, attrs, publicPath); } );
return dataSource[name].map(function (attrs) {
return createTag(name, attrs, publicPath);
});
} else {
return [ createTag(name, dataSource[name], publicPath) ];
return [createTag(name, dataSource[name], publicPath)];
}
})
.reduce(function(arr, curr) {
.reduce(function (arr, curr) {
return arr.concat(curr);
}, [])
.join('\n\t');
}

class HtmlElementsPlugin {
constructor(locations) {
this.locations = locations;
}

/* istanbul ignore next: this would be integration tests */
apply(compiler) {
compiler.hooks.compilation.tap('HtmlElementsPlugin', compilation => {
compilation.options.htmlElements = compilation.options.htmlElements || {};
compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tapAsync('HtmlElementsPlugin',
(htmlPluginData, callback) => {

const locations = this.locations;
if (locations) {
const publicPath = htmlPluginData.assets.publicPath;

Object.getOwnPropertyNames(locations).forEach(function (loc) {

compilation.options.htmlElements[loc] = getHtmlElementString(locations[loc], publicPath);
});
}

// return htmlPluginData;
callback(null, htmlPluginData);
}
);
});
}
}

module.exports = HtmlElementsPlugin;

9 changes: 7 additions & 2 deletions config/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ module.exports = function (config) {
/**
* enable / disable watching file and executing tests whenever any file changes
*/
autoWatch: false,
autoWatch: true,

/**
* start these browsers
Expand All @@ -134,7 +134,12 @@ module.exports = function (config) {
* Continuous Integration mode
* if true, Karma captures browsers, runs the tests and exits
*/
singleRun: true,
singleRun: false,

client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},

/**
* For slower machines you may need to have a longer browser
* wait time . Uncomment the line below if required.
Expand Down
5 changes: 0 additions & 5 deletions config/spec-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ require('zone.js/dist/jasmine-patch'); // put here since zone.js 0.6.14
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');

/**
* RxJS
*/
require('rxjs/Rx');

var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');

Expand Down
88 changes: 25 additions & 63 deletions config/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ const helpers = require('./helpers');
* problem with copy-webpack-plugin
*/
const DefinePlugin = require('webpack/lib/DefinePlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlElementsPlugin = require('./html-elements-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackInlineManifestPlugin = require('webpack-inline-manifest-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const ngcWebpack = require('ngc-webpack');
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;

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

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

const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA,options.metadata || {});
const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA, options.metadata || {});
const GTM_API_KEY = process.env.GTM_API_KEY || APP_CONFIG.gtmKey;

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

const entry = {
polyfills: './src/polyfills.browser.ts',
main: './src/main.browser.ts'
main: './src/main.browser.ts'
};

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

/**
* An array of extensions that should be used to resolve modules.
Expand Down Expand Up @@ -103,7 +101,6 @@ module.exports = function (options) {
* See: https://webpack.js.org/configuration/module/
*/
module: {

rules: [
...ngcWebpackConfig.loaders,

Expand Down Expand Up @@ -155,9 +152,7 @@ module.exports = function (options) {
test: /\.(eot|woff2?|svg|ttf)([\?]?.*)$/,
use: 'file-loader'
}

],

]
},

/**
Expand All @@ -177,40 +172,15 @@ module.exports = function (options) {
*/
// 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,
'AOT': METADATA.AOT,
ENV: JSON.stringify(METADATA.ENV),
HMR: METADATA.HMR,
AOT: METADATA.AOT,
'process.env.ENV': JSON.stringify(METADATA.ENV),
'process.env.NODE_ENV': JSON.stringify(METADATA.ENV),
'process.env.HMR': METADATA.HMR,
'process.env.HMR': METADATA.HMR
// 'FIREBASE_CONFIG': JSON.stringify(APP_CONFIG.firebase),
}),

/**
* Plugin: CommonsChunkPlugin
* Description: Shares common code between the pages.
* It identifies common modules and put them into a commons chunk.
*
* See: https://webpack.js.org/plugins/commons-chunk-plugin/
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
*/
new CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills']
}),

new CommonsChunkPlugin({
minChunks: Infinity,
name: 'inline'
}),
new CommonsChunkPlugin({
name: 'main',
async: 'common',
children: true,
minChunks: 2
}),


/**
* Plugin: CopyWebpackPlugin
* Description: Copy files and directories in webpack.
Expand All @@ -219,11 +189,9 @@ module.exports = function (options) {
*
* See: https://www.npmjs.com/package/copy-webpack-plugin
*/
new CopyWebpackPlugin([
{ from: 'src/assets', to: 'assets' },
{ from: 'src/meta'}
],
isProd ? { ignore: [ 'mock-data/**/*' ] } : undefined
new CopyWebpackPlugin(
[{ from: 'src/assets', to: 'assets' }, { from: 'src/meta' }],
isProd ? { ignore: ['mock-data/**/*'] } : undefined
),

/*
Expand All @@ -237,22 +205,24 @@ module.exports = function (options) {
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: function (a, b) {
const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];
chunksSortMode: function(a, b) {
const entryPoints = ['inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'main'];
return entryPoints.indexOf(a.names[0]) - entryPoints.indexOf(b.names[0]);
},
metadata: METADATA,
gtmKey: GTM_API_KEY,
inject: 'body',
xhtml: true,
minify: isProd ? {
caseSensitive: true,
collapseWhitespace: true,
keepClosingSlash: true
} : false
minify: isProd
? {
caseSensitive: true,
collapseWhitespace: true,
keepClosingSlash: true
}
: false
}),

/**
/**
* Plugin: ScriptExtHtmlWebpackPlugin
* Description: Enhances html-webpack-plugin functionality
* with different deployment options for your scripts including:
Expand Down Expand Up @@ -292,22 +262,15 @@ module.exports = function (options) {
headTags: require('./head-config.common')
}),

/**
* Plugin LoaderOptionsPlugin (experimental)
*
* See: https://gist.github.com/sokra/27b24881210b56bbaff7
*/
new LoaderOptionsPlugin({}),

new ngcWebpack.NgcWebpackPlugin(ngcWebpackConfig.plugin),
new AngularCompilerPlugin(ngcWebpackConfig.plugin),

/**
* Plugin: WebpackInlineManifestPlugin
* Inline Webpack's manifest.js in index.html
*
* https://github.com/almothafar/webpack-inline-manifest-plugin
*/
new WebpackInlineManifestPlugin(),
new WebpackInlineManifestPlugin()
],

/**
Expand All @@ -324,6 +287,5 @@ module.exports = function (options) {
clearImmediate: false,
setImmediate: false
}

};
};
Loading

0 comments on commit 8ba05f7

Please sign in to comment.