1 | const url = require('url')
|
2 | const Server = require('webpack-dev-server')
|
3 | const opn = require('opn')
|
4 | const chalk = require('chalk')
|
5 | const launchEditorMiddlewarre = require('launch-editor-middleware')
|
6 | const getPort = require('get-port')
|
7 | const address = require('address')
|
8 | const launchEditorEndpoint = require('@poi/dev-utils/launchEditorEndpoint')
|
9 | const logger = require('@poi/logger')
|
10 | const unspecifiedAddress = require('../utils/unspecifiedAddress')
|
11 | const isPath = require('../utils/isPath')
|
12 |
|
13 | module.exports = poi => {
|
14 | const command = poi.cli.handleCommand(
|
15 | 'develop',
|
16 | {
|
17 | desc: 'Run app in development mode',
|
18 | match(name) {
|
19 | return !name || isPath(name)
|
20 | }
|
21 | },
|
22 | async () => {
|
23 | const compiler = poi.createCompiler()
|
24 |
|
25 | const devServerOptions = Object.assign(
|
26 | {
|
27 | hot: poi.options.hotReload !== false,
|
28 | quiet: true,
|
29 | historyApiFallback: true,
|
30 | overlay: true,
|
31 | noInfo: true,
|
32 | disableHostCheck: true,
|
33 | publicPath: compiler.options.output.publicPath
|
34 | },
|
35 | compiler.options.devServer,
|
36 | poi.options.devServer
|
37 | )
|
38 |
|
39 | const existingBefore = devServerOptions.before
|
40 | devServerOptions.before = app => {
|
41 | app.use(
|
42 | launchEditorEndpoint,
|
43 | launchEditorMiddlewarre(() =>
|
44 | console.log(
|
45 | `To specify an editor, sepcify the EDITOR env variable or ` +
|
46 | `add "editor" field to your Vue project config.\n`
|
47 | )
|
48 | )
|
49 | )
|
50 | existingBefore && existingBefore(app)
|
51 | }
|
52 |
|
53 | if (typeof devServerOptions.proxy === 'string') {
|
54 | devServerOptions.proxy = {
|
55 | '/api': {
|
56 | target: devServerOptions.proxy,
|
57 | changeOrigin: true,
|
58 | pathRewrite: {
|
59 | '^/api': ''
|
60 | }
|
61 | }
|
62 | }
|
63 | }
|
64 |
|
65 | const host = poi.options.devServer.host
|
66 | const port = await getPort({ port: poi.options.devServer.port, host })
|
67 | if (port !== poi.options.devServer.port) {
|
68 | logger.warn(
|
69 | `Port ${
|
70 | poi.options.devServer.port
|
71 | } has been used, switched to ${port}.`
|
72 | )
|
73 | }
|
74 |
|
75 | const server = new Server(compiler, devServerOptions)
|
76 | server.listen(port, host)
|
77 | let lanIP
|
78 | poi.on('show-develop-logs', () => {
|
79 | let msg = `\n ${chalk.green('App running at:')}`
|
80 | const isUnspecifiedAddress = unspecifiedAddress(host)
|
81 |
|
82 | const localURL = url.format({
|
83 | protocol: 'http',
|
84 | hostname: isUnspecifiedAddress ? 'localhost' : host,
|
85 | port
|
86 | })
|
87 | msg += `\n${chalk.bold(` - Local: ${localURL}`)}`
|
88 | if (isUnspecifiedAddress) {
|
89 | const lanURL = url.format({
|
90 | protocol: 'http',
|
91 | hostname: lanIP || (lanIP = address.ip()),
|
92 | port
|
93 | })
|
94 | msg += `\n${chalk.dim(` - On Your Network: ${lanURL}`)}`
|
95 | }
|
96 |
|
97 | logger.log(msg + '\n')
|
98 |
|
99 | if (poi.options.open) {
|
100 | opn(
|
101 | url.format({
|
102 | protocol: 'http',
|
103 | hostname: unspecifiedAddress(host) ? 'localhost' : host,
|
104 | port
|
105 | })
|
106 | )
|
107 | }
|
108 | })
|
109 |
|
110 | return {
|
111 | devServer: server
|
112 | }
|
113 | }
|
114 | )
|
115 |
|
116 | command
|
117 | .option('host', {
|
118 | desc: 'Server host'
|
119 | })
|
120 | .option('port', {
|
121 | desc: 'Server port'
|
122 | })
|
123 | }
|