index.js 4.69 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
116
117
#!/usr/bin/env node

/**
 * 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.
 */

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /!\ DO NOT MODIFY THIS FILE /!\
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// create-react-app is installed globally on people's computers. This means
// that it is extremely difficult to have them upgrade the version and
// because there's only one global version installed, it is very prone to
// breaking changes.
//
// The only job of create-react-app is to init the repository and then
// forward all the commands to the local version of create-react-app.
//
// If you need to add a new command, please add it to local-cli/.
//
// The only reason to modify this file is to add more warnings and
// troubleshooting information for the `react init` command.
//
// Do not make breaking changes! We absolutely don't want to have to
// tell people to update their global version of create-react-app.
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /!\ DO NOT MODIFY THIS FILE /!\
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

'use strict';

var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var chalk = require('chalk');
var semver = require('semver');
/**
 * Used arguments:
 *   -v --version - to print current version of create-react-app and create-react-app-scripts dependency
 *   --verbose - to print logs while init
 *   --scripts-version <alternative create-react-app-scripts package> - override default (https://registry.npmjs.org/create-react-app-scripts@latest),
 *      package to install, examples:
 *     - "0.22.0-rc1" - A new app will be created using a specific version of React CLI from npm repo
 *     - "https://registry.npmjs.org/create-react-app-scripts/-/create-react-app-scripts-0.20.0.tgz" - a .tgz archive from any npm repo
 *     - "/Users/home/create-react-app/create-react-app-scripts-0.22.0.tgz" - for package prepared with `npm pack`, useful for e2e tests
 */
var argv = require('minimist')(process.argv.slice(2));

var commands = argv._;
if (commands.length === 0) {
  console.error(
    'Usage: create-react-app <project-name> [--verbose]'
  );
  process.exit(1);
}

if (argv.v || argv.version) {
  console.log('create-react-app: ' + require('./package.json').version);
  process.exit();
}

createApp(commands[0], argv.verbose, argv['scripts-version']);

function createApp(name, verbose, version) {
  if (fs.existsSync(name)) {
    console.log('Directory `' + name + '` already exists. Aborting.');
    process.exit();
  }

  var root = path.resolve(name);
  var appName = path.basename(root);

  console.log(
    'This will walk you through creating a new React app in',
    root
  );

  fs.mkdirSync(root);

  var packageJson = {
    name: appName,
    version: '0.0.1',
    private: true,
  };
  fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson));
  process.chdir(root);

  console.log('Installing create-react-app-scripts package from npm...');

  run(root, appName, version, verbose);
}

function run(root, appName, version, verbose) {
  var args = [
    'install',
    verbose && '--verbose',
    '--save',
    '--save-exact',
    getInstallPackage(version),
  ].filter(function(e) { return e; });
  var proc = spawn('npm', args, {stdio: 'inherit'});
  proc.on('close', function (code) {
    if (code !== 0) {
      console.error('`npm ' + args.join(' ') + '` failed');
      return;
    }

    var scriptsPath = path.resolve(
      process.cwd(),
      'node_modules',
      'create-react-app-scripts',
118
      'scripts',
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
      'init.js'
    );
    var init = require(scriptsPath);
    init(root, appName);
  });
}

function getInstallPackage(version) {
  var packageToInstall = 'create-react-app-scripts';
  var validSemver = semver.valid(version);
  if (validSemver) {
    packageToInstall += '@' + validSemver;
  } else if (version) {
    // for tar.gz or alternative paths
    packageToInstall = version;
  }
  return packageToInstall;
}

function checkNodeVersion() {
  var packageJsonPath = path.resolve(
    process.cwd(),
    'node_modules',
    'create-react-app-scripts',
    'package.json'
  );
  var packageJson = require(packageJsonPath);
  if (!packageJson.engines || !packageJson.engines.node) {
    return;
  }
  if (!semver.satisfies(process.version, packageJson.engines.node)) {
    console.error(
      chalk.red(
        'You are currently running Node %s but React CLI requires %s. ' +
        'Please use a supported version of Node.\n'
      ),
      process.version,
      packageJson.engines.node
    );
  }
}