From 04a57b7b9817ff62f64bd7d0ec1498917e9ffecf Mon Sep 17 00:00:00 2001 From: nixa <4dmitr@gmail.com> Date: Mon, 19 Sep 2016 16:51:05 +0300 Subject: [PATCH] chore(build): dependencies and config updates --- config/helpers.js | 10 +- config/webpack.common.js | 541 +++++++++++++++++++++------------------ config/webpack.dev.js | 252 +++++++++--------- config/webpack.prod.js | 376 ++++++++++++++------------- package.json | 30 +-- src/app/app.module.ts | 31 ++- src/app/app.service.ts | 11 +- src/app/environment.ts | 4 +- src/custom-typings.d.ts | 4 +- src/main.browser.ts | 1 - webpack.config.js | 4 +- 11 files changed, 650 insertions(+), 614 deletions(-) diff --git a/config/helpers.js b/config/helpers.js index 25920a99..41c9c774 100644 --- a/config/helpers.js +++ b/config/helpers.js @@ -11,7 +11,7 @@ function hasProcessFlag(flag) { } function isWebpackDevServer() { - return process.argv[1] && !! (/webpack-dev-server$/.exec(process.argv[1])); + return process.argv[1] && !! (/webpack-dev-server/.exec(process.argv[1])); } function root(args) { @@ -19,14 +19,6 @@ function root(args) { return path.join.apply(path, [ROOT].concat(args)); } -function checkNodeImport(context, request, cb) { - if (!path.isAbsolute(request) && request.charAt(0) !== '.') { - cb(null, 'commonjs ' + request); return; - } - cb(); -} - exports.hasProcessFlag = hasProcessFlag; exports.isWebpackDevServer = isWebpackDevServer; exports.root = root; -exports.checkNodeImport = checkNodeImport; diff --git a/config/webpack.common.js b/config/webpack.common.js index 4b7d16ce..ffb584ec 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -9,11 +9,13 @@ const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; const HtmlElementsPlugin = require('./html-elements-plugin'); +const AssetsPlugin = require('assets-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); /* * Webpack Constants */ +const HMR = helpers.hasProcessFlag('hot'); const METADATA = { title: 'ng2-admin - Angular 2 Admin Template', description: 'Free Angular 2 and Bootstrap 4 Admin Template', @@ -26,275 +28,302 @@ const METADATA = { * * 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.browser.ts', - 'vendor': './src/vendor.browser.ts', - 'main': './src/main.browser.ts' - - }, - - /* - * Options affecting the resolving of modules. - * - * See: http://webpack.github.io/docs/configuration.html#resolve - */ - resolve: { +module.exports = function (options) { + isProd = options.env === 'production'; + return { /* - * An array of extensions that should be used to resolve modules. + * Static metadata for index.html * - * See: http://webpack.github.io/docs/configuration.html#resolve-extensions + * See: (custom attribute) */ - extensions: ['', '.ts', '.js', '.css', '.scss', '.json'], - - // 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: { + metadata: METADATA, /* - * An array of applied pre and post loaders. + * 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#module-preloaders-module-postloaders + * See: http://webpack.github.io/docs/configuration.html#cache */ - preLoaders: [ - { - test: /\.ts$/, - loader: 'string-replace-loader', - query: { - search: '(System|SystemJS)(.*[\\n\\r]\\s*\\.|\\.)import\\((.+)\\)', - replace: '$1.import($3).then(mod => mod.__esModule ? mod.default : mod)', - flags: 'g' + //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.browser.ts', + 'vendor': './src/vendor.browser.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', '.css', '.scss', '.json'], + + // 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: [ + { + test: /\.ts$/, + loader: 'string-replace-loader', + query: { + search: '(System|SystemJS)(.*[\\n\\r]\\s*\\.|\\.)import\\((.+)\\)', + replace: '$1.import($3).then(mod => (mod.__esModule && mod.default) ? mod.default : mod)', + flags: 'g' + }, + include: [helpers.root('src')] }, - include: [helpers.root('src')] - } + + ], + + /* + * 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 + * Replace templateUrl and stylesUrl with require() + * + * See: https://github.com/s-panferov/awesome-typescript-loader + * See: https://github.com/TheLarkInn/angular2-template-loader + */ + { + test: /\.ts$/, + loaders: [ + '@angularclass/hmr-loader?pretty=' + !isProd + '&prod=' + isProd, + 'awesome-typescript-loader', + 'angular2-template-loader' + ], + exclude: [/\.(spec|e2e)\.ts$/] + }, + + /* + * Json loader support for *.json files. + * + * See: https://github.com/webpack/json-loader + */ + { + test: /\.json$/, + loader: 'json-loader' + }, + + /* + * to string and css loader support for *.css files + * Returns file content as string + * + */ + { + test: /\.css$/, + // loaders: ['to-string-loader', 'css-loader'] + loaders: ['raw-loader'] + }, + + { + test: /\.scss$/, + loaders: ['raw-loader', 'sass-loader'] + }, + + { + test: /initial\.scss$/, + loader: ExtractTextPlugin.extract({ + fallbackLoader: 'style-loader', + loader: 'css-loader!sass-loader?sourceMap' + }) + }, + + { + test: /\.woff(2)?(\?v=.+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' + }, + + { + test: /\.(ttf|eot|svg)(\?v=.+)?$/, loader: 'file-loader' + }, + + { + test: /bootstrap\/dist\/js\/umd\//, + loader: 'imports?jQuery=jquery' + }, + + /* 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')] + }, + + /* File loader for supporting images, for example, in CSS files. + */ + { + test: /\.(jpg|png|gif)$/, + loader: 'file' + } + ], + + postLoaders: [ + { + test: /\.js$/, + loader: 'string-replace-loader', + query: { + search: 'var sourceMappingUrl = extractSourceMappingUrl\\(cssText\\);', + replace: 'var sourceMappingUrl = "";', + flags: 'g' + } + } + ] + }, + + + /* + * Add additional plugins to the compiler. + * + * See: http://webpack.github.io/docs/configuration.html#plugins + */ + plugins: [ + new ExtractTextPlugin({filename: 'initial.css', allChunks: true}), + + new AssetsPlugin({ + path: helpers.root('dist'), + filename: 'webpack-assets.json', + prettyPrint: true + }), + + /* + * 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: 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: ['polyfills', 'vendor'].reverse() + }), + + /* + * 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: 'dependency' + }), + + new webpack.ProvidePlugin({ + jQuery: 'jquery', + 'Tether': 'tether', + 'window.Tether': 'tether' + }), + + /* + * Plugin: HtmlHeadConfigPlugin + * Description: Generate html tags based on javascript maps. + * + * If a publicPath is set in the webpack output configuration, it will be automatically added to + * href attributes, you can disable that by adding a "=href": false property. + * You can also enable it to other attribute by settings "=attName": true. + * + * The configuration supplied is map between a location (key) and an element definition object (value) + * The location (key) is then exported to the template under then htmlElements property in webpack configuration. + * + * Example: + * Adding this plugin configuration + * new HtmlElementsPlugin({ + * headTags: { ... } + * }) + * + * Means we can use it in the template like this: + * <%= webpackConfig.htmlElements.headTags %> + * + * Dependencies: HtmlWebpackPlugin + */ + new HtmlElementsPlugin({ + headTags: require('./head-config.common') + }) ], /* - * An array of automatically applied loaders. + * Include polyfills or mocks for various node stuff + * Description: Node configuration * - * 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 + * See: https://webpack.github.io/docs/configuration.html#node */ - loaders: [ + node: { + global: 'window', + crypto: 'empty', + process: true, + module: false, + clearImmediate: false, + setImmediate: false + } - /* - * Typescript loader support for .ts and Angular 2 async routes via .async.ts - * Replace templateUrl and stylesUrl with require() - * - * See: https://github.com/s-panferov/awesome-typescript-loader - * See: https://github.com/TheLarkInn/angular2-template-loader - */ - { - test: /\.ts$/, - loaders: ['awesome-typescript-loader', 'angular2-template-loader', '@angularclass/hmr-loader'], - exclude: [/\.(spec|e2e)\.ts$/] - }, - - /* - * Json loader support for *.json files. - * - * See: https://github.com/webpack/json-loader - */ - { - test: /\.json$/, - loader: 'json-loader' - }, - - /* - * to string and css loader support for *.css files - * Returns file content as string - * - */ - { - test: /\.css$/, - // loaders: ['to-string-loader', 'css-loader'] - loaders: ['raw-loader'] - }, - - { - test: /\.scss$/, - loaders: ['raw-loader', 'sass-loader'] - }, - - { - test: /initial\.scss$/, - loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader!sass-loader?sourceMap' }) - }, - - { - test: /\.woff(2)?(\?v=.+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' - }, - - { - test: /\.(ttf|eot|svg)(\?v=.+)?$/, loader: 'file-loader' - }, - - { - test: /bootstrap\/dist\/js\/umd\//, - loader: 'imports?jQuery=jquery' - }, - - /* 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')] - }, - - /* File loader for supporting images, for example, in CSS files. - */ - { - test: /\.(jpg|png|gif)$/, - loader: 'file' - } - ] - - }, - - /* - * Add additional plugins to the compiler. - * - * See: http://webpack.github.io/docs/configuration.html#plugins - */ - plugins: [ - new ExtractTextPlugin({ filename: 'initial.css', allChunks: true }), - - /* - * 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: 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: ['polyfills', 'vendor'].reverse() - }), - - /* - * 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: 'dependency' - }), - - new webpack.ProvidePlugin({ - jQuery: 'jquery', - 'Tether': 'tether', - 'window.Tether': 'tether' - }), - - /* - * Plugin: HtmlHeadConfigPlugin - * Description: Generate html tags based on javascript maps. - * - * If a publicPath is set in the webpack output configuration, it will be automatically added to - * href attributes, you can disable that by adding a "=href": false property. - * You can also enable it to other attribute by settings "=attName": true. - * - * The configuration supplied is map between a location (key) and an element definition object (value) - * The location (key) is then exported to the template under then htmlElements property in webpack configuration. - * - * Example: - * Adding this plugin configuration - * new HtmlElementsPlugin({ - * headTags: { ... } - * }) - * - * Means we can use it in the template like this: - * <%= webpackConfig.htmlElements.headTags %> - * - * Dependencies: HtmlWebpackPlugin - */ - new HtmlElementsPlugin({ - headTags: require('./head-config.common') - }) - - ], - - /* - * 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 - } - -}; + }; +} diff --git a/config/webpack.dev.js b/config/webpack.dev.js index f3fd8959..6e226893 100644 --- a/config/webpack.dev.js +++ b/config/webpack.dev.js @@ -1,7 +1,3 @@ -/** - * @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 @@ -18,9 +14,8 @@ const NamedModulesPlugin = require('webpack/lib/NamedModulesPlugin'); const ENV = process.env.ENV = process.env.NODE_ENV = 'development'; const HOST = process.env.HOST || 'localhost'; const PORT = process.env.PORT || 3000; - const HMR = helpers.hasProcessFlag('hot'); -const METADATA = webpackMerge(commonConfig.metadata, { +const METADATA = webpackMerge(commonConfig({env: ENV}).metadata, { host: HOST, port: PORT, ENV: ENV, @@ -32,146 +27,149 @@ const METADATA = webpackMerge(commonConfig.metadata, { * * 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-source-map', - - /** - * Options affecting the output of the compilation. - * - * See: http://webpack.github.io/docs/configuration.html#output - */ - output: { +module.exports = function(options) { + return webpackMerge(commonConfig({env: ENV}), { /** - * The output directory as absolute path (required). + * Merged metadata from webpack.common.js for index.html * - * See: http://webpack.github.io/docs/configuration.html#output-path + * See: (custom attribute) */ - path: helpers.root('dist'), + metadata: METADATA, /** - * Specifies the name of each output file on disk. - * IMPORTANT: You must not specify an absolute path here! + * Switch loaders to debug mode. * - * See: http://webpack.github.io/docs/configuration.html#output-filename + * See: http://webpack.github.io/docs/configuration.html#debug */ - filename: '[name].bundle.js', + debug: true, /** - * The filename of the SourceMaps for the JavaScript files. - * They are inside the output.path directory. + * Developer tool to enhance debugging * - * See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename + * See: http://webpack.github.io/docs/configuration.html#devtool + * See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps */ - sourceMapFilename: '[file].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', - - library: 'ac_[name]', - libraryTarget: 'var' - }, - - plugins: [ + devtool: 'cheap-module-source-map', /** - * Plugin: DefinePlugin - * Description: Define free variables. - * Useful for having development builds with debug logging or adding global constants. + * Options affecting the output of the compilation. * - * Environment helpers - * - * See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin + * See: http://webpack.github.io/docs/configuration.html#output */ - // 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 - } - }), + output: { - /** - * Plugin: NamedModulesPlugin (experimental) - * Description: Uses file names as module name. - * - * See: https://github.com/webpack/webpack/commit/a04ffb928365b19feb75087c63f13cadfc08e1eb - */ - new NamedModulesPlugin() - ], + /** + * The output directory as absolute path (required). + * + * See: http://webpack.github.io/docs/configuration.html#output-path + */ + path: helpers.root('dist'), - /** - * 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' - }, + /** + * 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', - /** - * 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 + /** + * 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', + + library: 'ac_[name]', + libraryTarget: 'var', }, - outputPath: helpers.root('dist') - }, - /* - * 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 - } + 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, + } + }), + + /** + * Plugin: NamedModulesPlugin (experimental) + * Description: Uses file names as module name. + * + * See: https://github.com/webpack/webpack/commit/a04ffb928365b19feb75087c63f13cadfc08e1eb + */ + new NamedModulesPlugin(), + + ], + + /** + * 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 + }, + outputPath: helpers.root('dist') + }, + + /* + * 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 + } + + }); +} diff --git a/config/webpack.prod.js b/config/webpack.prod.js index 453222fd..8ff60924 100644 --- a/config/webpack.prod.js +++ b/config/webpack.prod.js @@ -1,7 +1,3 @@ -/** - * @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 @@ -16,232 +12,234 @@ const IgnorePlugin = require('webpack/lib/IgnorePlugin'); const DedupePlugin = require('webpack/lib/optimize/DedupePlugin'); const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin'); const WebpackMd5Hash = require('webpack-md5-hash'); -const CompressionPlugin = require('compression-webpack-plugin'); + /** * 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, { +const METADATA = webpackMerge(commonConfig({env: ENV}).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: { +module.exports = function(env) { + return webpackMerge(commonConfig({env: ENV}), { /** - * The output directory as absolute path (required). + * Switch loaders to debug mode. * - * See: http://webpack.github.io/docs/configuration.html#output-path + * See: http://webpack.github.io/docs/configuration.html#debug */ - path: helpers.root('dist'), + debug: false, /** - * Specifies the name of each output file on disk. - * IMPORTANT: You must not specify an absolute path here! + * Developer tool to enhance debugging * - * See: http://webpack.github.io/docs/configuration.html#output-filename + * See: http://webpack.github.io/docs/configuration.html#devtool + * See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps */ - filename: '[name].[chunkhash].bundle.js', + devtool: 'source-map', /** - * The filename of the SourceMaps for the JavaScript files. - * They are inside the output.path directory. + * Options affecting the output of the compilation. * - * See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename + * See: http://webpack.github.io/docs/configuration.html#output */ - sourceMapFilename: '[name].[chunkhash].bundle.map', + 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' + + }, /** - * The filename of non-entry chunks as relative path - * inside the output.path directory. + * Add additional plugins to the compiler. * - * See: http://webpack.github.io/docs/configuration.html#output-chunkfilename + * See: http://webpack.github.io/docs/configuration.html#plugins */ - chunkFilename: '[id].[chunkhash].chunk.js' + plugins: [ - }, + /** + * Plugin: WebpackMd5Hash + * Description: Plugin to replace a standard webpack chunkhash with md5. + * + * See: https://www.npmjs.com/package/webpack-md5-hash + */ + new WebpackMd5Hash(), - /** - * Add additional plugins to the compiler. - * - * See: http://webpack.github.io/docs/configuration.html#plugins - */ - plugins: [ + /** + * 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(), // see: https://github.com/angular/angular-cli/issues/1587 - /** - * 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(), // see: https://github.com/angular/angular-cli/issues/1587 - - /** - * 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': { + /** + * 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), - 'NODE_ENV': JSON.stringify(METADATA.ENV), - 'HMR': METADATA.HMR - } - }), + '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 + /** + * 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 - /* eslint-disable camelcase */ - mangle: false, - compress: { screw_ie8: true }, //prod - /* eslint-enable camelcase */ - comments: false //prod - }), + beautify: false, //prod + // mangle: { screw_ie8 : true, keep_fnames: true }, //prod + mangle: false, + compress: { screw_ie8: true }, //prod + comments: false //prod + }), - /** - * Plugin: NormalModuleReplacementPlugin - * Description: Replace resources that matches resourceRegExp with newResource - * - * See: http://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin - */ + /** + * Plugin: NormalModuleReplacementPlugin + * Description: Replace resources that matches resourceRegExp with newResource + * + * See: http://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin + */ - new NormalModuleReplacementPlugin( - /angular2-hmr/, - helpers.root('config/modules/angular2-hmr-prod.js') - ), + new NormalModuleReplacementPlugin( + /angular2-hmr/, + helpers.root('config/modules/angular2-hmr-prod.js') + ), - /** - * Plugin: IgnorePlugin - * Description: Don’t generate modules for requests matching the provided RegExp. - * - * See: http://webpack.github.io/docs/list-of-plugins.html#ignoreplugin - */ + /** + * Plugin: IgnorePlugin + * Description: Don’t generate modules for requests matching the provided RegExp. + * + * See: http://webpack.github.io/docs/list-of-plugins.html#ignoreplugin + */ - // new IgnorePlugin(/angular2-hmr/), + // new IgnorePlugin(/angular2-hmr/), - /** - * 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 - }) + /** + * Plugin: CompressionPlugin + * Description: Prepares compressed versions of assets to serve + * them with Content-Encoding + * + * See: https://github.com/webpack/compression-webpack-plugin + */ + // install 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 - } + /** + * 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 + } + + }); +} diff --git a/package.json b/package.json index eb97197d..6981a135 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "@angularclass/request-idle-callback": "^1.0.7", "@angularclass/webpack-toolkit": "^1.3.3", "@angularclass/conventions-loader": "^1.0.2", + "@angularclass/hmr": "~1.2.0", + "@angularclass/hmr-loader": "~3.0.2", + "assets-webpack-plugin": "^3.4.0", "http-server": "^0.9.0", "ie-shim": "^0.1.0", @@ -30,11 +33,11 @@ "ammap3": "github:amcharts/ammap3", "animate.css": "^3.5.1", "bootstrap": "4.0.0-alpha.2", - "bootstrap-loader": "1.1.2", + "bootstrap-loader": "1.1.6", "chart.js": "^1.1.1", "chartist": "^0.9.7", "ckeditor": "^4.5.9", - "core-js": "^2.4.0", + "core-js": "^2.4.1", "easy-pie-chart": "^2.1.7", "extract-text-webpack-plugin": "2.0.0-beta.3", "font-awesome": "^4.6.1", @@ -47,17 +50,15 @@ "leaflet": "^0.7.7", "leaflet-map": "^0.2.1", "lodash": "^4.12.0", - "ng2-bootstrap": "1.1.2", + "ng2-bootstrap": "1.1.5", "ng2-tree": "^0.0.2-7", "ng2-ckeditor": "1.0.7", "ng2-smart-table": "^0.2.4", - "ng2-uploader": "0.5.14", + "ng2-uploader": "1.1.0", "normalize.css": "^4.1.1", "tether": "^1.2.4" }, "devDependencies": { - "@angularclass/hmr": "^1.0.1", - "@angularclass/hmr-loader": "^1.0.1", "angular2-template-loader": "^0.5.0", "@types/core-js": "^0.9.28", "@types/hammerjs": "^2.0.28", @@ -66,15 +67,14 @@ "@types/uglify-js": "^2.0.27", "@types/webpack": "^1.12.29", "@types/lodash": "0.0.28", - "angular2-hmr": "~0.8.0", "gh-pages": "^0.11.0", "parse5": "^1.3.2", "rimraf": "^2.5.2", - "codelyzer": "~0.0.21", - "tslint": "^3.15.1", + "codelyzer": "~0.0.28", + "tslint": "3.15.1", "ts-helpers": "1.1.1", "ts-node": "^1.3.0", - "typedoc": "^0.4.4", + "typedoc": "^0.4.5", "typescript": "2.0.0", "awesome-typescript-loader": "^2.2.1", "tslint-loader": "^2.1.3", @@ -82,15 +82,15 @@ "style-loader": "^0.13.1", "raw-loader": "0.5.1", "source-map-loader": "^0.1.5", - "string-replace-loader": "^1.0.3", + "string-replace-loader": "github:gdi2290/string-replace-loader", "imports-loader": "^0.6.5", "json-loader": "^0.5.4", - "css-loader": "^0.24.0", + "css-loader": "^0.25.0", "exports-loader": "^0.6.3", "expose-loader": "^0.7.1", "file-loader": "^0.9.0", "to-string-loader": "^1.1.4", - "sass-loader": "^3.2.0", + "sass-loader": "^4.0.2", "resolve-url-loader": "^1.4.3", "node-sass": "^3.5.3", "html-webpack-plugin": "^2.21.0", @@ -98,9 +98,9 @@ "webpack": "^2.1.0-beta.21", "webpack-dashboard": "^0.1.8", "webpack-dev-middleware": "^1.6.1", - "webpack-dev-server": "^2.1.0-beta.0", + "webpack-dev-server": "^2.1.0-beta.2", "webpack-md5-hash": "^0.0.5", - "webpack-merge": "^0.14.0", + "webpack-merge": "^0.14.1", "compression-webpack-plugin": "^0.3.1", "es6-promise": "^3.1.2", "es6-shim": "^0.35.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3fe3f414..575bd4bd 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,7 +3,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { RouterModule } from '@angular/router'; -import { removeNgStyles, createNewHosts } from '@angularclass/hmr'; +import { removeNgStyles, createNewHosts, createInputTransfer } from '@angularclass/hmr'; /* * Platform and Environment providers/directives/pipes @@ -13,7 +13,7 @@ import { routing } from './app.routing'; // App is our top level component import { App } from './app.component'; -import { AppState } from './app.service'; +import { AppState, InteralStateType } from './app.service'; import { GlobalState } from './global.state'; import { NgaModule } from './theme/nga.module'; import { PagesModule } from './pages/pages.module'; @@ -24,6 +24,12 @@ const APP_PROVIDERS = [ GlobalState ]; +type StoreType = { + state: InteralStateType, + restoreInputValues: () => void, + disposeOldHosts: () => void +}; + /** * `AppModule` is the main entry point into Angular2's bootstraping process */ @@ -51,28 +57,37 @@ const APP_PROVIDERS = [ export class AppModule { constructor(public appRef: ApplicationRef, public appState: AppState) { - } - hmrOnInit(store) { + hmrOnInit(store: StoreType) { if (!store || !store.state) return; - console.log('HMR store', store); + console.log('HMR store', JSON.stringify(store, null, 2)); + // set state this.appState._state = store.state; + // set input values + if ('restoreInputValues' in store) { + let restoreInputValues = store.restoreInputValues; + setTimeout(restoreInputValues); + } this.appRef.tick(); delete store.state; + delete store.restoreInputValues; } - hmrOnDestroy(store) { + hmrOnDestroy(store: StoreType) { const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement); - // recreate elements + // save state const state = this.appState._state; store.state = state; + // recreate root elements store.disposeOldHosts = createNewHosts(cmpLocation); + // save input values + store.restoreInputValues = createInputTransfer(); // remove styles removeNgStyles(); } - hmrAfterDestroy(store) { + hmrAfterDestroy(store: StoreType) { // display new elements store.disposeOldHosts(); delete store.disposeOldHosts; diff --git a/src/app/app.service.ts b/src/app/app.service.ts index c08700c4..e9bc98f7 100644 --- a/src/app/app.service.ts +++ b/src/app/app.service.ts @@ -1,8 +1,12 @@ import { Injectable } from '@angular/core'; +export type InteralStateType = { + [key: string]: any +}; + @Injectable() export class AppState { - _state = { }; + _state: InteralStateType = {}; constructor() { } @@ -11,6 +15,7 @@ export class AppState { get state() { return this._state = this._clone(this._state); } + // never allow mutation set state(value) { throw new Error('do not mutate the `.state` directly'); @@ -29,8 +34,8 @@ export class AppState { } - _clone(object) { + private _clone(object: InteralStateType) { // simple object clone - return JSON.parse(JSON.stringify( object )); + return JSON.parse(JSON.stringify(object)); } } diff --git a/src/app/environment.ts b/src/app/environment.ts index 8bba89c4..8d5288f9 100644 --- a/src/app/environment.ts +++ b/src/app/environment.ts @@ -4,13 +4,13 @@ import { enableDebugTools, disableDebugTools } from '@angular/platform-browser'; import { enableProdMode, ApplicationRef } from '@angular/core'; // Environment Providers -let PROVIDERS = [ +let PROVIDERS: any[] = [ // common env directives ]; // Angular debug tools in the dev console // https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md -let _decorateModuleRef = function identity(value) { return value; }; +let _decorateModuleRef = function identity(value: T): T { return value; }; if ('production' === ENV) { // Production diff --git a/src/custom-typings.d.ts b/src/custom-typings.d.ts index 2a6969c1..c88aad41 100644 --- a/src/custom-typings.d.ts +++ b/src/custom-typings.d.ts @@ -52,8 +52,8 @@ interface SystemJS { } interface GlobalEnvironment { - ENV; - HMR; + ENV: string; + HMR: boolean; SystemJS: SystemJS; System: SystemJS; } diff --git a/src/main.browser.ts b/src/main.browser.ts index 85a6e274..8022029a 100644 --- a/src/main.browser.ts +++ b/src/main.browser.ts @@ -3,7 +3,6 @@ */ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { decorateModuleRef } from './app/environment'; -import { ApplicationRef } from '@angular/core'; import { bootloader } from '@angularclass/hmr'; /* * App Module diff --git a/webpack.config.js b/webpack.config.js index eb35fdb9..72efa4ae 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,10 +2,10 @@ switch (process.env.NODE_ENV) { case 'prod': case 'production': - module.exports = require('./config/webpack.prod'); + module.exports = require('./config/webpack.prod')({env: 'production'}); break; case 'dev': case 'development': default: - module.exports = require('./config/webpack.dev'); + module.exports = require('./config/webpack.dev')({env: 'development'}); }