-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CLI: Add support for project templates
Summary: Currently it is not trivial for people to get started with React Native. `react-native init MyApp` just creates a simple app with a single screen. People have to spend time figuring out how to add more screens, or how to accomplish very basic tasks such as rendering a list of data or handling text input. Let's add an option: `react-native init --template navigation` - this creates a "starter" app which can be easily tweaked into the actual app the person wants to build. **Test plan (required)** - Checked that 'react-native init MyApp' still works as before: <img width="487" alt="screenshot 2017-02-02 16 56 28" src="https://cloud.githubusercontent.com/assets/346214/22559344/b2348ebe-e968-11e6-9032-d1c33216f490.png"> <img width="603" alt="screenshot 2017-02-02 16 58 04" src="https://cloud.githubusercontent.com/assets/346214/22559370/c96a2ca6-e968-11e6-91f7-7afb967920fc.png"> - Ran 'react-native init MyNavApp --template'. This prints the available templates: ``` $ react-native init MyNavApp Closes #12170 Differential Revision: D4516241 Pulled By: mkonicek fbshipit-source-id: 8ac081157919872e92947ed64ea64fb48078614d
- Loading branch information
1 parent
75c14e3
commit a54d449
Showing
13 changed files
with
250 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/** | ||
* 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. | ||
*/ | ||
'use strict'; | ||
|
||
const copyProjectTemplateAndReplace = require('./copyProjectTemplateAndReplace'); | ||
const execSync = require('child_process').execSync; | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
const availableTemplates = { | ||
navigation: 'HelloNavigation', | ||
}; | ||
|
||
function listTemplatesAndExit(newProjectName, options) { | ||
if (options.template === true) { | ||
// Just listing templates using 'react-native init --template'. | ||
// Not creating a new app. | ||
// Print available templates and exit. | ||
const templateKeys = Object.keys(availableTemplates); | ||
if (templateKeys.length === 0) { | ||
// Just a guard, should never happen as long availableTemplates | ||
// above is defined correctly :) | ||
console.log( | ||
'There are no templates available besides ' + | ||
'the default "Hello World" one.' | ||
); | ||
} else { | ||
console.log( | ||
'The available templates are:\n' + | ||
templateKeys.join('\n') + | ||
'\nYou can use these to create an app based on a template, for example: ' + | ||
'you could run: ' + | ||
'react-native init ' + newProjectName + ' --template ' + templateKeys[0] | ||
); | ||
} | ||
// Exit 'react-native init' | ||
return true; | ||
} | ||
// Continue 'react-native init' | ||
return false; | ||
} | ||
|
||
/** | ||
* @param newProjectName For example 'AwesomeApp'. | ||
* @param templateKey Template to use, for example 'navigation'. | ||
* @param yarnVersion Version of yarn available on the system, or null if | ||
* yarn is not available. For example '0.18.1'. | ||
*/ | ||
function createProjectFromTemplate(destPath, newProjectName, templateKey, yarnVersion) { | ||
// Expand the basic 'HelloWorld' template | ||
copyProjectTemplateAndReplace( | ||
path.resolve('node_modules', 'react-native', 'local-cli', 'templates', 'HelloWorld'), | ||
destPath, | ||
newProjectName | ||
); | ||
|
||
if (templateKey !== undefined) { | ||
// Keep the files from the 'HelloWorld' template, and overwrite some of them | ||
// with the specified project template. | ||
// The 'HelloWorld' template contains the native files (these are used by | ||
// all templates) and every other template only contains additional JS code. | ||
// Reason: | ||
// This way we don't have to duplicate the native files in every template. | ||
// If we duplicated them we'd make RN larger and risk that people would | ||
// forget to maintain all the copies so they would go out of sync. | ||
const templateName = availableTemplates[templateKey]; | ||
if (templateName) { | ||
copyProjectTemplateAndReplace( | ||
path.resolve( | ||
'node_modules', 'react-native', 'local-cli', 'templates', templateName | ||
), | ||
destPath, | ||
newProjectName | ||
); | ||
} else { | ||
throw new Error('Uknown template: ' + templateKey); | ||
} | ||
|
||
// Add dependencies: | ||
|
||
// dependencies.json is a special file that lists additional dependencies | ||
// that are required by this template | ||
const dependenciesJsonPath = path.resolve( | ||
'node_modules', 'react-native', 'local-cli', 'templates', templateName, 'dependencies.json' | ||
); | ||
if (fs.existsSync(dependenciesJsonPath)) { | ||
console.log('Adding dependencies for the project...'); | ||
const dependencies = JSON.parse(fs.readFileSync(dependenciesJsonPath)); | ||
for (let depName in dependencies) { | ||
const depVersion = dependencies[depName]; | ||
const depToInstall = depName + '@' + depVersion; | ||
console.log('Adding ' + depToInstall + '...'); | ||
if (yarnVersion) { | ||
execSync(`yarn add ${depToInstall}`, {stdio: 'inherit'}); | ||
} else { | ||
execSync(`npm install ${depToInstall} --save --save-exact`, {stdio: 'inherit'}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
module.exports = { | ||
listTemplatesAndExit, | ||
createProjectFromTemplate, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"react-navigation": "1.0.0-beta.1" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
local-cli/templates/HelloNavigation/views/welcome/WelcomeText.android.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, { Component } from 'react'; | ||
import { | ||
AppRegistry, | ||
StyleSheet, | ||
Text, | ||
View | ||
} from 'react-native'; | ||
|
||
export default class WelcomeText extends Component { | ||
render() { | ||
return ( | ||
<View style={styles.container}> | ||
<Text style={styles.welcome}> | ||
Welcome to React Native! | ||
</Text> | ||
<Text style={styles.instructions}> | ||
This app shows the basics of navigating between a few screens, | ||
working with ListView and handling text input. | ||
</Text> | ||
<Text style={styles.instructions}> | ||
Modify any files to get started. For example try changing the | ||
file views/welcome/WelcomeText.android.js. | ||
</Text> | ||
<Text style={styles.instructions}> | ||
Press Cmd+R to reload,{'\n'} | ||
Cmd+D or shake for dev menu. | ||
</Text> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
flex: 1, | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
backgroundColor: 'white', | ||
padding: 20, | ||
}, | ||
welcome: { | ||
fontSize: 20, | ||
textAlign: 'center', | ||
margin: 16, | ||
}, | ||
instructions: { | ||
textAlign: 'center', | ||
color: '#333333', | ||
marginBottom: 12, | ||
}, | ||
}); |
51 changes: 51 additions & 0 deletions
51
local-cli/templates/HelloNavigation/views/welcome/WelcomeText.ios.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, { Component } from 'react'; | ||
import { | ||
AppRegistry, | ||
StyleSheet, | ||
Text, | ||
View | ||
} from 'react-native'; | ||
|
||
export default class WelcomeText extends Component { | ||
render() { | ||
return ( | ||
<View style={styles.container}> | ||
<Text style={styles.welcome}> | ||
Welcome to React Native! | ||
</Text> | ||
<Text style={styles.instructions}> | ||
This app shows the basics of navigating between a few screens, | ||
working with ListView and handling text input. | ||
</Text> | ||
<Text style={styles.instructions}> | ||
Modify any files to get started. For example try changing the | ||
file{'\n'}views/welcome/WelcomeText.ios.js. | ||
</Text> | ||
<Text style={styles.instructions}> | ||
Press Cmd+R to reload,{'\n'} | ||
Cmd+D or shake for dev menu. | ||
</Text> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
flex: 1, | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
backgroundColor: 'white', | ||
padding: 20, | ||
}, | ||
welcome: { | ||
fontSize: 20, | ||
textAlign: 'center', | ||
margin: 16, | ||
}, | ||
instructions: { | ||
textAlign: 'center', | ||
color: '#333333', | ||
marginBottom: 12, | ||
}, | ||
}); |
File renamed without changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters