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 ora = require('ora')
|
11 | const webpack = require('webpack')
|
12 | const { getFreePort, localIp } = require('@mara/devkit')
|
13 | const config = require('../config')
|
14 | const getContext = require('../config/context')
|
15 | const getEntry = require('../lib/entry')
|
16 | const getWebpackConfig = require('../webpack/webpack.dev.conf')
|
17 | const createDevServerConfig = require('../webpack/webpack.devServer.conf')
|
18 | const prehandleConfig = require('../lib/prehandleConfig')
|
19 | const DevServerPlugin = require('../lib/DevServerPlugin')
|
20 | const DEFAULT_PORT = parseInt(process.env.PORT, 10) || config.devServer.port
|
21 | const PROTOCOL = config.devServer.https === true ? 'https' : 'http'
|
22 | const spinner = ora('Starting development server...')
|
23 |
|
24 | function getDevCompiler(webpackConf) {
|
25 | addDevClientToEntry(webpackConf, [
|
26 |
|
27 | require.resolve('../lib/hotDevClient')
|
28 | ])
|
29 |
|
30 | return webpack(webpackConf)
|
31 | }
|
32 |
|
33 | function addDevClientToEntry(config, devClient) {
|
34 | const { entry } = config
|
35 |
|
36 | if (typeof entry === 'object' && !Array.isArray(entry)) {
|
37 | Object.keys(entry).forEach(key => {
|
38 | entry[key] = devClient.concat(entry[key])
|
39 | })
|
40 | } else if (typeof entry === 'function') {
|
41 | config.entry = entry(devClient)
|
42 | } else {
|
43 | config.entry = devClient.concat(entry)
|
44 | }
|
45 | }
|
46 |
|
47 | function createDevServer(webpackConf, opts) {
|
48 | const host = localIp()
|
49 | const proxyConfig = config.devServer.proxy
|
50 | const serverConf = createDevServerConfig({
|
51 | entry: opts.entry,
|
52 | host: host,
|
53 | proxy: proxyConfig,
|
54 | protocol: PROTOCOL,
|
55 | publicPath: opts.publicPath
|
56 | })
|
57 | const compiler = getDevCompiler(webpackConf)
|
58 |
|
59 |
|
60 |
|
61 | new DevServerPlugin({
|
62 | port: opts.port,
|
63 | entry: opts.entry,
|
64 | useYarn: config.useYarn,
|
65 | spinner,
|
66 | protocol: PROTOCOL,
|
67 | root: config.paths.app,
|
68 | host: host,
|
69 | openBrowser: config.devServer.open,
|
70 | useTypeScript: config.useTypeScript,
|
71 | onTsError(severity, errors) {
|
72 | devServer.sockWrite(devServer.sockets, `${severity}s`, errors)
|
73 | }
|
74 | }).apply(compiler)
|
75 |
|
76 | const DevServer = require('webpack-dev-server')
|
77 | const devServer = new DevServer(compiler, serverConf)
|
78 |
|
79 | return devServer
|
80 | }
|
81 |
|
82 | async function setup(entryInput) {
|
83 | const context = await getContext({
|
84 | version: require(config.paths.packageJson).version,
|
85 | view: entryInput.entry
|
86 | })
|
87 |
|
88 | return { context, ...entryInput }
|
89 | }
|
90 |
|
91 | async function server({ context, entry }) {
|
92 | spinner.start()
|
93 |
|
94 | let webpackConfig = getWebpackConfig(context, spinner)
|
95 |
|
96 | webpackConfig = prehandleConfig({
|
97 | command: 'dev',
|
98 | webpackConfig,
|
99 | entry: entry
|
100 | })
|
101 |
|
102 | const port = await getFreePort(DEFAULT_PORT)
|
103 | const devServer = createDevServer(webpackConfig, {
|
104 | entry,
|
105 | port,
|
106 | publicPath: context.publicPath
|
107 | })
|
108 |
|
109 |
|
110 | ;['SIGINT', 'SIGTERM'].forEach(sig => {
|
111 | process.on(sig, () => {
|
112 | devServer.close()
|
113 | process.exit()
|
114 | })
|
115 | })
|
116 |
|
117 |
|
118 | return devServer.listen(port, '0.0.0.0', err => {
|
119 | if (err) return console.log(err)
|
120 | })
|
121 | }
|
122 |
|
123 | module.exports = function runServe(argv) {
|
124 | return getEntry(argv)
|
125 | .then(setup)
|
126 | .then(server)
|
127 | }
|