1 | 'use strict'
|
2 |
|
3 | process.env.BABEL_ENV = 'development'
|
4 | process.env.NODE_ENV = 'development'
|
5 |
|
6 | process.on('unhandledRejection', err => {
|
7 | throw err
|
8 | })
|
9 |
|
10 | const config = require('../config')
|
11 | const { getFreePort } = require('../libs/utils')
|
12 | const getEntry = require('../libs/entry')
|
13 | const maraConf = require(config.paths.marauder)
|
14 | const clearConsole = require('react-dev-utils/clearConsole')
|
15 |
|
16 |
|
17 | const isInteractive = process.stdout.isTTY
|
18 |
|
19 | const webpack = require('webpack')
|
20 | const getWebpackConfig = require('../webpack/webpack.dev.conf')
|
21 | const prehandleConfig = require('../libs/prehandleConfig')
|
22 | const progressHandler = require('../libs/buildProgress')
|
23 | const DEFAULT_PORT = parseInt(process.env.PORT, 10) || config.dev.port
|
24 | const PROTOCOL = maraConf.https === true ? 'https' : 'http'
|
25 |
|
26 |
|
27 |
|
28 | const proxyTable = config.dev.proxyTable
|
29 |
|
30 | function getCompiler(webpackConf, { entry, port } = {}) {
|
31 | const openBrowser = require('react-dev-utils/openBrowser')
|
32 | const hostUri = getServerHostUri(webpackConf.devServer.host, port)
|
33 | let isFirstCompile = true
|
34 |
|
35 |
|
36 | addHotDevClient(webpackConf.entry)
|
37 |
|
38 | const compiler = webpack(webpackConf)
|
39 |
|
40 | compiler.apply(
|
41 | new webpack.ProgressPlugin((...args) => {
|
42 | if (isFirstCompile) progressHandler.apply(null, args)
|
43 | })
|
44 | )
|
45 |
|
46 | compiler.plugin('after-emit', (compilation, callback) => {
|
47 | if (isFirstCompile) {
|
48 |
|
49 | isInteractive && clearConsole()
|
50 | }
|
51 | callback()
|
52 | })
|
53 |
|
54 | compiler.plugin('done', stats => {
|
55 | const messages = stats.toJson({}, true)
|
56 |
|
57 |
|
58 | if (messages.errors.length) return
|
59 |
|
60 | if (isFirstCompile) {
|
61 | console.log(`> Listening at ${hostUri}\n`)
|
62 | openBrowser(getServerURL(hostUri, entry))
|
63 | isFirstCompile = false
|
64 | }
|
65 | })
|
66 |
|
67 | return compiler
|
68 | }
|
69 |
|
70 | function addHotDevClient(entryConf) {
|
71 | Object.keys(entryConf).forEach(entry => {
|
72 |
|
73 | entryConf[entry] = [
|
74 | require.resolve('react-dev-utils/webpackHotDevClient')
|
75 | ].concat(entryConf[entry])
|
76 | })
|
77 | }
|
78 |
|
79 | function createDevServer(webpackConf, opt) {
|
80 | const DevServer = require('webpack-dev-server')
|
81 | const serverConf = webpackConf.devServer
|
82 | const compiler = getCompiler(webpackConf, opt)
|
83 |
|
84 | serverConf.https = PROTOCOL === 'https'
|
85 |
|
86 |
|
87 | serverConf.disableHostCheck = !proxyTable
|
88 |
|
89 | return new DevServer(compiler, serverConf)
|
90 | }
|
91 |
|
92 | function getServerHostUri(host, port) {
|
93 | return `${PROTOCOL}://${host || 'localhost'}:${port}`
|
94 | }
|
95 |
|
96 | function getServerURL(hostUri, entry) {
|
97 | let publicDevPath = config.dev.assetsPublicPath
|
98 |
|
99 |
|
100 |
|
101 | publicDevPath = publicDevPath.startsWith('/') ? publicDevPath : '/'
|
102 |
|
103 | return `${hostUri + publicDevPath + entry}.html`
|
104 | }
|
105 |
|
106 | async function server(entryInput) {
|
107 | console.log('> Starting development server...')
|
108 |
|
109 | const webpackConf = prehandleConfig('dev', getWebpackConfig(entryInput))
|
110 | const port = await getFreePort(DEFAULT_PORT)
|
111 | const devServer = createDevServer(webpackConf, {
|
112 | entry: entryInput.entry,
|
113 | port
|
114 | })
|
115 |
|
116 | ;['SIGINT', 'SIGTERM'].forEach(sig => {
|
117 | process.on(sig, () => {
|
118 | devServer.close()
|
119 | process.exit()
|
120 | })
|
121 | })
|
122 |
|
123 |
|
124 | return devServer.listen(port, '0.0.0.0', err => {
|
125 | if (err) return console.log(err)
|
126 | })
|
127 | }
|
128 |
|
129 | module.exports = args => {
|
130 | return getEntry(args).then(server)
|
131 | }
|