34
34
35
35
'use strict' ;
36
36
37
- const validateProjectName = require ( 'validate-npm-package-name' ) ;
38
37
const chalk = require ( 'chalk' ) ;
39
38
const commander = require ( 'commander' ) ;
39
+ const dns = require ( 'dns' ) ;
40
+ const envinfo = require ( 'envinfo' ) ;
41
+ const execSync = require ( 'child_process' ) . execSync ;
40
42
const fs = require ( 'fs-extra' ) ;
43
+ const hyperquest = require ( 'hyperquest' ) ;
44
+ const inquirer = require ( 'inquirer' ) ;
45
+ const os = require ( 'os' ) ;
41
46
const path = require ( 'path' ) ;
42
- const execSync = require ( 'child_process' ) . execSync ;
43
- const spawn = require ( 'cross-spawn' ) ;
44
47
const semver = require ( 'semver' ) ;
45
- const dns = require ( 'dns ' ) ;
48
+ const spawn = require ( 'cross-spawn ' ) ;
46
49
const tmp = require ( 'tmp' ) ;
47
50
const unpack = require ( 'tar-pack' ) . unpack ;
48
51
const url = require ( 'url' ) ;
49
- const hyperquest = require ( 'hyperquest' ) ;
50
- const envinfo = require ( 'envinfo' ) ;
51
- const os = require ( 'os' ) ;
52
+ const validateProjectName = require ( 'validate-npm-package-name' ) ;
52
53
53
54
const packageJson = require ( './package.json' ) ;
54
55
@@ -135,7 +136,6 @@ if (program.info) {
135
136
npmGlobalPackages : [ 'create-react-app' ] ,
136
137
} ,
137
138
{
138
- clipboard : false ,
139
139
duplicates : true ,
140
140
showNotFound : true ,
141
141
}
@@ -222,13 +222,13 @@ function createApp(
222
222
process . exit ( 1 ) ;
223
223
}
224
224
225
- if ( ! semver . satisfies ( process . version , '>=6.0 .0' ) ) {
225
+ if ( ! semver . satisfies ( process . version , '>=8.10 .0' ) ) {
226
226
console . log (
227
227
chalk . yellow (
228
228
`You are using Node ${
229
229
process . version
230
230
} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
231
- `Please update to Node 6 or higher for a better, fully supported experience.\n`
231
+ `Please update to Node 8.10 or higher for a better, fully supported experience.\n`
232
232
)
233
233
) ;
234
234
// Fall back to latest supported react-scripts on Node 4
@@ -244,7 +244,7 @@ function createApp(
244
244
`You are using npm ${
245
245
npmInfo . npmVersion
246
246
} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
247
- `Please update to npm 3 or higher for a better, fully supported experience.\n`
247
+ `Please update to npm 5 or higher for a better, fully supported experience.\n`
248
248
)
249
249
) ;
250
250
}
@@ -255,11 +255,13 @@ function createApp(
255
255
const yarnInfo = checkYarnVersion ( ) ;
256
256
if ( ! yarnInfo . hasMinYarnPnp ) {
257
257
if ( yarnInfo . yarnVersion ) {
258
- chalk . yellow (
259
- `You are using Yarn ${
260
- yarnInfo . yarnVersion
261
- } together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
262
- `Please update to Yarn 1.12 or higher for a better, fully supported experience.\n`
258
+ console . log (
259
+ chalk . yellow (
260
+ `You are using Yarn ${
261
+ yarnInfo . yarnVersion
262
+ } together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
263
+ `Please update to Yarn 1.12 or higher for a better, fully supported experience.\n`
264
+ )
263
265
) ;
264
266
}
265
267
// 1.11 had an issue with webpack-dev-middleware, so better not use PnP with it (never reached stable, but still)
@@ -380,112 +382,120 @@ function run(
380
382
usePnp ,
381
383
useTypescript
382
384
) {
383
- const packageToInstall = getInstallPackage ( version , originalDirectory ) ;
384
- const allDependencies = [ 'react' , 'react-dom' , packageToInstall ] ;
385
- if ( useTypescript ) {
386
- // TODO: get user's node version instead of installing latest
387
- allDependencies . push (
388
- '@types/node' ,
389
- '@types/react' ,
390
- '@types/react-dom' ,
391
- '@types/jest' ,
392
- 'typescript'
393
- ) ;
394
- }
395
-
396
- console . log ( 'Installing packages. This might take a couple of minutes.' ) ;
397
- getPackageName ( packageToInstall )
398
- . then ( packageName =>
399
- checkIfOnline ( useYarn ) . then ( isOnline => ( {
400
- isOnline : isOnline ,
401
- packageName : packageName ,
402
- } ) )
403
- )
404
- . then ( info => {
405
- const isOnline = info . isOnline ;
406
- const packageName = info . packageName ;
407
- console . log (
408
- `Installing ${ chalk . cyan ( 'react' ) } , ${ chalk . cyan (
409
- 'react-dom'
410
- ) } , and ${ chalk . cyan ( packageName ) } ...`
385
+ getInstallPackage ( version , originalDirectory ) . then ( packageToInstall => {
386
+ const allDependencies = [ 'react' , 'react-dom' , packageToInstall ] ;
387
+ if ( useTypescript ) {
388
+ allDependencies . push (
389
+ // TODO: get user's node version instead of installing latest
390
+ '@types/node' ,
391
+ '@types/react' ,
392
+ '@types/react-dom' ,
393
+ // TODO: get version of Jest being used instead of installing latest
394
+ '@types/jest' ,
395
+ 'typescript'
411
396
) ;
412
- console . log ( ) ;
413
-
414
- return install (
415
- root ,
416
- useYarn ,
417
- usePnp ,
418
- allDependencies ,
419
- verbose ,
420
- isOnline
421
- ) . then ( ( ) => packageName ) ;
422
- } )
423
- . then ( async packageName => {
424
- checkNodeVersion ( packageName ) ;
425
- setCaretRangeForRuntimeDeps ( packageName ) ;
426
-
427
- const pnpPath = path . resolve ( process . cwd ( ) , '.pnp.js' ) ;
428
-
429
- const nodeArgs = fs . existsSync ( pnpPath ) ? [ '--require' , pnpPath ] : [ ] ;
430
-
431
- await executeNodeScript (
432
- {
433
- cwd : process . cwd ( ) ,
434
- args : nodeArgs ,
435
- } ,
436
- [ root , appName , verbose , originalDirectory , template ] ,
437
- `
397
+ }
398
+
399
+ console . log ( 'Installing packages. This might take a couple of minutes.' ) ;
400
+ getPackageName ( packageToInstall )
401
+ . then ( packageName =>
402
+ checkIfOnline ( useYarn ) . then ( isOnline => ( {
403
+ isOnline : isOnline ,
404
+ packageName : packageName ,
405
+ } ) )
406
+ )
407
+ . then ( info => {
408
+ const isOnline = info . isOnline ;
409
+ const packageName = info . packageName ;
410
+ console . log (
411
+ `Installing ${ chalk . cyan ( 'react' ) } , ${ chalk . cyan (
412
+ 'react-dom'
413
+ ) } , and ${ chalk . cyan ( packageName ) } ...`
414
+ ) ;
415
+ console . log ( ) ;
416
+
417
+ return install (
418
+ root ,
419
+ useYarn ,
420
+ usePnp ,
421
+ allDependencies ,
422
+ verbose ,
423
+ isOnline
424
+ ) . then ( ( ) => packageName ) ;
425
+ } )
426
+ . then ( async packageName => {
427
+ checkNodeVersion ( packageName ) ;
428
+ setCaretRangeForRuntimeDeps ( packageName ) ;
429
+
430
+ const pnpPath = path . resolve ( process . cwd ( ) , '.pnp.js' ) ;
431
+
432
+ const nodeArgs = fs . existsSync ( pnpPath ) ? [ '--require' , pnpPath ] : [ ] ;
433
+
434
+ await executeNodeScript (
435
+ {
436
+ cwd : process . cwd ( ) ,
437
+ args : nodeArgs ,
438
+ } ,
439
+ [ root , appName , verbose , originalDirectory , template ] ,
440
+ `
438
441
var init = require('${ packageName } /scripts/init.js');
439
442
init.apply(null, JSON.parse(process.argv[1]));
440
443
`
441
- ) ;
442
-
443
- if ( version === 'react-scripts@0.9.x' ) {
444
- console . log (
445
- chalk . yellow (
446
- `\nNote: the project was bootstrapped with an old unsupported version of tools.\n` +
447
- `Please update to Node >=6 and npm >=3 to get supported tools in new projects.\n`
448
- )
449
444
) ;
450
- }
451
- } )
452
- . catch ( reason => {
453
- console . log ( ) ;
454
- console . log ( 'Aborting installation.' ) ;
455
- if ( reason . command ) {
456
- console . log ( ` ${ chalk . cyan ( reason . command ) } has failed.` ) ;
457
- } else {
458
- console . log ( chalk . red ( 'Unexpected error. Please report it as a bug:' ) ) ;
459
- console . log ( reason ) ;
460
- }
461
- console . log ( ) ;
462
-
463
- // On 'exit' we will delete these files from target directory.
464
- const knownGeneratedFiles = [ 'package.json' , 'yarn.lock' , 'node_modules' ] ;
465
- const currentFiles = fs . readdirSync ( path . join ( root ) ) ;
466
- currentFiles . forEach ( file => {
467
- knownGeneratedFiles . forEach ( fileToMatch => {
468
- // This removes all knownGeneratedFiles.
469
- if ( file === fileToMatch ) {
470
- console . log ( `Deleting generated file... ${ chalk . cyan ( file ) } ` ) ;
471
- fs . removeSync ( path . join ( root , file ) ) ;
472
- }
445
+
446
+ if ( version === 'react-scripts@0.9.x' ) {
447
+ console . log (
448
+ chalk . yellow (
449
+ `\nNote: the project was bootstrapped with an old unsupported version of tools.\n` +
450
+ `Please update to Node >=8.10 and npm >=5 to get supported tools in new projects.\n`
451
+ )
452
+ ) ;
453
+ }
454
+ } )
455
+ . catch ( reason => {
456
+ console . log ( ) ;
457
+ console . log ( 'Aborting installation.' ) ;
458
+ if ( reason . command ) {
459
+ console . log ( ` ${ chalk . cyan ( reason . command ) } has failed.` ) ;
460
+ } else {
461
+ console . log (
462
+ chalk . red ( 'Unexpected error. Please report it as a bug:' )
463
+ ) ;
464
+ console . log ( reason ) ;
465
+ }
466
+ console . log ( ) ;
467
+
468
+ // On 'exit' we will delete these files from target directory.
469
+ const knownGeneratedFiles = [
470
+ 'package.json' ,
471
+ 'yarn.lock' ,
472
+ 'node_modules' ,
473
+ ] ;
474
+ const currentFiles = fs . readdirSync ( path . join ( root ) ) ;
475
+ currentFiles . forEach ( file => {
476
+ knownGeneratedFiles . forEach ( fileToMatch => {
477
+ // This removes all knownGeneratedFiles.
478
+ if ( file === fileToMatch ) {
479
+ console . log ( `Deleting generated file... ${ chalk . cyan ( file ) } ` ) ;
480
+ fs . removeSync ( path . join ( root , file ) ) ;
481
+ }
482
+ } ) ;
473
483
} ) ;
484
+ const remainingFiles = fs . readdirSync ( path . join ( root ) ) ;
485
+ if ( ! remainingFiles . length ) {
486
+ // Delete target folder if empty
487
+ console . log (
488
+ `Deleting ${ chalk . cyan ( `${ appName } /` ) } from ${ chalk . cyan (
489
+ path . resolve ( root , '..' )
490
+ ) } `
491
+ ) ;
492
+ process . chdir ( path . resolve ( root , '..' ) ) ;
493
+ fs . removeSync ( path . join ( root ) ) ;
494
+ }
495
+ console . log ( 'Done.' ) ;
496
+ process . exit ( 1 ) ;
474
497
} ) ;
475
- const remainingFiles = fs . readdirSync ( path . join ( root ) ) ;
476
- if ( ! remainingFiles . length ) {
477
- // Delete target folder if empty
478
- console . log (
479
- `Deleting ${ chalk . cyan ( `${ appName } /` ) } from ${ chalk . cyan (
480
- path . resolve ( root , '..' )
481
- ) } `
482
- ) ;
483
- process . chdir ( path . resolve ( root , '..' ) ) ;
484
- fs . removeSync ( path . join ( root ) ) ;
485
- }
486
- console . log ( 'Done.' ) ;
487
- process . exit ( 1 ) ;
488
- } ) ;
498
+ } ) ;
489
499
}
490
500
491
501
function getInstallPackage ( version , originalDirectory ) {
@@ -506,7 +516,36 @@ function getInstallPackage(version, originalDirectory) {
506
516
packageToInstall = version ;
507
517
}
508
518
}
509
- return packageToInstall ;
519
+
520
+ const scriptsToWarn = [
521
+ {
522
+ name : 'react-scripts-ts' ,
523
+ message : chalk . yellow (
524
+ 'The react-scripts-ts package is deprecated. TypeScript is now supported natively in Create React App. You can use the --typescript option instead when generating your app to include TypeScript support. Would you like to continue using react-scripts-ts?'
525
+ ) ,
526
+ } ,
527
+ ] ;
528
+
529
+ for ( const script of scriptsToWarn ) {
530
+ if ( packageToInstall . startsWith ( script . name ) ) {
531
+ return inquirer
532
+ . prompt ( {
533
+ type : 'confirm' ,
534
+ name : 'useScript' ,
535
+ message : script . message ,
536
+ default : false ,
537
+ } )
538
+ . then ( answer => {
539
+ if ( ! answer . useScript ) {
540
+ process . exit ( 0 ) ;
541
+ }
542
+
543
+ return packageToInstall ;
544
+ } ) ;
545
+ }
546
+ }
547
+
548
+ return Promise . resolve ( packageToInstall ) ;
510
549
}
511
550
512
551
function getTemporaryDirectory ( ) {
@@ -609,7 +648,7 @@ function checkNpmVersion() {
609
648
npmVersion = execSync ( 'npm --version' )
610
649
. toString ( )
611
650
. trim ( ) ;
612
- hasMinNpm = semver . gte ( npmVersion , '3 .0.0' ) ;
651
+ hasMinNpm = semver . gte ( npmVersion , '5 .0.0' ) ;
613
652
} catch ( err ) {
614
653
// ignore
615
654
}
0 commit comments