[6a3a178] | 1 | #!/usr/bin/env node
|
---|
| 2 |
|
---|
| 3 | 'use strict';
|
---|
| 4 |
|
---|
| 5 | /* eslint-disable no-shadow, no-console */
|
---|
| 6 |
|
---|
| 7 | const fs = require('fs');
|
---|
| 8 | const net = require('net');
|
---|
| 9 | const debug = require('debug')('webpack-dev-server');
|
---|
| 10 | const importLocal = require('import-local');
|
---|
| 11 | const yargs = require('yargs');
|
---|
| 12 | const webpack = require('webpack');
|
---|
| 13 | const Server = require('../lib/Server');
|
---|
| 14 | const setupExitSignals = require('../lib/utils/setupExitSignals');
|
---|
| 15 | const colors = require('../lib/utils/colors');
|
---|
| 16 | const processOptions = require('../lib/utils/processOptions');
|
---|
| 17 | const createLogger = require('../lib/utils/createLogger');
|
---|
| 18 | const getVersions = require('../lib/utils/getVersions');
|
---|
| 19 | const options = require('./options');
|
---|
| 20 |
|
---|
| 21 | let server;
|
---|
| 22 | const 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.
|
---|
| 29 | setupExitSignals(serverData);
|
---|
| 30 |
|
---|
| 31 | // Prefer the local installation of webpack-dev-server
|
---|
| 32 | if (importLocal(__filename)) {
|
---|
| 33 | debug('Using local install of webpack-dev-server');
|
---|
| 34 |
|
---|
| 35 | return;
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | try {
|
---|
| 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 |
|
---|
| 51 | yargs.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'
|
---|
| 56 | let configYargsPath;
|
---|
| 57 | try {
|
---|
| 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
|
---|
| 65 | require(configYargsPath)(yargs);
|
---|
| 66 |
|
---|
| 67 | // It is important that this is done after the webpack yargs config,
|
---|
| 68 | // so it overrides webpack's version info.
|
---|
| 69 | yargs.version(getVersions());
|
---|
| 70 | yargs.options(options);
|
---|
| 71 |
|
---|
| 72 | const argv = yargs.argv;
|
---|
| 73 |
|
---|
| 74 | // webpack-cli@3.3 path : 'webpack-cli/bin/utils/convert-argv'
|
---|
| 75 | let convertArgvPath;
|
---|
| 76 | try {
|
---|
| 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
|
---|
| 84 | const config = require(convertArgvPath)(yargs, argv, {
|
---|
| 85 | outputFilename: '/bundle.js',
|
---|
| 86 | });
|
---|
| 87 |
|
---|
| 88 | function 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 |
|
---|
| 165 | processOptions(config, argv, (config, options) => {
|
---|
| 166 | startDevServer(config, options);
|
---|
| 167 | });
|
---|