Skip to content

Commit

Permalink
Merge pull request #2 from foghina/gradleplugin
Browse files Browse the repository at this point in the history
Add gradle plugin for bundling JS in assets
  • Loading branch information
Felix Oghină committed Jul 16, 2015
2 parents cfb4ce2 + 96499c7 commit 52d62b6
Show file tree
Hide file tree
Showing 14 changed files with 600 additions and 0 deletions.
5 changes: 5 additions & 0 deletions react-native-gradle/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.idea/*
!.idea/codeStyleSettings.xml

.gradle
*.iml
110 changes: 110 additions & 0 deletions react-native-gradle/.idea/codeStyleSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions react-native-gradle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# React Native Gradle plugin

This is a plugin for the default build system for Android applications, [gradle][0]. It hooks into the default Android build lifecycle and copies the JS bundle from the packager server to the `assets/` folder.

## Usage

To add this plugin to an existing Android project, first add this to your top-level `build.gradle` file, under `buildscript / dependencies`:

classpath 'com.facebook.react:gradleplugin:1.0.+'

Then apply the plugin to your application module (usually `app/build.gradle`):

apply plugin: 'com.facebook.react'

That's it! The plugin will now download the bundle from the default packager location (http://localhost:8081/index.android.js) and place it in the assets folder at build time.

## Configuration

The following shows all of the values that can be customized and their defaults. Configuration goes into your application module (`app/build.gradle`).

react {
bundleFileName "index.android.js"
bundlePath "/index.android.bundle"
packagerHost "localhost:8081"

devParams {
dev true
inlineSourceMap false
minify false
runModule true
}
releaseParams {
dev false
inlineSourceMap false
minify true
runModule true
}
}

This makes it so that the following bundles are added to the respective builds, as `assets/index.android.js`.

| Build | Packager URL |
|---------|---------------------------------------------------------------------------------------------------|
| dev | http://localhost:8081/index.android.js?dev=true&inlineSourceMap=false&minify=false&runModule=true |
| release | http://localhost:8081/index.android.js?dev=false&inlineSourceMap=false&minify=true&runModule=true |

For more information regarding the URL parameters, check out the [packager documentation][1].

## Contributing

After you make changes to the plugin code, simply run `gradle build install` in this directory. Then, in your Android project, change the top-level buildscript classpath dependency to whatever version you just built, something like `1.2.3-SNAPSHOT`. This should be picked up and used from your local maven repository.

[0]: https://gradle.org/
[1]: https://github.com/facebook/react-native/blob/master/packager/README.md
17 changes: 17 additions & 0 deletions react-native-gradle/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
group = 'com.facebook.react'
version = '1.0.0-SNAPSHOT'

apply plugin: 'groovy'
apply plugin: 'maven'

repositories {
mavenCentral()
}

dependencies {
compile gradleApi()
compile 'commons-io:commons-io:2.4'

testCompile 'junit:junit:4.12'
testCompile 'com.squareup.okhttp:mockwebserver:2.4.0'
}
1 change: 1 addition & 0 deletions react-native-gradle/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'gradleplugin'
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.facebook.react;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.gradle.api.DefaultTask;

/**
* Base class for tasks that build JS packages. Handles requesting a bundle from the packager server
* and putting it into the appropriate folder.
*/
public abstract class AbstractPackageJsTask extends DefaultTask {

/**
* Get a bundle from packager and copy it to the appropriate folder.
*
* @param debug whether this is a debug build or not
*/
protected void copyBundle(boolean debug) throws URISyntaxException, IOException {
ReactGradleExtension config = getConfig();
PackagerParams packagerParams = getPackagerParams(config, debug);

File assets = new File(
getProject().getProjectDir(),
FilenameUtils
.separatorsToSystem("build/intermediates/assets/" + (debug ? "debug" : "release")));
assets.mkdirs();
File bundle = new File(assets, config.getBundleFileName());
System.out.println("Writing debug=" + debug + " bundle to " + bundle.getAbsolutePath());

URL packageUrl = getPackageUrl(config, packagerParams);

InputStream packageStream = packageUrl.openStream();
OutputStream bundleStream = new FileOutputStream(bundle);
IOUtils.copy(packageStream, bundleStream);
IOUtils.closeQuietly(packageStream);
IOUtils.closeQuietly(bundleStream);
}

/**
* Generate a packager URL for a specific configuration.
*
* @param config the top-level config of the plugin
* @param params packager params to include in the URL
*/
private URL getPackageUrl(ReactGradleExtension config, PackagerParams params)
throws URISyntaxException, MalformedURLException {
String query = "dev=" + params.isDev() + "&" +
"inlineSourceMap=" + params.isInlineSourceMap() + "&" +
"minify=" + params.isMinify() + "&" +
"runModule=" + params.isRunModule();
return new URI(
"http",
config.getPackagerHost(),
config.getBundlePath(),
query,
null).toURL();
}

/**
* Get the configuration for this project, or a blank config.
*/
private ReactGradleExtension getConfig() {
ReactGradleExtension config =
getProject().getExtensions().findByType(ReactGradleExtension.class);
if (config == null) {
config = new ReactGradleExtension(getProject());
}
return config;
}

/**
* Extract packager parameters from a configuration, or return default values.
*
* @param config the configuration to extract from
* @param debug whether default values should be for debug or prod
*/
private PackagerParams getPackagerParams(ReactGradleExtension config, boolean debug) {
if (debug) {
return config.getDevParams() != null
? config.getDevParams()
: PackagerParams.devDefaults();
} else {
return config.getReleaseParams() != null
? config.getReleaseParams()
: PackagerParams.releaseDefaults();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.facebook.react;

import java.io.IOException;
import java.net.URISyntaxException;

import org.gradle.api.tasks.TaskAction;

/**
* Gradle task that copies the dev bundle to the debug build's assets.
*/
public class PackageDebugJsTask extends AbstractPackageJsTask {

@TaskAction
public void packageJS() throws IOException, URISyntaxException {
copyBundle(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.facebook.react;

import java.io.IOException;
import java.net.URISyntaxException;

import org.gradle.api.tasks.TaskAction;

/**
* Gradle task that copies the prod bundle to the debug build's assets.
*/
public class PackageReleaseJsTask extends AbstractPackageJsTask {

@TaskAction
public void packageJS() throws IOException, URISyntaxException {
copyBundle(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.facebook.react;

/**
* POJO for packager parameters.
*/
public class PackagerParams {
private boolean dev = true;
private boolean inlineSourceMap = false;
private boolean minify = false;
private boolean runModule = true;

/**
* Returns default parameters for debug builds.
*/
public static PackagerParams devDefaults() {
PackagerParams params = new PackagerParams();
params.dev = true;
params.inlineSourceMap = false;
params.minify = false;
params.runModule = true;
return params;
}

/**
* Returns default parameters for release builds.
*/
public static PackagerParams releaseDefaults() {
PackagerParams params = new PackagerParams();
params.dev = false;
params.inlineSourceMap = false;
params.minify = true;
params.runModule = true;
return params;
}

public boolean isDev() {
return dev;
}

public void dev(boolean dev) {
this.dev = dev;
}

public boolean isInlineSourceMap() {
return inlineSourceMap;
}

public void inlineSourceMap(boolean inlineSourceMap) {
this.inlineSourceMap = inlineSourceMap;
}

public boolean isMinify() {
return minify;
}

public void minify(boolean minify) {
this.minify = minify;
}

public boolean isRunModule() {
return runModule;
}

public void runModule(boolean runModule) {
this.runModule = runModule;
}
}
Loading

0 comments on commit 52d62b6

Please sign in to comment.