start.js 3.81 KB
Newer Older
Christopher Chedeau's avatar
Christopher Chedeau committed
1
2
3
4
5
6
7
8
9
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

10
11
process.env.NODE_ENV = 'development';

12
var chalk = require('chalk');
Dan Abramov's avatar
Dan Abramov committed
13
14
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
15
var config = require('../config/webpack.config.dev');
Christopher Chedeau's avatar
.    
Christopher Chedeau committed
16
var execSync = require('child_process').execSync;
17
var opn = require('opn');
Dan Abramov's avatar
Dan Abramov committed
18

19
20
// TODO: hide this behind a flag and eliminate dead code on eject.
// This shouldn't be exposed to the user.
Dan Abramov's avatar
Dan Abramov committed
21
22
23
var handleCompile;
if (process.argv[2] === '--smoke-test') {
  handleCompile = function (err, stats) {
24
    if (err || stats.hasErrors() || stats.hasWarnings()) {
Dan Abramov's avatar
Dan Abramov committed
25
26
27
28
29
30
31
      process.exit(1);
    } else {
      process.exit(0);
    }
  };
}

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
var friendlySyntaxErrorLabel = 'Syntax error:';

function isLikelyASyntaxError(message) {
  return message.indexOf(friendlySyntaxErrorLabel) !== -1;
}

// This is a little hacky.
// It would be easier if webpack provided a rich error object.

function formatMessage(message) {
  return message
    // Make some common errors shorter:
    .replace(
      // Babel syntax error
      'Module build failed: SyntaxError:',
      friendlySyntaxErrorLabel
    )
    .replace(
      // Webpack file not found error
      /Module not found: Error: Cannot resolve 'file' or 'directory'/,
      'Module not found:'
    )
    // Internal stacks are generally useless so we strip them
    .replace(/^\s*at\s.*\(.*:\d+:\d+\.*\).*\n/gm, '') // at ... (...:x:y)
    // Webpack loader names obscure CSS filenames
    .replace('./~/css-loader!./~/postcss-loader!', '');
}

var compiler = webpack(config, handleCompile);
compiler.plugin('done', function (stats) {
  // Clear the console and reset the cursor
  process.stdout.write('\x1B[2J\x1B[0f');

  var hasErrors = stats.hasErrors();
  var hasWarnings = stats.hasWarnings();

  if (!hasErrors && !hasWarnings) {
    console.log(chalk.green('Compiled successfully!'));
    console.log();
    console.log('The app is running at http://localhost:3000/');
    console.log();
    return;
  }

  var json = stats.toJson();
  var formattedErrors = json.errors.map(message =>
    'Error in ' + formatMessage(message)
  );
  var formattedWarnings = json.warnings.map(message =>
    'Warning in ' + formatMessage(message)
  );

  if (hasErrors) {
    console.log(chalk.red('There were errors compiling.'));
    console.log();
    if (formattedErrors.some(isLikelyASyntaxError)) {
      // If there are any syntax errors, show just them.
      // This prevents a confusing ESLint parsing error
      // preceding a much more useful Babel syntax error.
      formattedErrors = formattedErrors.filter(isLikelyASyntaxError);
    }
    formattedErrors.forEach(message => {
      console.log(message);
      console.log();
    });
    // If errors exist, ignore warnings.
    return;
  }

  if (hasWarnings) {
    console.log(chalk.yellow('Compiled with warnings.'));
    console.log();
    formattedWarnings.forEach(message => {
      console.log(message);
      console.log();
    });

    console.log('You may use special comments to disable some warnings.');
    console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.');
    console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.');
  }
});

new WebpackDevServer(compiler, {
Dan Abramov's avatar
Dan Abramov committed
116
  historyApiFallback: true,
117
  hot: true, // Note: only CSS is currently hot reloaded
118
119
  publicPath: config.output.publicPath,
  quiet: true
Dan Abramov's avatar
Dan Abramov committed
120
121
122
123
}).listen(3000, 'localhost', function (err, result) {
  if (err) {
    return console.log(err);
  }
Christopher Chedeau's avatar
.    
Christopher Chedeau committed
124

125
  console.log('Starting the development server...');
126
  opn('http://localhost:3000/');
Dan Abramov's avatar
Dan Abramov committed
127
});