eject.js 4.32 KB
Newer Older
eanplatter's avatar
eanplatter 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.
 */

Christoph Pojer's avatar
Christoph Pojer committed
10
var createJestConfig = require('./utils/create-jest-config');
eanplatter's avatar
eanplatter committed
11
12
var fs = require('fs');
var path = require('path');
Christoph Pojer's avatar
Christoph Pojer committed
13
var prompt = require('./utils/prompt');
eanplatter's avatar
eanplatter committed
14
var rimrafSync = require('rimraf').sync;
Dan Abramov's avatar
Dan Abramov committed
15
var spawnSync = require('cross-spawn').sync;
eanplatter's avatar
eanplatter committed
16

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

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

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

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

64
  // Copy the files over
65
66
  fs.mkdirSync(path.join(appPath, 'config'));
  fs.mkdirSync(path.join(appPath, 'config', 'flow'));
Christoph Pojer's avatar
Christoph Pojer committed
67
  fs.mkdirSync(path.join(appPath, 'config', 'jest'));
68
  fs.mkdirSync(path.join(appPath, 'scripts'));
69
  fs.mkdirSync(path.join(appPath, 'scripts', 'utils'));
70

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

84
85
  var ownPackage = require(path.join(ownPath, 'package.json'));
  var appPackage = require(path.join(appPath, 'package.json'));
eanplatter's avatar
eanplatter committed
86

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

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

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

Christoph Pojer's avatar
Christoph Pojer committed
105
106
107
108
109
  appPackage.scripts.test = 'jest';
  appPackage.jest = createJestConfig(
    filePath => path.join('<rootDir>', filePath)
  );

110
  // explicitly specify ESLint config path for editor plugins
111
  appPackage.eslintConfig = {
112
113
114
    extends: './config/eslint.js',
  };

eanplatter's avatar
eanplatter committed
115
116
  console.log('Writing package.json');
  fs.writeFileSync(
117
118
    path.join(appPath, 'package.json'),
    JSON.stringify(appPackage, null, 2)
eanplatter's avatar
eanplatter committed
119
120
121
122
  );
  console.log();

  console.log('Running npm install...');
123
  rimrafSync(ownPath);
eanplatter's avatar
eanplatter committed
124
  spawnSync('npm', ['install'], {stdio: 'inherit'});
Dan Abramov's avatar
Dan Abramov committed
125
  console.log('Ejected successfully!');
eanplatter's avatar
eanplatter committed
126
127
  console.log();

Dan Abramov's avatar
Dan Abramov committed
128
129
130
  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
131
});