eject.js 3.92 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
    path.join('scripts', 'utils', 'chrome.applescript'),
43
    path.join('scripts', 'utils', 'detectPort.js'),
44
    path.join('scripts', 'utils', 'prompt.js')
eanplatter's avatar
eanplatter committed
45
46
  ];

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

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

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

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

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

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

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

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

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

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

Dan Abramov's avatar
Dan Abramov committed
118
119
120
  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
121
});