eject.js 3.87 KB
Newer Older
eanplatter's avatar
eanplatter committed
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 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 rimrafSync = require('rimraf').sync;
Dan Abramov's avatar
Dan Abramov committed
13
var spawnSync = require('cross-spawn').sync;
14
var prompt = require('./utils/prompt');
eanplatter's avatar
eanplatter committed
15

16
17
18
19
prompt(
  'Are you sure you want to eject? This action is permanent.',
  false
).then(shouldEject => {
Dan Abramov's avatar
Dan Abramov committed
20
  if (!shouldEject) {
Tyler McGinnis's avatar
Tyler McGinnis committed
21
    console.log('Close one! Eject aborted.');
eanplatter's avatar
eanplatter committed
22
23
24
25
26
    process.exit(1);
  }

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

28
29
  var ownPath = path.join(__dirname, '..');
  var appPath = path.join(ownPath, '..', '..');
eanplatter's avatar
eanplatter committed
30
  var files = [
31
32
    path.join('config', 'babel.dev.js'),
    path.join('config', 'babel.prod.js'),
Dan Abramov's avatar
Dan Abramov committed
33
34
    path.join('config', 'flow', 'css.js.flow'),
    path.join('config', 'flow', 'file.js.flow'),
35
    path.join('config', 'eslint.js'),
36
    path.join('config', 'paths.js'),
37
    path.join('config', 'polyfills.js'),
38
39
40
    path.join('config', 'webpack.config.dev.js'),
    path.join('config', 'webpack.config.prod.js'),
    path.join('scripts', 'build.js'),
41
    path.join('scripts', 'start.js'),
42
43
    path.join('scripts', 'utils', 'chrome.applescript'),
    path.join('scripts', 'utils', 'prompt.js')
eanplatter's avatar
eanplatter committed
44
45
  ];

46
  // Ensure that the app folder is clean and we won't override any files
eanplatter's avatar
eanplatter committed
47
  files.forEach(function(file) {
48
    if (fs.existsSync(path.join(appPath, file))) {
Dan Abramov's avatar
Dan Abramov committed
49
50
51
52
53
54
55
56
      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
57
58
  });

59
  // Copy the files over
60
61
62
  fs.mkdirSync(path.join(appPath, 'config'));
  fs.mkdirSync(path.join(appPath, 'config', 'flow'));
  fs.mkdirSync(path.join(appPath, 'scripts'));
63
  fs.mkdirSync(path.join(appPath, 'scripts', 'utils'));
64

eanplatter's avatar
eanplatter committed
65
  files.forEach(function(file) {
66
    console.log('Copying ' + file + ' to ' + appPath);
67
    var content = fs
68
      .readFileSync(path.join(ownPath, file), 'utf8')
69
70
71
72
73
      // Remove license header from JS
      .replace(/^\/\*\*(\*(?!\/)|[^*])*\*\//, '')
      // Remove license header from AppleScript
      .replace(/^--.*\n/gm, '')
      .trim() + '\n';
74
    fs.writeFileSync(path.join(appPath, file), content);
eanplatter's avatar
eanplatter committed
75
76
77
  });
  console.log();

78
79
  var ownPackage = require(path.join(ownPath, 'package.json'));
  var appPackage = require(path.join(appPath, 'package.json'));
eanplatter's avatar
eanplatter committed
80

81
  console.log('Removing dependency: react-scripts');
82
  delete appPackage.devDependencies['react-scripts'];
eanplatter's avatar
eanplatter committed
83

84
  Object.keys(ownPackage.dependencies).forEach(function (key) {
Dan Abramov's avatar
Dan Abramov committed
85
    // For some reason optionalDependencies end up in dependencies after install
86
    if (ownPackage.optionalDependencies[key]) {
Dan Abramov's avatar
Dan Abramov committed
87
88
89
      return;
    }
    console.log('Adding dependency: ' + key);
90
    appPackage.devDependencies[key] = ownPackage.dependencies[key];
eanplatter's avatar
eanplatter committed
91
92
93
  });

  console.log('Updating scripts');
94
95
  Object.keys(appPackage.scripts).forEach(function (key) {
    appPackage.scripts[key] = 'node ./scripts/' + key + '.js'
eanplatter's avatar
eanplatter committed
96
  });
97
  delete appPackage.scripts['eject'];
eanplatter's avatar
eanplatter committed
98

99
  // explicitly specify ESLint config path for editor plugins
100
  appPackage.eslintConfig = {
101
102
103
    extends: './config/eslint.js',
  };

eanplatter's avatar
eanplatter committed
104
105
  console.log('Writing package.json');
  fs.writeFileSync(
106
107
    path.join(appPath, 'package.json'),
    JSON.stringify(appPackage, null, 2)
eanplatter's avatar
eanplatter committed
108
109
110
111
  );
  console.log();

  console.log('Running npm install...');
112
  rimrafSync(ownPath);
eanplatter's avatar
eanplatter committed
113
  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
});