UNPKG

4.68 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3'use strict';
4
5/* eslint-disable no-shadow, no-console */
6
7const fs = require('fs');
8const net = require('net');
9const debug = require('debug')('webpack-dev-server');
10const importLocal = require('import-local');
11const yargs = require('yargs');
12const webpack = require('webpack');
13const Server = require('../lib/Server');
14const setupExitSignals = require('../lib/utils/setupExitSignals');
15const colors = require('../lib/utils/colors');
16const processOptions = require('../lib/utils/processOptions');
17const createLogger = require('../lib/utils/createLogger');
18const getVersions = require('../lib/utils/getVersions');
19const options = require('./options');
20
21let server;
22const serverData = {
23 server: null,
24};
25// we must pass an object that contains the server object as a property so that
26// we can update this server property later, and setupExitSignals will be able to
27// recognize that the server has been instantiated, because we will set
28// serverData.server to the new server object.
29setupExitSignals(serverData);
30
31// Prefer the local installation of webpack-dev-server
32if (importLocal(__filename)) {
33 debug('Using local install of webpack-dev-server');
34
35 return;
36}
37
38try {
39 require.resolve('webpack-cli');
40} catch (err) {
41 console.error('The CLI moved into a separate package: webpack-cli');
42 console.error(
43 "Please install 'webpack-cli' in addition to webpack itself to use the CLI"
44 );
45 console.error('-> When using npm: npm i -D webpack-cli');
46 console.error('-> When using yarn: yarn add -D webpack-cli');
47
48 process.exitCode = 1;
49}
50
51yargs.usage(
52 `${getVersions()}\nUsage: https://webpack.js.org/configuration/dev-server/`
53);
54
55// webpack-cli@3.3 path : 'webpack-cli/bin/config/config-yargs'
56let configYargsPath;
57try {
58 require.resolve('webpack-cli/bin/config/config-yargs');
59 configYargsPath = 'webpack-cli/bin/config/config-yargs';
60} catch (e) {
61 configYargsPath = 'webpack-cli/bin/config-yargs';
62}
63// eslint-disable-next-line import/no-extraneous-dependencies
64// eslint-disable-next-line import/no-dynamic-require
65require(configYargsPath)(yargs);
66
67// It is important that this is done after the webpack yargs config,
68// so it overrides webpack's version info.
69yargs.version(getVersions());
70yargs.options(options);
71
72const argv = yargs.argv;
73
74// webpack-cli@3.3 path : 'webpack-cli/bin/utils/convert-argv'
75let convertArgvPath;
76try {
77 require.resolve('webpack-cli/bin/utils/convert-argv');
78 convertArgvPath = 'webpack-cli/bin/utils/convert-argv';
79} catch (e) {
80 convertArgvPath = 'webpack-cli/bin/convert-argv';
81}
82// eslint-disable-next-line import/no-extraneous-dependencies
83// eslint-disable-next-line import/no-dynamic-require
84const config = require(convertArgvPath)(yargs, argv, {
85 outputFilename: '/bundle.js',
86});
87
88function startDevServer(config, options) {
89 const log = createLogger(options);
90
91 let compiler;
92
93 try {
94 compiler = webpack(config);
95 } catch (err) {
96 if (err instanceof webpack.WebpackOptionsValidationError) {
97 log.error(colors.error(options.stats.colors, err.message));
98 // eslint-disable-next-line no-process-exit
99 process.exit(1);
100 }
101
102 throw err;
103 }
104
105 try {
106 server = new Server(compiler, options, log);
107 serverData.server = server;
108 } catch (err) {
109 if (err.name === 'ValidationError') {
110 log.error(colors.error(options.stats.colors, err.message));
111 // eslint-disable-next-line no-process-exit
112 process.exit(1);
113 }
114
115 throw err;
116 }
117
118 if (options.socket) {
119 server.listeningApp.on('error', (e) => {
120 if (e.code === 'EADDRINUSE') {
121 const clientSocket = new net.Socket();
122
123 clientSocket.on('error', (err) => {
124 if (err.code === 'ECONNREFUSED') {
125 // No other server listening on this socket so it can be safely removed
126 fs.unlinkSync(options.socket);
127
128 server.listen(options.socket, options.host, (error) => {
129 if (error) {
130 throw error;
131 }
132 });
133 }
134 });
135
136 clientSocket.connect({ path: options.socket }, () => {
137 throw new Error('This socket is already used');
138 });
139 }
140 });
141
142 server.listen(options.socket, options.host, (err) => {
143 if (err) {
144 throw err;
145 }
146
147 // chmod 666 (rw rw rw)
148 const READ_WRITE = 438;
149
150 fs.chmod(options.socket, READ_WRITE, (err) => {
151 if (err) {
152 throw err;
153 }
154 });
155 });
156 } else {
157 server.listen(options.port, options.host, (err) => {
158 if (err) {
159 throw err;
160 }
161 });
162 }
163}
164
165processOptions(config, argv, (config, options) => {
166 startDevServer(config, options);
167});