From 60fb36afe4cfa9e9167816045c70c376a6929655 Mon Sep 17 00:00:00 2001 From: Larkin Family Date: Sun, 12 Jun 2016 14:56:28 -0500 Subject: [PATCH] Added serve task as well as some interfaces for safer maintainability --- addon/ng2/commands/serve.ts | 37 +++++++++++++---- addon/ng2/models/save-for-later.ts | 4 +- addon/ng2/models/webpack-build-config.ts | 27 +++--------- addon/ng2/tasks/build-webpack-watch.ts | 5 ++- addon/ng2/tasks/build-webpack.ts | 2 +- addon/ng2/tasks/serve-webpack.ts | 52 +++++++++++++++++++++--- package.json | 3 +- 7 files changed, 88 insertions(+), 42 deletions(-) diff --git a/addon/ng2/commands/serve.ts b/addon/ng2/commands/serve.ts index be85c20a5629..63c82928dd76 100644 --- a/addon/ng2/commands/serve.ts +++ b/addon/ng2/commands/serve.ts @@ -11,6 +11,23 @@ PortFinder.basePort = 49152; const getPort = Promise.denodeify(PortFinder.getPort); const defaultPort = process.env.PORT || 4200; +export interface IServeTaskOptions { + port?: number; + host?: string; + proxy?: string; + insecureProxy?: boolean; + watcher?: string; + liveReload?: boolean; + liveReloadHost?: string; + liveReloadPort?: number; + liveReloadBaseUrl?: string; + liveReloadLiveCss?: boolean; + environment?: string; + outputPath?: string; + ssl?: boolean; + sslKey?: string; + sslCert?: string; +} module.exports = Command.extend({ name: 'serve', @@ -35,12 +52,12 @@ module.exports = Command.extend({ { name: 'ssl-cert', type: String, default: 'ssl/server.crt' } ], - run: function(commandOptions) { + run: function(commandOptions: IServeTaskOptions) { commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host; return this._checkExpressPort(commandOptions) .then(this._autoFindLiveReloadPort.bind(this)) - .then(function(commandOptions) { + .then(function(commandOptions: IServeTaskOptions) { commandOptions = assign({}, commandOptions, { baseURL: this.project.config(commandOptions.environment).baseURL || '/' }); @@ -53,11 +70,13 @@ module.exports = Command.extend({ } } - var ServeTask = require('../tasks/serve'); - var serve = new ServeTask({ + const ServeWebpackTask = (require('../tasks/serve-webpack.ts')) + // var ServeTask = require('../tasks/serve'); + + var serve = new ServeWebpackTask({ ui: this.ui, analytics: this.analytics, - project: this.project + project: this.project, }); return win.checkWindowsElevation(this.ui).then(function() { @@ -66,9 +85,9 @@ module.exports = Command.extend({ }.bind(this)); }, - _checkExpressPort: function(commandOptions) { + _checkExpressPort: function(commandOptions: IServeTaskOptions) { return getPort({ port: commandOptions.port, host: commandOptions.host }) - .then(function(foundPort) { + .then(function(foundPort: number) { if (commandOptions.port !== foundPort && commandOptions.port !== 0) { var message = 'Port ' + commandOptions.port + ' is already in use.'; @@ -82,9 +101,9 @@ module.exports = Command.extend({ }.bind(this)); }, - _autoFindLiveReloadPort: function(commandOptions) { + _autoFindLiveReloadPort: function(commandOptions: IServeTaskOptions) { return getPort({ port: commandOptions.liveReloadPort, host: commandOptions.liveReloadHost }) - .then(function(foundPort) { + .then(function(foundPort: number) { // if live reload port matches express port, try one higher if (foundPort === commandOptions.port) { diff --git a/addon/ng2/models/save-for-later.ts b/addon/ng2/models/save-for-later.ts index 2b69bb0e8c1c..0537ee356fbe 100644 --- a/addon/ng2/models/save-for-later.ts +++ b/addon/ng2/models/save-for-later.ts @@ -1,6 +1,4 @@ -// new webpack.optimize.CommonsChunkPlugin({ -// name: ['polyfills', 'vendor'].reverse() -// }), + // new webpack.LoaderOptionsPlugin({ // minimize: true // }), diff --git a/addon/ng2/models/webpack-build-config.ts b/addon/ng2/models/webpack-build-config.ts index e88407bf49dd..7af85a87748f 100644 --- a/addon/ng2/models/webpack-build-config.ts +++ b/addon/ng2/models/webpack-build-config.ts @@ -25,30 +25,11 @@ export const webpackOutputOptions = { export interface IWebpackDevServerConfigurationOptions { contentBase?: string; - // or: contentBase: "http://localhost/", - hot?: boolean; - // Enable special support for Hot Module Replacement - // Page is no longer updated, but a "webpackHotUpdate" message is send to the content - // Use "webpack/hot/dev-server" as additional module in your entry point - // Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does. - - // Set this as true if you want to access dev server from arbitrary url. - // This is handy if you are using a html5 router. historyApiFallback?: boolean; - - // Set this if you want to enable gzip compression for assets compress?: boolean; - - // Set this if you want webpack-dev-server to delegate a single path to an arbitrary server. - // Use "*" to proxy all paths to the specified server. - // This is useful if you want to get rid of 'http://localhost:8080/' in script[src], - // and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ). proxy?: {[key: string] : string}; - - // pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server staticOptions?: any; - // webpack-dev-middleware options quiet?: boolean; noInfo?: boolean; lazy?: boolean; @@ -60,6 +41,7 @@ export interface IWebpackDevServerConfigurationOptions { publicPath?: string; headers?: { [key:string]: string }; stats?: { colors: boolean; }; + inline: boolean; } // Webpack Configuration Object @@ -69,13 +51,13 @@ export const webpackCommonConfig = { // Resolve loaders from the CLI node_modules rather than the projects context: path.resolve(__dirname, './'), entry: { - main: ngAppResolve('./src/main.ts'), + main: [ngAppResolve('./src/main.ts')], vendor: ngAppResolve('./src/vendor.ts'), polyfills: ngAppResolve('./src/polyfills.ts') }, output: { - path: './dist', + path: ngAppResolve('./dist'), filename: '[name].bundle.js' }, @@ -124,6 +106,9 @@ export const webpackCommonConfig = { ] }, plugins: [ + new webpack.optimize.CommonsChunkPlugin({ + name: ['polyfills', 'vendor'].reverse() + }), new HtmlWebpackPlugin(baseHtmlTemplateConfig) ], resolve: { diff --git a/addon/ng2/tasks/build-webpack-watch.ts b/addon/ng2/tasks/build-webpack-watch.ts index f56282dc2c70..216c072d378f 100644 --- a/addon/ng2/tasks/build-webpack-watch.ts +++ b/addon/ng2/tasks/build-webpack-watch.ts @@ -1,4 +1,5 @@ -import {webpackCommonConfig, webpackOutputOptions} from '../models/webpack-build-config.ts'; +import {webpackCommonConfig, webpackOutputOptions} from '../models/webpack-build-config'; +import {IServeTaskOptions} from '../commands/serve'; const Task = require('ember-cli/lib/models/task'); const webpack = require('webpack'); @@ -13,7 +14,7 @@ let lastHash = null; module.exports = Task.extend({ run: () => { - let commandOptions = this.options; + let commandOptions: IServeTaskOptions = this.options; return new Promise( (resolve, reject) => { webpackCompiler.watch({}, (err, stats) => { diff --git a/addon/ng2/tasks/build-webpack.ts b/addon/ng2/tasks/build-webpack.ts index c0d3b08d0386..4a068a6c725f 100644 --- a/addon/ng2/tasks/build-webpack.ts +++ b/addon/ng2/tasks/build-webpack.ts @@ -1,4 +1,4 @@ -import {webpackCommonConfig, webpackOutputOptions} from '../models/webpack-build-config.ts'; +import {webpackCommonConfig, webpackOutputOptions} from '../models/webpack-build-config'; // Configure build and output; const Task = require('ember-cli/lib/models/task'); diff --git a/addon/ng2/tasks/serve-webpack.ts b/addon/ng2/tasks/serve-webpack.ts index fe97f26d8674..8039ddd18863 100644 --- a/addon/ng2/tasks/serve-webpack.ts +++ b/addon/ng2/tasks/serve-webpack.ts @@ -1,18 +1,60 @@ -import {webpackCommonConfig, webpackOutputOptions} from '../models/webpack-build-config.ts'; +import {webpackCommonConfig, webpackOutputOptions, IWebpackDevServerConfigurationOptions} from '../models/webpack-build-config.ts'; +import {IServeTaskOptions} from '../commands/serve'; + +const path = require('path'); +const chalk = require('chalk'); -webpackCommonConfig.entry.main.unshift("webpack-dev-server/client?http://localhost:8080/"); const Task = require('ember-cli/lib/models/task'); const webpack = require('webpack'); const WebpackDevServer = require('webpack-dev-server'); -const webpackCompiler = webpack(webpackCommonConfig); const ProgressPlugin = require('webpack/lib/ProgressPlugin'); -const server = new WebpackDevServer(webpackCompiler); +let lastHash = null; + +module.exports = Task.extend({ + run: (commandOptions: IServeTaskOptions) => { + + webpackCommonConfig.entry.main.unshift(`webpack-dev-server/client?http://localhost:${commandOptions.port}/`); + const webpackCompiler = webpack(webpackCommonConfig); + + webpackCompiler.apply(new ProgressPlugin({ + profile: true, + colors: true + })); + + const webpackDevServerConfiguration: IWebpackDevServerConfigurationOptions = { + contentBase: path.resolve(process.cwd(), './src'), + historyApiFallback: true, + stats: { colors: true }, + inline: true + }; + + const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration); + const serveMessage:string = chalk.green(`\n*\n*\n NG Live Development Server is running on http://localhost:${commandOptions.port}.\n*\n*`); + + return new Promise((resolve, reject) => { + server.listen(commandOptions.port, "localhost", function(err, stats) { + if(err) { + lastHash = null; + console.error(err.stack || err); + if(err.details) console.error(err.details); + reject(err.details); + } + + if(stats && stats.hash && stats.hash !== lastHash) { + lastHash = stats.hash; + process.stdout.write(stats.toString(webpackOutputOptions) + "\n" + serveMessage + "\n"); + } + + process.stdout.write(serveMessage); + }); + }) + } +}); -server.listen(8080); diff --git a/package.json b/package.json index a12757ca65f5..7e9eca43a556 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,8 @@ "ts-loader": "^0.8.2", "typescript": "^1.9.0-dev.20160611-1.0", "typings": "^0.8.1", - "webpack": "2.1.0-beta.13" + "webpack": "2.1.0-beta.13", + "webpack-dev-server": "^1.14.1" }, "ember-addon": { "paths": [