3434
3535'use strict' ;
3636
37- const validateProjectName = require ( 'validate-npm-package-name' ) ;
3837const chalk = require ( 'chalk' ) ;
3938const commander = require ( 'commander' ) ;
39+ const dns = require ( 'dns' ) ;
40+ const envinfo = require ( 'envinfo' ) ;
41+ const execSync = require ( 'child_process' ) . execSync ;
4042const fs = require ( 'fs-extra' ) ;
43+ const hyperquest = require ( 'hyperquest' ) ;
44+ const inquirer = require ( 'inquirer' ) ;
45+ const os = require ( 'os' ) ;
4146const path = require ( 'path' ) ;
42- const execSync = require ( 'child_process' ) . execSync ;
43- const spawn = require ( 'cross-spawn' ) ;
4447const semver = require ( 'semver' ) ;
45- const dns = require ( 'dns ' ) ;
48+ const spawn = require ( 'cross-spawn ' ) ;
4649const tmp = require ( 'tmp' ) ;
4750const unpack = require ( 'tar-pack' ) . unpack ;
4851const 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' ) ;
5253
5354const packageJson = require ( './package.json' ) ;
5455
@@ -221,13 +222,13 @@ function createApp(
221222 process . exit ( 1 ) ;
222223 }
223224
224- if ( ! semver . satisfies ( process . version , '>=6.0 .0' ) ) {
225+ if ( ! semver . satisfies ( process . version , '>=8.10 .0' ) ) {
225226 console . log (
226227 chalk . yellow (
227228 `You are using Node ${
228229 process . version
229230 } so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
230- `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`
231232 )
232233 ) ;
233234 // Fall back to latest supported react-scripts on Node 4
@@ -243,7 +244,7 @@ function createApp(
243244 `You are using npm ${
244245 npmInfo . npmVersion
245246 } so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
246- `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`
247248 )
248249 ) ;
249250 }
@@ -381,112 +382,120 @@ function run(
381382 usePnp ,
382383 useTypescript
383384) {
384- const packageToInstall = getInstallPackage ( version , originalDirectory ) ;
385- const allDependencies = [ 'react' , 'react-dom' , packageToInstall ] ;
386- if ( useTypescript ) {
387- // TODO: get user's node version instead of installing latest
388- allDependencies . push (
389- '@types/node' ,
390- '@types/react' ,
391- '@types/react-dom' ,
392- '@types/jest' ,
393- 'typescript'
394- ) ;
395- }
396-
397- console . log ( 'Installing packages. This might take a couple of minutes.' ) ;
398- getPackageName ( packageToInstall )
399- . then ( packageName =>
400- checkIfOnline ( useYarn ) . then ( isOnline => ( {
401- isOnline : isOnline ,
402- packageName : packageName ,
403- } ) )
404- )
405- . then ( info => {
406- const isOnline = info . isOnline ;
407- const packageName = info . packageName ;
408- console . log (
409- `Installing ${ chalk . cyan ( 'react' ) } , ${ chalk . cyan (
410- 'react-dom'
411- ) } , 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'
412396 ) ;
413- console . log ( ) ;
414-
415- return install (
416- root ,
417- useYarn ,
418- usePnp ,
419- allDependencies ,
420- verbose ,
421- isOnline
422- ) . then ( ( ) => packageName ) ;
423- } )
424- . then ( async packageName => {
425- checkNodeVersion ( packageName ) ;
426- setCaretRangeForRuntimeDeps ( packageName ) ;
427-
428- const pnpPath = path . resolve ( process . cwd ( ) , '.pnp.js' ) ;
429-
430- const nodeArgs = fs . existsSync ( pnpPath ) ? [ '--require' , pnpPath ] : [ ] ;
431-
432- await executeNodeScript (
433- {
434- cwd : process . cwd ( ) ,
435- args : nodeArgs ,
436- } ,
437- [ root , appName , verbose , originalDirectory , template ] ,
438- `
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+ `
439441 var init = require('${ packageName } /scripts/init.js');
440442 init.apply(null, JSON.parse(process.argv[1]));
441443 `
442- ) ;
443-
444- if ( version === 'react-scripts@0.9.x' ) {
445- console . log (
446- chalk . yellow (
447- `\nNote: the project was bootstrapped with an old unsupported version of tools.\n` +
448- `Please update to Node >=6 and npm >=3 to get supported tools in new projects.\n`
449- )
450444 ) ;
451- }
452- } )
453- . catch ( reason => {
454- console . log ( ) ;
455- console . log ( 'Aborting installation.' ) ;
456- if ( reason . command ) {
457- console . log ( ` ${ chalk . cyan ( reason . command ) } has failed.` ) ;
458- } else {
459- console . log ( chalk . red ( 'Unexpected error. Please report it as a bug:' ) ) ;
460- console . log ( reason ) ;
461- }
462- console . log ( ) ;
463-
464- // On 'exit' we will delete these files from target directory.
465- const knownGeneratedFiles = [ 'package.json' , 'yarn.lock' , 'node_modules' ] ;
466- const currentFiles = fs . readdirSync ( path . join ( root ) ) ;
467- currentFiles . forEach ( file => {
468- knownGeneratedFiles . forEach ( fileToMatch => {
469- // This removes all knownGeneratedFiles.
470- if ( file === fileToMatch ) {
471- console . log ( `Deleting generated file... ${ chalk . cyan ( file ) } ` ) ;
472- fs . removeSync ( path . join ( root , file ) ) ;
473- }
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+ } ) ;
474483 } ) ;
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 ) ;
475497 } ) ;
476- const remainingFiles = fs . readdirSync ( path . join ( root ) ) ;
477- if ( ! remainingFiles . length ) {
478- // Delete target folder if empty
479- console . log (
480- `Deleting ${ chalk . cyan ( `${ appName } /` ) } from ${ chalk . cyan (
481- path . resolve ( root , '..' )
482- ) } `
483- ) ;
484- process . chdir ( path . resolve ( root , '..' ) ) ;
485- fs . removeSync ( path . join ( root ) ) ;
486- }
487- console . log ( 'Done.' ) ;
488- process . exit ( 1 ) ;
489- } ) ;
498+ } ) ;
490499}
491500
492501function getInstallPackage ( version , originalDirectory ) {
@@ -507,7 +516,36 @@ function getInstallPackage(version, originalDirectory) {
507516 packageToInstall = version ;
508517 }
509518 }
510- 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 ) ;
511549}
512550
513551function getTemporaryDirectory ( ) {
@@ -610,7 +648,7 @@ function checkNpmVersion() {
610648 npmVersion = execSync ( 'npm --version' )
611649 . toString ( )
612650 . trim ( ) ;
613- hasMinNpm = semver . gte ( npmVersion , '3 .0.0' ) ;
651+ hasMinNpm = semver . gte ( npmVersion , '5 .0.0' ) ;
614652 } catch ( err ) {
615653 // ignore
616654 }
0 commit comments