Skip to content

feat: add support for Java templates #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 92 additions & 21 deletions packages/create-react-native-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ const JS_FILES = path.resolve(__dirname, '../templates/js-library');
const EXPO_FILES = path.resolve(__dirname, '../templates/expo-library');
const CPP_FILES = path.resolve(__dirname, '../templates/cpp-library');
const EXAMPLE_FILES = path.resolve(__dirname, '../templates/example');
const NATIVE_COMMON_FILES = path.resolve(
__dirname,
'../templates/native-common'
);

// Android
const NATIVE_FILES = (moduleType: ModuleType) => {
// Java
const JAVA_FILES = (moduleType: ModuleType) => {
switch (moduleType) {
case 'module':
return path.resolve(__dirname, '../templates/native-library');
return path.resolve(__dirname, '../templates/java-library');
case 'view':
return path.resolve(__dirname, '../templates/native-view-library');
return path.resolve(__dirname, '../templates/java-view-library');
}
};

Expand All @@ -37,6 +41,16 @@ const OBJC_FILES = (moduleType: ModuleType) => {
}
};

// Kotlin
const KOTLIN_FILES = (moduleType: ModuleType) => {
switch (moduleType) {
case 'module':
return path.resolve(__dirname, '../templates/kotlin-library');
case 'view':
return path.resolve(__dirname, '../templates/kotlin-view-library');
}
};

// Swift
const SWIFT_FILES = (moduleType: ModuleType) => {
switch (moduleType) {
Expand All @@ -59,12 +73,16 @@ type ArgName =
type ModuleType = 'module' | 'view';

type LibraryType =
| 'native-view'
| 'native-view-swift'
| 'native'
| 'native-swift'
| 'js'
| 'native-kotlin'
| 'native-kotlin-swift'
| 'native-view'
| 'native-view-swift'
| 'native-view-kotlin'
| 'native-view-kotlin-swift'
| 'cpp'
| 'js'
| 'expo';

type Answers = {
Expand Down Expand Up @@ -104,7 +122,19 @@ const args: Record<ArgName, yargs.Options> = {
},
'type': {
description: 'Type package do you want to develop',
choices: ['native', 'native-swift', 'js', 'cpp', 'expo'],
choices: [
'native',
'native-swift',
'native-kotlin',
'native-kotlin-swift',
'native-view',
'native-view-swift',
'native-view-kotlin',
'native-view-kotlin-swift',
'cpp',
'js',
'expo',
],
},
};

Expand Down Expand Up @@ -218,17 +248,33 @@ async function create(argv: yargs.Arguments<any>) {
name: 'type',
message: 'What type of package do you want to develop?',
choices: [
{ title: 'Native module in Kotlin and Objective-C', value: 'native' },
{ title: 'Native module in Kotlin and Swift', value: 'native-swift' },
{ title: 'Native module in Java and Objective-C', value: 'native' },
{ title: 'Native module in Java and Swift', value: 'native-swift' },
{
title: 'Native module in Kotlin and Objective-C',
value: 'native-kotlin',
},
{
title: 'Native module in Kotlin and Swift',
value: 'native-kotlin-swift',
},
{ title: 'Native module with C++ code', value: 'cpp' },
{
title: 'Native view in Kotlin and Objective-C',
title: 'Native view in Java and Objective-C',
value: 'native-view',
},
{
title: 'Native view in Kotlin and Swift',
title: 'Native view in Java and Swift',
value: 'native-view-swift',
},
{
title: 'Native view in Kotlin and Objective-C',
value: 'native-view-kotlin',
},
{
title: 'Native view in Kotlin and Swift',
value: 'native-view-kotlin-swift',
},
{
title: 'JavaScript library with native example',
value: 'js',
Expand Down Expand Up @@ -265,7 +311,12 @@ async function create(argv: yargs.Arguments<any>) {

const project = slug.replace(/^(react-native-|@[^/]+\/)/, '');
const moduleType: ModuleType =
type === 'native-view' || type === 'native-view-swift' ? 'view' : 'module';
type === 'native-view' ||
type === 'native-view-swift' ||
type === 'native-view-kotlin' ||
type === 'native-view-kotlin-swift'
? 'view'
: 'module';

// Get latest version of Bob from NPM
let version: string;
Expand Down Expand Up @@ -308,13 +359,26 @@ async function create(argv: yargs.Arguments<any>) {
package: slug.replace(/[^a-z0-9]/g, '').toLowerCase(),
podspec: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''),
native:
type === 'native' ||
type === 'cpp' ||
'native-swift' ||
'native-view' ||
'native-view-swift',
type === 'native' ||
type === 'native-swift' ||
type === 'native-kotlin' ||
type === 'native-kotlin-swift' ||
type === 'native-view' ||
type === 'native-view-swift' ||
type === 'native-view-kotlin' ||
type === 'native-view-kotlin-swift',
cpp: type === 'cpp',
swift: type === 'native-swift' || 'native-view-swift',
kotlin:
type === 'native-kotlin' ||
type === 'native-kotlin-swift' ||
type === 'native-view-kotlin' ||
type === 'native-view-kotlin-swift',
swift:
type === 'native-swift' ||
type === 'native-kotlin-swift' ||
type === 'native-view-swift' ||
type === 'native-view-kotlin-swift',
module: type !== 'js',
moduleType,
},
Expand Down Expand Up @@ -372,15 +436,22 @@ async function create(argv: yargs.Arguments<any>) {
path.join(folder, 'example')
);

await copyDir(NATIVE_FILES(moduleType), folder);
await copyDir(NATIVE_COMMON_FILES, folder);

if (type === 'cpp') {
if (options.project.cpp) {
await copyDir(CPP_FILES, folder);
} else if (type === 'native-swift') {
}

if (options.project.swift) {
await copyDir(SWIFT_FILES(moduleType), folder);
} else {
await copyDir(OBJC_FILES(moduleType), folder);
}
if (options.project.kotlin) {
await copyDir(KOTLIN_FILES(moduleType), folder);
} else {
await copyDir(JAVA_FILES(moduleType), folder);
}
}

try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
buildscript {
if (project == rootProject) {
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
}
}
}

apply plugin: 'com.android.library'

def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

android {
compileSdkVersion safeExtGet('<%- project.name %>_compileSdkVersion', 29)
buildToolsVersion safeExtGet('<%- project.name %>_buildToolsVersion', '29.0.2')
defaultConfig {
minSdkVersion safeExtGet('<%- project.name %>_minSdkVersion', 16)
targetSdkVersion safeExtGet('<%- project.name %>_targetSdkVersion', 29)
versionCode 1
versionName "1.0"
<% if (project.cpp) { %>
externalNativeBuild {
cmake {
cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
}
<% } %>
}
<% if (project.cpp) { %>
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
<% } %>
buildTypes {
release {
minifyEnabled false
}
}
lintOptions {
disable 'GradleCompatible'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
google()
jcenter()
}

dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.<%- project.package %>;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;

@ReactModule(name = <%- project.name %>Module.NAME)
public class <%- project.name %>Module extends ReactContextBaseJavaModule {
public static final String NAME = "<%- project.name %>";

public <%- project.name %>Module(ReactApplicationContext reactContext) {
super(reactContext);
}

@Override
@NonNull
public String getName() {
return NAME;
}

<% if (project.cpp) { -%>
static {
try {
// Used to load the 'native-lib' library on application startup.
System.loadLibrary("cpp");
} catch (Exception ignored) {
}
}
<% } -%>

// Example method
// See https://reactnative.dev/docs/native-modules-android
@ReactMethod
public void multiply(int a, int b, Promise promise) {
<% if (project.cpp) { -%>
promise.resolve(nativeMultiply(a, b));
<% } else { -%>
promise.resolve(a * b);
<% } -%>
}

public static native int nativeMultiply(int a, int b);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.<%- project.package %>;

import androidx.annotation.NonNull;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class <%- project.name %>Package implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new <%- project.name %>Module(reactContext));
return modules;
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Loading