|
1 | 1 | module.exports = (api, options) => {
|
2 |
| - api.registerCommand('serve', (getWebpackConfig, args) => { |
3 |
| - process.env.NODE_ENV = args.prod ? 'production' : 'development' |
4 |
| - |
5 |
| - // TODO use port-finder |
6 |
| - const port = options.port || 8080 |
7 |
| - const host = options.host || '127.0.0.1' |
8 |
| - |
9 |
| - api.chainWebpack(config => { |
10 |
| - config |
11 |
| - .entry('app') |
12 |
| - .add(`webpack-dev-server/client/index.js?http://${host}:${port}`) |
13 |
| - .add(`webpack/hot/dev-server`) |
14 |
| - }) |
| 2 | + api.registerCommand('serve', args => { |
| 3 | + // TODO improve log formatting |
| 4 | + console.log('[vue-cli] starting dev server, hang tight...') |
| 5 | + |
| 6 | + api.setEnv(args.env || 'development') |
15 | 7 |
|
| 8 | + const chalk = require('chalk') |
16 | 9 | const webpack = require('webpack')
|
17 | 10 | const WebpackDevServer = require('webpack-dev-server')
|
18 |
| - const webpackConfig = getWebpackConfig() |
19 |
| - |
20 |
| - const compiler = webpack(webpackConfig) |
21 |
| - const server = new WebpackDevServer(compiler, Object.assign({ |
22 |
| - clientLogLevel: 'warning', |
23 |
| - historyApiFallback: true, |
24 |
| - hot: true, |
25 |
| - compress: true, |
26 |
| - open: true, |
27 |
| - overlay: { warnings: false, errors: true }, |
28 |
| - publicPath: '/', |
29 |
| - quiet: true |
30 |
| - }, options.devServer)) |
31 |
| - |
32 |
| - server.listen(port, host) |
| 11 | + const portfinder = require('portfinder') |
| 12 | + const openBrowser = require('../util/openBrowser') |
| 13 | + const prepareURLs = require('../util/prepareURLs') |
| 14 | + const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') |
| 15 | + |
| 16 | + const useHttps = args.https || options.https |
| 17 | + const host = args.host || process.env.HOST || options.host || '0.0.0.0' |
| 18 | + portfinder.basePort = args.port || process.env.PORT || options.port || 8080 |
| 19 | + |
| 20 | + portfinder.getPort((err, port) => { |
| 21 | + if (err) { |
| 22 | + return console.error(err) |
| 23 | + } |
| 24 | + |
| 25 | + const webpackConfig = api.resolveWebpackConfig() |
| 26 | + const projectDevServerOptions = options.devServer || {} |
| 27 | + const urls = prepareURLs( |
| 28 | + useHttps ? 'https' : 'http', |
| 29 | + host, |
| 30 | + port |
| 31 | + ) |
| 32 | + |
| 33 | + // inject friendly errors |
| 34 | + webpackConfig.plugins.push(new FriendlyErrorsPlugin({ |
| 35 | + compilationSuccessInfo: { |
| 36 | + messages: [ |
| 37 | + `App running at:`, |
| 38 | + `- Local: ${urls.localUrlForTerminal}`, |
| 39 | + `- Network: ${urls.lanUrlForTerminal}` |
| 40 | + ], |
| 41 | + notes: [ |
| 42 | + `Note that the development build is not optimized.`, |
| 43 | + `To create a production build, run ${chalk.cyan(`npm run build`)} or ${chalk.cyan(`yarn build`)}.` |
| 44 | + ] |
| 45 | + } |
| 46 | + })) |
| 47 | + |
| 48 | + // inject dev/hot client |
| 49 | + addDevClientToEntry(webpackConfig, [ |
| 50 | + `webpack-dev-server/client/?${urls.localUrlForBrowser}`, |
| 51 | + projectDevServerOptions.hotOnly |
| 52 | + ? 'webpack/hot/dev-server' |
| 53 | + : 'webpack/hot/only-dev-server' |
| 54 | + ]) |
| 55 | + |
| 56 | + const compiler = webpack(webpackConfig) |
| 57 | + const server = new WebpackDevServer(compiler, Object.assign({ |
| 58 | + clientLogLevel: 'none', |
| 59 | + historyApiFallback: { |
| 60 | + disableDotRule: true |
| 61 | + }, |
| 62 | + contentBase: api.resolve('public'), |
| 63 | + watchContentBase: true, |
| 64 | + https: useHttps, |
| 65 | + hot: true, |
| 66 | + quiet: true, |
| 67 | + compress: true, |
| 68 | + publicPath: webpackConfig.output.publicPath, |
| 69 | + // TODO use custom overlay w/ open-in-editor |
| 70 | + overlay: { warnings: false, errors: true }, |
| 71 | + // TODO handle proxy |
| 72 | + proxy: {} |
| 73 | + }, projectDevServerOptions)) |
| 74 | + |
| 75 | + server.listen(port, host, err => { |
| 76 | + if (err) { |
| 77 | + return console.error(err) |
| 78 | + } |
| 79 | + // TODO avoid duplicate opening |
| 80 | + // TODO avoid opening when compilation fails |
| 81 | + openBrowser(urls.localUrlForBrowser) |
| 82 | + }) |
| 83 | + }) |
33 | 84 | })
|
34 | 85 | }
|
| 86 | + |
| 87 | +function addDevClientToEntry (config, devClient) { |
| 88 | + const { entry } = config |
| 89 | + if (typeof entry === 'object' && !Array.isArray(entry)) { |
| 90 | + Object.keys(entry).forEach((key) => { |
| 91 | + entry[key] = devClient.concat(entry[key]) |
| 92 | + }) |
| 93 | + } else if (typeof entry === 'function') { |
| 94 | + config.entry = entry(devClient) |
| 95 | + } else { |
| 96 | + config.entry = devClient.concat(entry) |
| 97 | + } |
| 98 | +} |
0 commit comments