eject.js 3.76 KB
Newer Older
eanplatter's avatar
eanplatter committed
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * 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.
 */

var fs = require('fs');
var path = require('path');
var rl = require('readline');
var rimrafSync = require('rimraf').sync;
Dan Abramov's avatar
Dan Abramov committed
14
var spawnSync = require('cross-spawn').sync;
eanplatter's avatar
eanplatter committed
15
16
17
18
19
20
21
22
23
24
25
26

var prompt = function(question, cb) {
  var rlInterface = rl.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  rlInterface.question(question + '\n', function(answer) {
    rlInterface.close();
    cb(answer);
  })
}

Dan Abramov's avatar
Dan Abramov committed
27
28
29
30
31
32
prompt('Are you sure you want to eject? This action is permanent. [y/N]', function(answer) {
  var shouldEject = answer && (
    answer.toLowerCase() === 'y' ||
    answer.toLowerCase() === 'yes'
  );
  if (!shouldEject) {
eanplatter's avatar
eanplatter committed
33
34
35
36
37
38
    console.log('Close one! Eject aported.');
    process.exit(1);
  }

  console.log('Ejecting...');
  console.log();
Dan Abramov's avatar
Dan Abramov committed
39

eanplatter's avatar
eanplatter committed
40
41
42
  var selfPath = path.join(__dirname, '..');
  var hostPath = path.join(selfPath, '..', '..');
  var files = [
43
44
45
    path.join('config', 'babel.dev.js'),
    path.join('config', 'babel.prod.js'),
    path.join('config', 'eslint.js'),
46
47
48
    path.join('config', 'webpack.config.dev.js'),
    path.join('config', 'webpack.config.prod.js'),
    path.join('scripts', 'build.js'),
49
50
    path.join('scripts', 'start.js'),
    path.join('scripts', 'openChrome.applescript')
eanplatter's avatar
eanplatter committed
51
52
53
54
  ];

  // Ensure that the host folder is clean and we won't override any files
  files.forEach(function(file) {
Dan Abramov's avatar
Dan Abramov committed
55
56
57
58
59
60
61
62
63
    if (fs.existsSync(path.join(hostPath, file))) {
      console.error(
        '`' + file + '` already exists in your app folder. We cannot ' +
        'continue as you would lose all the changes in that file or directory. ' +
        'Please delete it (maybe make a copy for backup) and run this ' +
        'command again.'
      );
      process.exit(1);
    }
eanplatter's avatar
eanplatter committed
64
65
  });

66
  // Copy the files over
67
  fs.mkdirSync(path.join(hostPath, 'config'));
68
  fs.mkdirSync(path.join(hostPath, 'scripts'));
69

eanplatter's avatar
eanplatter committed
70
  files.forEach(function(file) {
Dan Abramov's avatar
Dan Abramov committed
71
    console.log('Copying ' + file + ' to ' + hostPath);
72
73
74
75
76
77
78
    content = fs
      .readFileSync(path.join(selfPath, file), 'utf8')
      // Remove license header from JS
      .replace(/^\/\*\*(\*(?!\/)|[^*])*\*\//, '')
      // Remove license header from AppleScript
      .replace(/^--.*\n/gm, '')
      .trim() + '\n';
Dan Abramov's avatar
Dan Abramov committed
79
    fs.writeFileSync(path.join(hostPath, file), content);
eanplatter's avatar
eanplatter committed
80
81
82
83
84
85
  });
  console.log();

  var selfPackage = require(path.join(selfPath, 'package.json'));
  var hostPackage = require(path.join(hostPath, 'package.json'));

86
87
  console.log('Removing dependency: react-scripts');
  delete hostPackage.devDependencies['react-scripts'];
eanplatter's avatar
eanplatter committed
88
89

  Object.keys(selfPackage.dependencies).forEach(function (key) {
Dan Abramov's avatar
Dan Abramov committed
90
91
92
93
94
95
    // For some reason optionalDependencies end up in dependencies after install
    if (selfPackage.optionalDependencies[key]) {
      return;
    }
    console.log('Adding dependency: ' + key);
    hostPackage.devDependencies[key] = selfPackage.dependencies[key];
eanplatter's avatar
eanplatter committed
96
97
98
99
  });

  console.log('Updating scripts');
  Object.keys(hostPackage.scripts).forEach(function (key) {
100
    hostPackage.scripts[key] = 'node ./scripts/' + key + '.js'
eanplatter's avatar
eanplatter committed
101
102
103
104
105
  });
  delete hostPackage.scripts['eject'];

  console.log('Writing package.json');
  fs.writeFileSync(
Dan Abramov's avatar
Dan Abramov committed
106
107
    path.join(hostPath, 'package.json'),
    JSON.stringify(hostPackage, null, 2)
eanplatter's avatar
eanplatter committed
108
109
110
111
112
113
  );
  console.log();

  console.log('Running npm install...');
  rimrafSync(selfPath);
  spawnSync('npm', ['install'], {stdio: 'inherit'});
Dan Abramov's avatar
Dan Abramov committed
114
  console.log('Ejected successfully!');
eanplatter's avatar
eanplatter committed
115
116
  console.log();

Dan Abramov's avatar
Dan Abramov committed
117
118
119
  console.log('Please consider sharing why you ejected in this survey:');
  console.log('  http://goo.gl/forms/Bi6CZjk1EqsdelXk1');
  console.log();
eanplatter's avatar
eanplatter committed
120
});