Added react-native new-library command

This commit is contained in:
Joe Stanton 2015-03-28 15:50:31 +00:00
parent b2d1d6f3e9
commit 396439bf86
11 changed files with 427 additions and 39 deletions

View File

@ -0,0 +1,17 @@
/**
* Stub of Sample for Android.
*
* @providesModule Sample
* @flow
*/
'use strict';
var warning = require('warning');
var Sample = {
test: function() {
warning("Not yet implemented for Android.");
}
};
module.exports = Sample;

View File

@ -0,0 +1,5 @@
#import "RCTBridgeModule.h"
@interface Sample : NSObject <RCTBridgeModule>
@end

View File

@ -0,0 +1,20 @@
/**
* @providesModule Sample
* @flow
*/
'use strict';
var NativeSample = require('NativeModules').Sample;
var invariant = require('invariant');
/**
* High-level docs for the Sample iOS API can be written here.
*/
var Sample = {
test: function() {
NativeSample.test();
}
};
module.exports = Sample;

10
Libraries/Sample/Sample.m Normal file
View File

@ -0,0 +1,10 @@
#import "Sample.h"
@implementation Sample
- (void)test
{
RCT_EXPORT();
}
@end

View File

@ -0,0 +1,252 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
13BE3DEE1AC21097009241FE /* Sample.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* Sample.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
58B511D91A9E6C8500147676 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSample.a; sourceTree = BUILT_PRODUCTS_DIR; };
13BE3DEC1AC21097009241FE /* Sample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sample.h; sourceTree = "<group>"; };
13BE3DED1AC21097009241FE /* Sample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Sample.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
58B511D81A9E6C8500147676 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
134814211AA4EA7D00B7C361 /* Products */ = {
isa = PBXGroup;
children = (
134814201AA4EA6300B7C361 /* libSample.a */,
);
name = Products;
sourceTree = "<group>";
};
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
13BE3DEC1AC21097009241FE /* Sample.h */,
13BE3DED1AC21097009241FE /* Sample.m */,
134814211AA4EA7D00B7C361 /* Products */,
);
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
58B511DA1A9E6C8500147676 /* Sample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "Sample" */;
buildPhases = (
58B511D71A9E6C8500147676 /* Sources */,
58B511D81A9E6C8500147676 /* Frameworks */,
58B511D91A9E6C8500147676 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = Sample;
productName = RCTDataManager;
productReference = 134814201AA4EA6300B7C361 /* libSample.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
58B511D31A9E6C8500147676 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
58B511DA1A9E6C8500147676 = {
CreatedOnToolsVersion = 6.1.1;
};
};
};
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "Sample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 58B511D21A9E6C8500147676;
productRefGroup = 58B511D21A9E6C8500147676;
projectDirPath = "";
projectRoot = "";
targets = (
58B511DA1A9E6C8500147676 /* Sample */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
58B511D71A9E6C8500147676 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
13BE3DEE1AC21097009241FE /* Sample.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
58B511ED1A9E6C8500147676 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
58B511EE1A9E6C8500147676 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
58B511F01A9E6C8500147676 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Sample;
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../../**";
};
name = Debug;
};
58B511F11A9E6C8500147676 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../React/**",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Sample;
SKIP_INSTALL = YES;
USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../../**";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "Sample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511ED1A9E6C8500147676 /* Debug */,
58B511EE1A9E6C8500147676 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "Sample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511F01A9E6C8500147676 /* Debug */,
58B511F11A9E6C8500147676 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
}

View File

@ -0,0 +1,5 @@
{
"name": "Sample",
"version": "0.0.1",
"keywords": "react-native"
}

View File

@ -10,6 +10,7 @@ var path = require('path');
var init = require('./init.js');
var install = require('./install.js');
var bundle = require('./bundle.js');
var newLibrary = require('./new-library.js');
function printUsage() {
console.log([
@ -18,7 +19,8 @@ function printUsage() {
'Commands:',
' start: starts the webserver',
' install: installs npm react components',
' bundle: builds the javascript bundle for offline use'
' bundle: builds the javascript bundle for offline use',
' new-library: generates a native library bridge'
].join('\n'));
process.exit(1);
}
@ -51,6 +53,9 @@ function run() {
case 'bundle':
bundle.init(args);
break;
case 'new-library':
newLibrary.init(args);
break;
case 'init':
printInitWarning();
break;

View File

@ -0,0 +1,47 @@
'use strict';
var path = require('path');
var fs = require('fs');
function copyAndReplace(src, dest, replacements) {
if (fs.lstatSync(src).isDirectory()) {
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest);
}
} else {
var content = fs.readFileSync(src, 'utf8');
Object.keys(replacements).forEach(function(regex) {
content = content.replace(new RegExp(regex, 'g'), replacements[regex]);
});
fs.writeFileSync(dest, content);
}
}
function walk(current) {
if (!fs.lstatSync(current).isDirectory()) {
return [current];
}
var files = fs.readdirSync(current).map(function(child) {
child = path.join(current, child);
return walk(child);
});
return [].concat.apply([current], files);
}
function validatePackageName(name) {
if (!name.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
console.error(
'"%s" is not a valid name for a project. Please use a valid identifier ' +
'name (alphanumeric).',
name
);
process.exit(1);
}
}
module.exports = {
copyAndReplace: copyAndReplace,
walk: walk,
validatePackageName: validatePackageName
};

View File

@ -1,15 +1,15 @@
'use strict';
var path = require('path');
var fs = require('fs');
var utils = require('./generator-utils');
function init(projectDir, appName) {
console.log('Setting up new React Native app in ' + projectDir);
var source = path.resolve(__dirname, '..', 'Examples/SampleApp');
walk(source).forEach(function(f) {
utils.walk(source).forEach(function(f) {
f = f.replace(source + '/', ''); // Strip off absolute path
if (f === 'project.xcworkspace' || f === 'xcuserdata') {
if (f === 'project.xcworkspace' || f.indexOf('.xcodeproj/xcuserdata') !== -1) {
return;
}
@ -21,7 +21,7 @@ function init(projectDir, appName) {
};
var dest = f.replace(/SampleApp/g, appName).replace(/^_/, '.');
copyAndReplace(
utils.copyAndReplace(
path.resolve(source, f),
path.resolve(projectDir, dest),
replacements
@ -34,30 +34,4 @@ function init(projectDir, appName) {
console.log('');
}
function copyAndReplace(src, dest, replacements) {
if (fs.lstatSync(src).isDirectory()) {
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest);
}
} else {
var content = fs.readFileSync(src, 'utf8');
Object.keys(replacements).forEach(function(regex) {
content = content.replace(new RegExp(regex, 'g'), replacements[regex]);
});
fs.writeFileSync(dest, content);
}
}
function walk(current) {
if (!fs.lstatSync(current).isDirectory()) {
return [current];
}
var files = fs.readdirSync(current).map(function(child) {
child = path.join(current, child);
return walk(child);
});
return [].concat.apply([current], files);
}
module.exports = init;

59
local-cli/new-library.js Normal file
View File

@ -0,0 +1,59 @@
'use strict';
var path = require('path');
var fs = require('fs');
var utils = require('./generator-utils');
function showHelp() {
console.log([
'Usage: react-native new-library <LibraryName>',
''
].join('\n'));
process.exit(1);
}
function newLibrary(libraryName) {
var root = process.cwd();
var libraries = path.resolve(root, 'Libraries');
var libraryDest = path.resolve(libraries, libraryName);
var source = path.resolve('node_modules', 'react-native', 'Libraries', 'Sample') + '/';
if (!fs.existsSync(libraries)) {
fs.mkdir(libraries);
}
if (fs.existsSync(libraryDest)) {
console.log('Library already exists in', libraryDest);
process.exit(1);
}
utils.walk(source).forEach(function(f) {
f = f.replace(source, ''); // Strip off absolute path
if (f === 'project.xcworkspace' || f.indexOf('.xcodeproj/xcuserdata') !== -1) {
return;
}
var dest = f.replace(/Sample/g, libraryName).replace(/^_/, '.');
utils.copyAndReplace(
path.resolve(source, f),
path.resolve(libraryDest, dest),
{ 'Sample': libraryName }
);
});
console.log('Created library in', libraryDest);
console.log('Next Steps:');
console.log(' Link your library in Xcode:');
console.log(' https://facebook.github.io/react-native/docs/linking-libraries.html#content');
console.log('');
}
module.exports = {
init: function(args) {
var libraryName = args[1];
if (!libraryName) { showHelp(); }
utils.validatePackageName(libraryName);
newLibrary(libraryName);
}
};

View File

@ -7,6 +7,7 @@
var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var utils = require('../local-cli/generator-utils');
var CLI_MODULE_PATH = function() {
return path.resolve(
@ -56,14 +57,7 @@ if (cli) {
}
function init(name) {
if (!name.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
console.error(
'"%s" is not a valid name for a project. Please use a valid identifier ' +
'name (alphanumeric).',
name
);
process.exit(1);
}
utils.validatePackageName(name);
var root = path.resolve(name);
var projectName = path.basename(root);