1 | "use strict";
|
2 | const fs = require('fs');
|
3 | const path = require('path');
|
4 | const chalk = require('chalk');
|
5 | const rimraf = require('rimraf');
|
6 | const webpack = require('webpack');
|
7 | const url = require('url');
|
8 | const common_tags_1 = require('common-tags');
|
9 | const utils_1 = require('../models/webpack-configs/utils');
|
10 | const webpack_config_1 = require('../models/webpack-config');
|
11 | const config_1 = require('../models/config');
|
12 | const WebpackDevServer = require('webpack-dev-server');
|
13 | const Task = require('../ember-cli/lib/models/task');
|
14 | const SilentError = require('silent-error');
|
15 | const opn = require('opn');
|
16 | Object.defineProperty(exports, "__esModule", { value: true });
|
17 | exports.default = Task.extend({
|
18 | run: function (serveTaskOptions, rebuildDoneCb) {
|
19 | const ui = this.ui;
|
20 | let webpackCompiler;
|
21 | const projectConfig = config_1.CliConfig.fromProject().config;
|
22 | const appConfig = projectConfig.apps[0];
|
23 | const outputPath = serveTaskOptions.outputPath || appConfig.outDir;
|
24 | if (this.project.root === outputPath) {
|
25 | throw new SilentError('Output path MUST not be project root directory!');
|
26 | }
|
27 | rimraf.sync(path.resolve(this.project.root, outputPath));
|
28 | const serveDefaults = {
|
29 |
|
30 | deployUrl: ''
|
31 | };
|
32 | serveTaskOptions = Object.assign({}, serveDefaults, serveTaskOptions);
|
33 | let webpackConfig = new webpack_config_1.NgCliWebpackConfig(serveTaskOptions).config;
|
34 |
|
35 |
|
36 | let entryPoints = [
|
37 | `webpack-dev-server/client?http://${serveTaskOptions.host}:${serveTaskOptions.port}/`
|
38 | ];
|
39 | if (serveTaskOptions.hmr) {
|
40 | const webpackHmrLink = 'https://webpack.github.io/docs/hot-module-replacement.html';
|
41 | ui.writeLine(common_tags_1.oneLine `
|
42 | ${chalk.yellow('NOTICE')} Hot Module Replacement (HMR) is enabled for the dev server.
|
43 | `);
|
44 | ui.writeLine(' The project will still live reload when HMR is enabled,');
|
45 | ui.writeLine(' but to take advantage of HMR additional application code is required');
|
46 | ui.writeLine(' (not included in an Angular CLI project by default).');
|
47 | ui.writeLine(` See ${chalk.blue(webpackHmrLink)}`);
|
48 | ui.writeLine(' for information on working with HMR for Webpack.');
|
49 | entryPoints.push('webpack/hot/dev-server');
|
50 | webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
|
51 | webpackConfig.plugins.push(new webpack.NamedModulesPlugin());
|
52 | if (serveTaskOptions.extractCss) {
|
53 | ui.writeLine(common_tags_1.oneLine `
|
54 | ${chalk.yellow('NOTICE')} (HMR) does not allow for CSS hot reload when used
|
55 | together with '--extract-css'.
|
56 | `);
|
57 | }
|
58 | }
|
59 | if (!webpackConfig.entry.main) {
|
60 | webpackConfig.entry.main = [];
|
61 | }
|
62 | webpackConfig.entry.main.unshift(...entryPoints);
|
63 | webpackCompiler = webpack(webpackConfig);
|
64 | if (rebuildDoneCb) {
|
65 | webpackCompiler.plugin('done', rebuildDoneCb);
|
66 | }
|
67 | const statsConfig = utils_1.getWebpackStatsConfig(serveTaskOptions.verbose);
|
68 | let proxyConfig = {};
|
69 | if (serveTaskOptions.proxyConfig) {
|
70 | const proxyPath = path.resolve(this.project.root, serveTaskOptions.proxyConfig);
|
71 | if (fs.existsSync(proxyPath)) {
|
72 | proxyConfig = require(proxyPath);
|
73 | }
|
74 | else {
|
75 | const message = 'Proxy config file ' + proxyPath + ' does not exist.';
|
76 | return Promise.reject(new SilentError(message));
|
77 | }
|
78 | }
|
79 | let sslKey = null;
|
80 | let sslCert = null;
|
81 | if (serveTaskOptions.ssl) {
|
82 | const keyPath = path.resolve(this.project.root, serveTaskOptions.sslKey);
|
83 | if (fs.existsSync(keyPath)) {
|
84 | sslKey = fs.readFileSync(keyPath, 'utf-8');
|
85 | }
|
86 | const certPath = path.resolve(this.project.root, serveTaskOptions.sslCert);
|
87 | if (fs.existsSync(certPath)) {
|
88 | sslCert = fs.readFileSync(certPath, 'utf-8');
|
89 | }
|
90 | }
|
91 | const webpackDevServerConfiguration = {
|
92 | contentBase: path.join(this.project.root, `./${appConfig.root}`),
|
93 | headers: { 'Access-Control-Allow-Origin': '*' },
|
94 | historyApiFallback: {
|
95 | index: `/${appConfig.index}`,
|
96 | disableDotRule: true,
|
97 | htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
|
98 | },
|
99 | stats: statsConfig,
|
100 | inline: true,
|
101 | proxy: proxyConfig,
|
102 | compress: serveTaskOptions.target === 'production',
|
103 | watchOptions: {
|
104 | poll: projectConfig.defaults && projectConfig.defaults.poll
|
105 | },
|
106 | https: serveTaskOptions.ssl
|
107 | };
|
108 | if (sslKey != null && sslCert != null) {
|
109 | webpackDevServerConfiguration.key = sslKey;
|
110 | webpackDevServerConfiguration.cert = sslCert;
|
111 | }
|
112 | webpackDevServerConfiguration.hot = serveTaskOptions.hmr;
|
113 | if (serveTaskOptions.target === 'production') {
|
114 | ui.writeLine(chalk.red(common_tags_1.stripIndents `
|
115 | ****************************************************************************************
|
116 | This is a simple server for use in testing or debugging Angular applications locally.
|
117 | It hasn't been reviewed for security issues.
|
118 |
|
119 | DON'T USE IT FOR PRODUCTION USE!
|
120 | ****************************************************************************************
|
121 | `));
|
122 | }
|
123 | ui.writeLine(chalk.green(common_tags_1.oneLine `
|
124 | **
|
125 | NG Live Development Server is running on
|
126 | http${serveTaskOptions.ssl ? 's' : ''}://${serveTaskOptions.host}:${serveTaskOptions.port}.
|
127 | **
|
128 | `));
|
129 | const server = new WebpackDevServer(webpackCompiler, webpackDevServerConfiguration);
|
130 | return new Promise((resolve, reject) => {
|
131 | server.listen(serveTaskOptions.port, `${serveTaskOptions.host}`, (err, stats) => {
|
132 | if (err) {
|
133 | console.error(err.stack || err);
|
134 | if (err.details) {
|
135 | console.error(err.details);
|
136 | }
|
137 | reject(err.details);
|
138 | }
|
139 | else {
|
140 | const { open, ssl, host, port } = serveTaskOptions;
|
141 | if (open) {
|
142 | let protocol = ssl ? 'https' : 'http';
|
143 | opn(url.format({ protocol: protocol, hostname: host, port: port.toString() }));
|
144 | }
|
145 | }
|
146 | });
|
147 | });
|
148 | }
|
149 | });
|
150 |
|
\ | No newline at end of file |