mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
31
Commits
fix/cli-start
...
v0.54.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56a2d6d720 | ||
|
|
0ba6ed897a | ||
|
|
7e4cd53383 | ||
|
|
69c277051e | ||
|
|
863a49f2ab | ||
|
|
5c00de7b6b | ||
|
|
17e0066c0d | ||
|
|
ec542f44dd | ||
|
|
d9bd9d5587 | ||
|
|
387e1c4d11 | ||
|
|
9a3cad4d89 | ||
|
|
48f29a74c5 | ||
|
|
8e03ced500 | ||
|
|
ac55ffd777 | ||
|
|
8bdd98ea48 | ||
|
|
2d57335fa7 | ||
|
|
2f8446319a | ||
|
|
815a07c77b | ||
|
|
53c1a4cc7b | ||
|
|
67e67ec83c | ||
|
|
0f96ebd93b | ||
|
|
f4fde9d84a | ||
|
|
4194bb242d | ||
|
|
675f14257a | ||
|
|
21dd3dd296 | ||
|
|
03d7b2aa0e | ||
|
|
2c5fbd79a2 | ||
|
|
49e35bd939 | ||
|
|
829f675b8b | ||
|
|
b58d848d9c | ||
|
|
294d95a236 |
@@ -383,6 +383,9 @@ jobs:
|
||||
publish_npm_package:
|
||||
<<: *android_defaults
|
||||
steps:
|
||||
# Checkout code so that we can work with `git` in publish.js
|
||||
- checkout
|
||||
|
||||
- attach_workspace:
|
||||
at: ~/react-native
|
||||
|
||||
@@ -606,6 +609,7 @@ workflows:
|
||||
- approve_publish_npm_package:
|
||||
filters: *filter-only-stable
|
||||
type: approval
|
||||
|
||||
- publish_npm_package:
|
||||
requires:
|
||||
- checkout_code
|
||||
|
||||
@@ -260,6 +260,9 @@ RCT_EXPORT_METHOD(release:(NSString *)blobId)
|
||||
|
||||
- (id)handleNetworkingResponse:(NSURLResponse *)response data:(NSData *)data
|
||||
{
|
||||
// An empty body will have nil for data, in this case we need to return
|
||||
// an empty blob as per the XMLHttpRequest spec.
|
||||
data = data ?: [NSData new];
|
||||
return @{
|
||||
@"blobId": [self store:data],
|
||||
@"offset": @0,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
exports.version = {
|
||||
major: 0,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
minor: 54,
|
||||
patch: 4,
|
||||
prerelease: null,
|
||||
};
|
||||
|
||||
@@ -441,10 +441,6 @@ RCT_EXPORT_MODULE()
|
||||
{
|
||||
RCTAssertThread(_methodQueue, @"sendData: must be called on method queue");
|
||||
|
||||
if (data.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
id responseData = nil;
|
||||
for (id<RCTNetworkingResponseHandler> handler in _responseHandlers) {
|
||||
if ([handler canHandleNetworkingResponse:responseType]) {
|
||||
@@ -454,6 +450,10 @@ RCT_EXPORT_MODULE()
|
||||
}
|
||||
|
||||
if (!responseData) {
|
||||
if (data.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([responseType isEqualToString:@"text"]) {
|
||||
// No carry storage is required here because the entire data has been loaded.
|
||||
responseData = [RCTNetworking decodeTextData:data fromResponse:task.response withCarryData:nil];
|
||||
|
||||
@@ -1 +1 @@
|
||||
467b1034ce8af6807e11deb9dfeca4d4e922ed82
|
||||
ad9544f48e58f2599a8ea0de1e9f4dd104db30bb
|
||||
+1481
-1464
File diff suppressed because it is too large
Load Diff
+1102
-974
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
const ReactFeatureFlags = {
|
||||
debugRenderPhaseSideEffects: false,
|
||||
debugRenderPhaseSideEffectsForStrictMode: false,
|
||||
warnAboutDeprecatedLifecycles: true,
|
||||
warnAboutDeprecatedLifecycles: false,
|
||||
};
|
||||
|
||||
module.exports = ReactFeatureFlags;
|
||||
|
||||
@@ -80,10 +80,12 @@ export type ReactContext<T> = {
|
||||
$$typeof: Symbol | number,
|
||||
Consumer: ReactContext<T>,
|
||||
Provider: ReactProviderType<T>,
|
||||
calculateChangedBits: ((a: T, b: T) => number) | null,
|
||||
defaultValue: T,
|
||||
currentValue: T,
|
||||
changedBits: number,
|
||||
|
||||
_calculateChangedBits: ((a: T, b: T) => number) | null,
|
||||
_defaultValue: T,
|
||||
|
||||
_currentValue: T,
|
||||
_changedBits: number,
|
||||
|
||||
// DEV only
|
||||
_currentRenderer?: Object | null,
|
||||
|
||||
@@ -350,9 +350,12 @@ static YGSize RCTTextShadowViewMeasure(YGNodeRef node, float width, YGMeasureMod
|
||||
MIN(RCTCeilPixelValue(size.height), maximumSize.height)
|
||||
};
|
||||
|
||||
// Adding epsilon value illuminates problems with converting values from
|
||||
// `double` to `float`, and then rounding them to pixel grid in Yoga.
|
||||
CGFloat epsilon = 0.001;
|
||||
return (YGSize){
|
||||
RCTYogaFloatFromCoreGraphicsFloat(size.width),
|
||||
RCTYogaFloatFromCoreGraphicsFloat(size.height)
|
||||
RCTYogaFloatFromCoreGraphicsFloat(size.width + epsilon),
|
||||
RCTYogaFloatFromCoreGraphicsFloat(size.height + epsilon)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
@@ -11,7 +11,7 @@
|
||||
|
||||
#define RCT_REACT_NATIVE_VERSION @{ \
|
||||
@"major": @(0), \
|
||||
@"minor": @(0), \
|
||||
@"patch": @(0), \
|
||||
@"minor": @(54), \
|
||||
@"patch": @(4), \
|
||||
@"prerelease": [NSNull null], \
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0-master
|
||||
VERSION_NAME=0.54.4
|
||||
GROUP=com.facebook.react
|
||||
|
||||
POM_NAME=ReactNative
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -250,7 +251,31 @@ public class ReadableNativeMap extends NativeMap implements ReadableMap {
|
||||
}
|
||||
return hashMap;
|
||||
}
|
||||
return getLocalMap();
|
||||
|
||||
// we can almost just return getLocalMap(), but we need to convert nested arrays and maps to the
|
||||
// correct types first
|
||||
HashMap<String, Object> hashMap = new HashMap<>(getLocalMap());
|
||||
Iterator iterator = hashMap.keySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
String key = (String) iterator.next();
|
||||
switch (getType(key)) {
|
||||
case Null:
|
||||
case Boolean:
|
||||
case Number:
|
||||
case String:
|
||||
break;
|
||||
case Map:
|
||||
hashMap.put(key, Assertions.assertNotNull(getMap(key)).toHashMap());
|
||||
break;
|
||||
case Array:
|
||||
hashMap.put(key, Assertions.assertNotNull(getArray(key)).toArrayList());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Could not convert object with key: " + key + ".");
|
||||
}
|
||||
}
|
||||
return hashMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -146,13 +146,13 @@ public class BundleDownloader {
|
||||
if (match.find()) {
|
||||
String boundary = match.group(1);
|
||||
MultipartStreamReader bodyReader = new MultipartStreamReader(response.body().source(), boundary);
|
||||
boolean completed = bodyReader.readAllParts(new MultipartStreamReader.ChunkCallback() {
|
||||
boolean completed = bodyReader.readAllParts(new MultipartStreamReader.ChunkListener() {
|
||||
@Override
|
||||
public void execute(Map<String, String> headers, Buffer body, boolean finished) throws IOException {
|
||||
public void onChunkComplete(Map<String, String> headers, Buffer body, boolean isLastChunk) throws IOException {
|
||||
// This will get executed for every chunk of the multipart response. The last chunk
|
||||
// (finished = true) will be the JS bundle, the other ones will be progress events
|
||||
// (isLastChunk = true) will be the JS bundle, the other ones will be progress events
|
||||
// encoded as JSON.
|
||||
if (finished) {
|
||||
if (isLastChunk) {
|
||||
// The http status code for each separate chunk is in the X-Http-Status header.
|
||||
int status = response.code();
|
||||
if (headers.containsKey("X-Http-Status")) {
|
||||
@@ -184,6 +184,15 @@ public class BundleDownloader {
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onChunkProgress(Map<String, String> headers, long loaded, long total) throws IOException {
|
||||
if ("application/javascript".equals(headers.get("Content-Type"))) {
|
||||
callback.onProgress(
|
||||
"Downloading JavaScript bundle",
|
||||
(int) (loaded / 1024),
|
||||
(int) (total / 1024));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!completed) {
|
||||
callback.onFailure(new DebugServerException(
|
||||
|
||||
+51
-9
@@ -26,9 +26,18 @@ public class MultipartStreamReader {
|
||||
|
||||
private final BufferedSource mSource;
|
||||
private final String mBoundary;
|
||||
private long mLastProgressEvent;
|
||||
|
||||
public interface ChunkCallback {
|
||||
void execute(Map<String, String> headers, Buffer body, boolean done) throws IOException;
|
||||
public interface ChunkListener {
|
||||
/**
|
||||
* Invoked when a chunk of a multipart response is fully downloaded.
|
||||
*/
|
||||
void onChunkComplete(Map<String, String> headers, Buffer body, boolean isLastChunk) throws IOException;
|
||||
|
||||
/**
|
||||
* Invoked as bytes of the current chunk are read.
|
||||
*/
|
||||
void onChunkProgress(Map<String, String> headers, long loaded, long total) throws IOException;
|
||||
}
|
||||
|
||||
public MultipartStreamReader(BufferedSource source, String boundary) {
|
||||
@@ -55,34 +64,50 @@ public class MultipartStreamReader {
|
||||
return headers;
|
||||
}
|
||||
|
||||
private void emitChunk(Buffer chunk, boolean done, ChunkCallback callback) throws IOException {
|
||||
private void emitChunk(Buffer chunk, boolean done, ChunkListener listener) throws IOException {
|
||||
ByteString marker = ByteString.encodeUtf8(CRLF + CRLF);
|
||||
long indexOfMarker = chunk.indexOf(marker);
|
||||
if (indexOfMarker == -1) {
|
||||
callback.execute(null, chunk, done);
|
||||
listener.onChunkComplete(null, chunk, done);
|
||||
} else {
|
||||
Buffer headers = new Buffer();
|
||||
Buffer body = new Buffer();
|
||||
chunk.read(headers, indexOfMarker);
|
||||
chunk.skip(marker.size());
|
||||
chunk.readAll(body);
|
||||
callback.execute(parseHeaders(headers), body, done);
|
||||
listener.onChunkComplete(parseHeaders(headers), body, done);
|
||||
}
|
||||
}
|
||||
|
||||
private void emitProgress(Map<String, String> headers, long contentLength, boolean isFinal, ChunkListener listener) throws IOException {
|
||||
if (headers == null || listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - mLastProgressEvent > 16 || isFinal) {
|
||||
mLastProgressEvent = currentTime;
|
||||
long headersContentLength = headers.get("Content-Length") != null ? Long.parseLong(headers.get("Content-Length")) : 0;
|
||||
listener.onChunkProgress(headers, contentLength, headersContentLength);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all parts of the multipart response and execute the callback for each chunk received.
|
||||
* @param callback Callback executed when a chunk is received
|
||||
* Reads all parts of the multipart response and execute the listener for each chunk received.
|
||||
* @param listener Listener invoked when chunks are received.
|
||||
* @return If the read was successful
|
||||
*/
|
||||
public boolean readAllParts(ChunkCallback callback) throws IOException {
|
||||
public boolean readAllParts(ChunkListener listener) throws IOException {
|
||||
ByteString delimiter = ByteString.encodeUtf8(CRLF + "--" + mBoundary + CRLF);
|
||||
ByteString closeDelimiter = ByteString.encodeUtf8(CRLF + "--" + mBoundary + "--" + CRLF);
|
||||
ByteString headersDelimiter = ByteString.encodeUtf8(CRLF + CRLF);
|
||||
|
||||
int bufferLen = 4 * 1024;
|
||||
long chunkStart = 0;
|
||||
long bytesSeen = 0;
|
||||
Buffer content = new Buffer();
|
||||
Map<String, String> currentHeaders = null;
|
||||
long currentHeadersLength = 0;
|
||||
|
||||
while (true) {
|
||||
boolean isCloseDelimiter = false;
|
||||
@@ -98,6 +123,20 @@ public class MultipartStreamReader {
|
||||
|
||||
if (indexOfDelimiter == -1) {
|
||||
bytesSeen = content.size();
|
||||
|
||||
if (currentHeaders == null) {
|
||||
long indexOfHeaders = content.indexOf(headersDelimiter, searchStart);
|
||||
if (indexOfHeaders >= 0) {
|
||||
mSource.read(content, indexOfHeaders);
|
||||
Buffer headers = new Buffer();
|
||||
content.copyTo(headers, searchStart, indexOfHeaders - searchStart);
|
||||
currentHeadersLength = headers.size() + headersDelimiter.size();
|
||||
currentHeaders = parseHeaders(headers);
|
||||
}
|
||||
} else {
|
||||
emitProgress(currentHeaders, content.size() - currentHeadersLength, false, listener);
|
||||
}
|
||||
|
||||
long bytesRead = mSource.read(content, bufferLen);
|
||||
if (bytesRead <= 0) {
|
||||
return false;
|
||||
@@ -113,7 +152,10 @@ public class MultipartStreamReader {
|
||||
Buffer chunk = new Buffer();
|
||||
content.skip(chunkStart);
|
||||
content.read(chunk, length);
|
||||
emitChunk(chunk, isCloseDelimiter, callback);
|
||||
emitProgress(currentHeaders, chunk.size() - currentHeadersLength, true, listener);
|
||||
emitChunk(chunk, isCloseDelimiter, listener);
|
||||
currentHeaders = null;
|
||||
currentHeadersLength = 0;
|
||||
} else {
|
||||
content.skip(chunkEnd);
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
RequestBody requestBody;
|
||||
if (data == null) {
|
||||
if (data == null || method.toLowerCase().equals("get") || method.toLowerCase().equals("head")) {
|
||||
requestBody = RequestBodyUtil.getEmptyBody(method);
|
||||
} else if (handler != null) {
|
||||
requestBody = handler.toRequestBody(data, contentType);
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import java.util.Map;
|
||||
public class ReactNativeVersion {
|
||||
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
|
||||
"major", 0,
|
||||
"minor", 0,
|
||||
"patch", 0,
|
||||
"minor", 54,
|
||||
"patch", 4,
|
||||
"prerelease", null);
|
||||
}
|
||||
|
||||
@@ -174,14 +174,16 @@ public class ReactEditText extends EditText {
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
ReactContext reactContext = (ReactContext) getContext();
|
||||
ReactEditTextInputConnectionWrapper inputConnectionWrapper =
|
||||
new ReactEditTextInputConnectionWrapper(super.onCreateInputConnection(outAttrs), reactContext, this);
|
||||
InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
|
||||
if (inputConnection != null) {
|
||||
inputConnection = new ReactEditTextInputConnectionWrapper(inputConnection, reactContext, this);
|
||||
}
|
||||
|
||||
if (isMultiline() && getBlurOnSubmit()) {
|
||||
// Remove IME_FLAG_NO_ENTER_ACTION to keep the original IME_OPTION
|
||||
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
|
||||
}
|
||||
return inputConnectionWrapper;
|
||||
return inputConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-5
@@ -94,14 +94,15 @@ class ReactEditTextInputConnectionWrapper extends InputConnectionWrapper {
|
||||
int previousSelectionEnd = mEditText.getSelectionEnd();
|
||||
String key;
|
||||
boolean consumed = super.setComposingText(text, newCursorPosition);
|
||||
int currentSelectionStart = mEditText.getSelectionStart();
|
||||
boolean noPreviousSelection = previousSelectionStart == previousSelectionEnd;
|
||||
boolean cursorDidNotMove = mEditText.getSelectionStart() == previousSelectionStart;
|
||||
boolean cursorMovedBackwards = mEditText.getSelectionStart() < previousSelectionStart;
|
||||
if ((noPreviousSelection && cursorMovedBackwards)
|
||||
|| !noPreviousSelection && cursorDidNotMove) {
|
||||
boolean cursorDidNotMove = currentSelectionStart == previousSelectionStart;
|
||||
boolean cursorMovedBackwardsOrAtBeginningOfInput =
|
||||
(currentSelectionStart < previousSelectionStart) || currentSelectionStart <= 0;
|
||||
if (cursorMovedBackwardsOrAtBeginningOfInput || (!noPreviousSelection && cursorDidNotMove)) {
|
||||
key = BACKSPACE_KEY_VALUE;
|
||||
} else {
|
||||
key = String.valueOf(mEditText.getText().charAt(mEditText.getSelectionStart() - 1));
|
||||
key = String.valueOf(mEditText.getText().charAt(currentSelectionStart - 1));
|
||||
}
|
||||
dispatchKeyEventOrEnqueue(key);
|
||||
return consumed;
|
||||
|
||||
+23
-18
@@ -24,14 +24,19 @@ import static org.fest.assertions.api.Assertions.assertThat;
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class MultipartStreamReaderTest {
|
||||
|
||||
class CallCountTrackingChunkCallback implements MultipartStreamReader.ChunkCallback {
|
||||
class CallCountTrackingChunkCallback implements MultipartStreamReader.ChunkListener {
|
||||
private int mCount = 0;
|
||||
|
||||
@Override
|
||||
public void execute(Map<String, String> headers, Buffer body, boolean done) throws IOException {
|
||||
public void onChunkComplete(Map<String, String> headers, Buffer body, boolean done) throws IOException {
|
||||
mCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkProgress(Map<String, String> headers, long loaded, long total) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public int getCallCount() {
|
||||
return mCount;
|
||||
}
|
||||
@@ -41,12 +46,12 @@ public class MultipartStreamReaderTest {
|
||||
public void testSimpleCase() throws IOException {
|
||||
ByteString response = ByteString.encodeUtf8(
|
||||
"preable, should be ignored\r\n" +
|
||||
"--sample_boundary\r\n" +
|
||||
"Content-Type: application/json; charset=utf-8\r\n" +
|
||||
"Content-Length: 2\r\n\r\n" +
|
||||
"{}\r\n" +
|
||||
"--sample_boundary--\r\n" +
|
||||
"epilogue, should be ignored");
|
||||
"--sample_boundary\r\n" +
|
||||
"Content-Type: application/json; charset=utf-8\r\n" +
|
||||
"Content-Length: 2\r\n\r\n" +
|
||||
"{}\r\n" +
|
||||
"--sample_boundary--\r\n" +
|
||||
"epilogue, should be ignored");
|
||||
|
||||
Buffer source = new Buffer();
|
||||
source.write(response);
|
||||
@@ -55,8 +60,8 @@ public class MultipartStreamReaderTest {
|
||||
|
||||
CallCountTrackingChunkCallback callback = new CallCountTrackingChunkCallback() {
|
||||
@Override
|
||||
public void execute(Map<String, String> headers, Buffer body, boolean done) throws IOException {
|
||||
super.execute(headers, body, done);
|
||||
public void onChunkComplete(Map<String, String> headers, Buffer body, boolean done) throws IOException {
|
||||
super.onChunkComplete(headers, body, done);
|
||||
|
||||
assertThat(done).isTrue();
|
||||
assertThat(headers.get("Content-Type")).isEqualTo("application/json; charset=utf-8");
|
||||
@@ -89,8 +94,8 @@ public class MultipartStreamReaderTest {
|
||||
|
||||
CallCountTrackingChunkCallback callback = new CallCountTrackingChunkCallback() {
|
||||
@Override
|
||||
public void execute(Map<String, String> headers, Buffer body, boolean done) throws IOException {
|
||||
super.execute(headers, body, done);
|
||||
public void onChunkComplete(Map<String, String> headers, Buffer body, boolean done) throws IOException {
|
||||
super.onChunkComplete(headers, body, done);
|
||||
|
||||
assertThat(done).isEqualTo(getCallCount() == 3);
|
||||
assertThat(body.readUtf8()).isEqualTo(String.valueOf(getCallCount()));
|
||||
@@ -122,12 +127,12 @@ public class MultipartStreamReaderTest {
|
||||
public void testNoCloseDelimiter() throws IOException {
|
||||
ByteString response = ByteString.encodeUtf8(
|
||||
"preable, should be ignored\r\n" +
|
||||
"--sample_boundary\r\n" +
|
||||
"Content-Type: application/json; charset=utf-8\r\n" +
|
||||
"Content-Length: 2\r\n\r\n" +
|
||||
"{}\r\n" +
|
||||
"--sample_boundary\r\n" +
|
||||
"incomplete message...");
|
||||
"--sample_boundary\r\n" +
|
||||
"Content-Type: application/json; charset=utf-8\r\n" +
|
||||
"Content-Length: 2\r\n\r\n" +
|
||||
"{}\r\n" +
|
||||
"--sample_boundary\r\n" +
|
||||
"incomplete message...");
|
||||
|
||||
Buffer source = new Buffer();
|
||||
source.write(response);
|
||||
|
||||
@@ -126,3 +126,5 @@ exports.dependencyConfig = function dependencyConfigAndroid(folder, userConfig)
|
||||
|
||||
return { sourceDir, folder, manifest, packageImportPath, packageInstance };
|
||||
};
|
||||
|
||||
exports.linkConfig = require('../../link/android');
|
||||
|
||||
@@ -57,3 +57,5 @@ exports.projectConfig = function projectConfigIOS(folder, userConfig) {
|
||||
};
|
||||
|
||||
exports.dependencyConfig = exports.projectConfig;
|
||||
|
||||
exports.linkConfig = require('../../link/ios');
|
||||
|
||||
@@ -81,8 +81,10 @@ describe('link', () => {
|
||||
it('should register native module when android/ios projects are present', (done) => {
|
||||
const registerNativeModule = sinon.stub();
|
||||
const dependencyConfig = {android: {}, ios: {}, assets: [], commands: {}};
|
||||
const androidLinkConfig = require('../android');
|
||||
const iosLinkConfig = require('../ios');
|
||||
const config = {
|
||||
getPlatformConfig: () => ({ios: {}, android: {}}),
|
||||
getPlatformConfig: () => ({ios: { linkConfig: iosLinkConfig }, android: { linkConfig: androidLinkConfig }}),
|
||||
getProjectConfig: () => ({android: {}, ios: {}, assets: []}),
|
||||
getDependencyConfig: sinon.stub().returns(dependencyConfig),
|
||||
};
|
||||
@@ -223,8 +225,9 @@ describe('link', () => {
|
||||
sinon.stub().returns(false)
|
||||
);
|
||||
|
||||
const linkConfig = require('../ios');
|
||||
const config = {
|
||||
getPlatformConfig: () => ({ ios: {}}),
|
||||
getPlatformConfig: () => ({ ios: { linkConfig: linkConfig }}),
|
||||
getProjectConfig: () => ({ ios: {}, assets: [] }),
|
||||
getDependencyConfig: sinon.stub().returns({
|
||||
ios: {}, assets: [], commands: { prelink, postlink },
|
||||
@@ -251,8 +254,9 @@ describe('link', () => {
|
||||
copyAssets
|
||||
);
|
||||
|
||||
const linkConfig = require('../ios');
|
||||
const config = {
|
||||
getPlatformConfig: () => ({ ios: {} }),
|
||||
getPlatformConfig: () => ({ ios: { linkConfig: linkConfig } }),
|
||||
getProjectConfig: () => ({ ios: {}, assets: projectAssets }),
|
||||
getDependencyConfig: sinon.stub().returns(dependencyConfig),
|
||||
};
|
||||
|
||||
@@ -17,10 +17,10 @@ const groupFilesByType = require('../groupFilesByType');
|
||||
* For now, the only types of files that are handled are:
|
||||
* - Fonts (otf, ttf) - copied to targetPath/fonts under original name
|
||||
*/
|
||||
module.exports = function copyAssetsAndroid(files, targetPath) {
|
||||
module.exports = function copyAssetsAndroid(files, project) {
|
||||
const assets = groupFilesByType(files);
|
||||
|
||||
(assets.font || []).forEach(asset =>
|
||||
fs.copySync(asset, path.join(targetPath, 'fonts', path.basename(asset)))
|
||||
fs.copySync(asset, path.join(project.assetsPath, 'fonts', path.basename(asset)))
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
module.exports = function() {
|
||||
return {
|
||||
isInstalled: require('./isInstalled'),
|
||||
register: require('./registerNativeModule'),
|
||||
unregister: require('./unregisterNativeModule'),
|
||||
copyAssets: require('./copyAssets'),
|
||||
unlinkAssets: require('./unlinkAssets')
|
||||
};
|
||||
};
|
||||
@@ -17,11 +17,11 @@ const groupFilesByType = require('../groupFilesByType');
|
||||
* For now, the only types of files that are handled are:
|
||||
* - Fonts (otf, ttf) - copied to targetPath/fonts under original name
|
||||
*/
|
||||
module.exports = function unlinkAssetsAndroid(files, targetPath) {
|
||||
module.exports = function unlinkAssetsAndroid(files, project) {
|
||||
const assets = groupFilesByType(files);
|
||||
|
||||
(assets.font || []).forEach((file) => {
|
||||
const filePath = path.join(targetPath, 'fonts', path.basename(file));
|
||||
const filePath = path.join(project.assetsPath, 'fonts', path.basename(file));
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.unlinkSync(filePath);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
const isInstalledIOS = require('../isInstalled');
|
||||
const isInstalledPods = require('../../pods/isInstalled');
|
||||
|
||||
module.exports = function isInstalled(projectConfig, name, dependencyConfig) {
|
||||
return isInstalledIOS(projectConfig, dependencyConfig) || isInstalledPods(projectConfig, dependencyConfig);
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
const registerDependencyIOS = require('../registerNativeModule');
|
||||
const registerDependencyPods = require('../../pods/registerNativeModule');
|
||||
|
||||
module.exports = function registerNativeModule(
|
||||
name,
|
||||
dependencyConfig,
|
||||
params,
|
||||
projectConfig
|
||||
) {
|
||||
if (projectConfig.podfile && dependencyConfig.podspec) {
|
||||
registerDependencyPods(name, dependencyConfig, projectConfig);
|
||||
}
|
||||
else {
|
||||
registerDependencyIOS(dependencyConfig, projectConfig);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
const compact = require('lodash').compact;
|
||||
const isInstalledIOS = require('../isInstalled');
|
||||
const isInstalledPods = require('../../pods/isInstalled');
|
||||
const unregisterDependencyIOS = require('../unregisterNativeModule');
|
||||
const unregisterDependencyPods = require('../../pods/unregisterNativeModule');
|
||||
|
||||
module.exports = function unregisterNativeModule(
|
||||
name,
|
||||
dependencyConfig,
|
||||
projectConfig,
|
||||
otherDependencies
|
||||
) {
|
||||
const isIosInstalled = isInstalledIOS(projectConfig, dependencyConfig);
|
||||
const isPodInstalled = isInstalledPods(projectConfig, dependencyConfig);
|
||||
if (isIosInstalled) {
|
||||
const iOSDependencies = compact(otherDependencies.map(d => d.config.ios));
|
||||
unregisterDependencyIOS(dependencyConfig, projectConfig, iOSDependencies);
|
||||
}
|
||||
else if (isPodInstalled) {
|
||||
unregisterDependencyPods(dependencyConfig, projectConfig);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
module.exports = function() {
|
||||
return {
|
||||
isInstalled: require('./common/isInstalled'),
|
||||
register: require('./common/registerNativeModule'),
|
||||
unregister: require('./common/unregisterNativeModule'),
|
||||
copyAssets: require('./copyAssets'),
|
||||
unlinkAssets: require('./unlinkAssets')
|
||||
};
|
||||
};
|
||||
+12
-84
@@ -26,14 +26,6 @@ const chalk = require('chalk');
|
||||
* run Flow. */
|
||||
const isEmpty = require('lodash').isEmpty;
|
||||
const promiseWaterfall = require('./promiseWaterfall');
|
||||
const registerDependencyAndroid = require('./android/registerNativeModule');
|
||||
const registerDependencyIOS = require('./ios/registerNativeModule');
|
||||
const registerDependencyPods = require('./pods/registerNativeModule');
|
||||
const isInstalledAndroid = require('./android/isInstalled');
|
||||
const isInstalledIOS = require('./ios/isInstalled');
|
||||
const isInstalledPods = require('./pods/isInstalled');
|
||||
const copyAssetsAndroid = require('./android/copyAssets');
|
||||
const copyAssetsIOS = require('./ios/copyAssets');
|
||||
const getProjectDependencies = require('./getProjectDependencies');
|
||||
const getDependencyConfig = require('./getDependencyConfig');
|
||||
const pollParams = require('./pollParams');
|
||||
@@ -47,37 +39,10 @@ log.heading = 'rnpm-link';
|
||||
|
||||
const dedupeAssets = (assets) => uniqBy(assets, asset => path.basename(asset));
|
||||
|
||||
const linkDependency = async (platforms, project, dependency) => {
|
||||
const params = await pollParams(dependency.config.params);
|
||||
|
||||
const linkDependencyAndroid = (androidProject, dependency) => {
|
||||
if (!androidProject || !dependency.config.android) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isInstalled = isInstalledAndroid(androidProject, dependency.name);
|
||||
|
||||
if (isInstalled) {
|
||||
log.info(chalk.grey(`Android module ${dependency.name} is already linked`));
|
||||
return null;
|
||||
}
|
||||
|
||||
return pollParams(dependency.config.params).then(params => {
|
||||
log.info(`Linking ${dependency.name} android dependency`);
|
||||
|
||||
registerDependencyAndroid(
|
||||
dependency.name,
|
||||
dependency.config.android,
|
||||
params,
|
||||
androidProject
|
||||
);
|
||||
|
||||
log.info(`Android module ${dependency.name} has been successfully linked`);
|
||||
});
|
||||
};
|
||||
|
||||
const linkDependencyPlatforms = (platforms, project, dependency) => {
|
||||
const ignorePlatforms = ['android', 'ios'];
|
||||
Object.keys(platforms || {})
|
||||
.filter(platform => ignorePlatforms.indexOf(platform) < 0)
|
||||
.forEach(platform => {
|
||||
if (!project[platform] || !dependency.config[platform]) {
|
||||
return null;
|
||||
@@ -88,67 +53,32 @@ const linkDependencyPlatforms = (platforms, project, dependency) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isInstalled = linkConfig.isInstalled(project[platform], dependency.config[platform]);
|
||||
const isInstalled = linkConfig.isInstalled(project[platform], dependency.name, dependency.config[platform]);
|
||||
|
||||
if (isInstalled) {
|
||||
log.info(chalk.grey(`Platform '${platform}' module ${dependency.name} is already linked`));
|
||||
return null;
|
||||
}
|
||||
|
||||
return pollParams(dependency.config.params).then(params => {
|
||||
log.info(`Linking ${dependency.name} ${platform} dependency`);
|
||||
log.info(`Linking ${dependency.name} ${platform} dependency`);
|
||||
|
||||
linkConfig.register(
|
||||
dependency.name,
|
||||
dependency.config[platform],
|
||||
params,
|
||||
project[platform]
|
||||
);
|
||||
linkConfig.register(
|
||||
dependency.name,
|
||||
dependency.config[platform],
|
||||
params,
|
||||
project[platform]
|
||||
);
|
||||
|
||||
log.info(`Platform '${platform}' module ${dependency.name} has been successfully linked`);
|
||||
});
|
||||
log.info(`Platform '${platform}' module ${dependency.name} has been successfully linked`);
|
||||
});
|
||||
};
|
||||
|
||||
const linkDependencyIOS = (iOSProject, dependency) => {
|
||||
if (!iOSProject || !dependency.config.ios) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isInstalled = isInstalledIOS(iOSProject, dependency.config.ios) || isInstalledPods(iOSProject, dependency.config.ios);
|
||||
if (isInstalled) {
|
||||
log.info(chalk.grey(`iOS module ${dependency.name} is already linked`));
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(`Linking ${dependency.name} ios dependency`);
|
||||
if (iOSProject.podfile && dependency.config.ios.podspec) {
|
||||
registerDependencyPods(dependency, iOSProject);
|
||||
}
|
||||
else {
|
||||
registerDependencyIOS(dependency.config.ios, iOSProject);
|
||||
}
|
||||
log.info(`iOS module ${dependency.name} has been successfully linked`);
|
||||
};
|
||||
|
||||
const linkAssets = (platforms, project, assets) => {
|
||||
if (isEmpty(assets)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (project.ios) {
|
||||
log.info('Linking assets to ios project');
|
||||
copyAssetsIOS(assets, project.ios);
|
||||
}
|
||||
|
||||
if (project.android) {
|
||||
log.info('Linking assets to android project');
|
||||
copyAssetsAndroid(assets, project.android.assetsPath);
|
||||
}
|
||||
|
||||
const ignorePlatforms = ['android', 'ios'];
|
||||
Object.keys(platforms || {})
|
||||
.filter(platform => ignorePlatforms.indexOf(platform) < 0)
|
||||
.forEach(platform => {
|
||||
const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig();
|
||||
if (!linkConfig || !linkConfig.copyAssets) {
|
||||
@@ -212,9 +142,7 @@ function link(args: Array<string>, config: RNConfig) {
|
||||
|
||||
const tasks = flatten(dependencies.map(dependency => [
|
||||
() => promisify(dependency.config.commands.prelink || commandStub),
|
||||
() => linkDependencyAndroid(project.android, dependency),
|
||||
() => linkDependencyIOS(project.ios, dependency),
|
||||
() => linkDependencyPlatforms(platforms, project, dependency),
|
||||
() => linkDependency(platforms, project, dependency),
|
||||
() => promisify(dependency.config.commands.postlink || commandStub),
|
||||
]));
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@ const findMarkedLinesInPodfile = require('./findMarkedLinesInPodfile');
|
||||
const addPodEntry = require('./addPodEntry');
|
||||
const savePodFile = require('./savePodFile');
|
||||
|
||||
module.exports = function registerNativeModulePods(dependency, iOSProject) {
|
||||
module.exports = function registerNativeModulePods(name, dependencyConfig, iOSProject) {
|
||||
const podLines = readPodfile(iOSProject.podfile);
|
||||
const linesToAddEntry = getLinesToAddEntry(podLines, iOSProject);
|
||||
addPodEntry(podLines, linesToAddEntry, dependency.config.ios.podspec, dependency.name);
|
||||
addPodEntry(podLines, linesToAddEntry, dependencyConfig.podspec, name);
|
||||
savePodFile(iOSProject.podfile, podLines);
|
||||
};
|
||||
|
||||
|
||||
+17
-72
@@ -10,16 +10,7 @@
|
||||
const log = require('npmlog');
|
||||
|
||||
const getProjectDependencies = require('./getProjectDependencies');
|
||||
const unregisterDependencyAndroid = require('./android/unregisterNativeModule');
|
||||
const unregisterDependencyIOS = require('./ios/unregisterNativeModule');
|
||||
const unregisterDependencyPods = require('./pods/unregisterNativeModule');
|
||||
const isInstalledAndroid = require('./android/isInstalled');
|
||||
const isInstalledIOS = require('./ios/isInstalled');
|
||||
const isInstalledPods = require('./pods/isInstalled');
|
||||
const unlinkAssetsAndroid = require('./android/unlinkAssets');
|
||||
const unlinkAssetsIOS = require('./ios/unlinkAssets');
|
||||
const getDependencyConfig = require('./getDependencyConfig');
|
||||
const compact = require('lodash').compact;
|
||||
const difference = require('lodash').difference;
|
||||
const filter = require('lodash').filter;
|
||||
const flatten = require('lodash').flatten;
|
||||
@@ -30,41 +21,20 @@ const promisify = require('./promisify');
|
||||
|
||||
log.heading = 'rnpm-link';
|
||||
|
||||
const unlinkDependencyAndroid = (androidProject, dependency, packageName) => {
|
||||
if (!androidProject || !dependency.android) {
|
||||
return;
|
||||
}
|
||||
const unlinkDependency = (platforms, project, dependency, packageName, otherDependencies) => {
|
||||
|
||||
const isInstalled = isInstalledAndroid(androidProject, packageName);
|
||||
|
||||
if (!isInstalled) {
|
||||
log.info(`Android module ${packageName} is not installed`);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(`Unlinking ${packageName} android dependency`);
|
||||
|
||||
unregisterDependencyAndroid(packageName, dependency.android, androidProject);
|
||||
|
||||
log.info(`Android module ${packageName} has been successfully unlinked`);
|
||||
};
|
||||
|
||||
const unlinkDependencyPlatforms = (platforms, project, dependency, packageName) => {
|
||||
|
||||
const ignorePlatforms = ['android', 'ios'];
|
||||
Object.keys(platforms || {})
|
||||
.filter(platform => ignorePlatforms.indexOf(platform) < 0)
|
||||
.forEach(platform => {
|
||||
if (!project[platform] || !dependency[platform]) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig();
|
||||
if (!linkConfig || !linkConfig.isInstalled || !linkConfig.unregister) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
const isInstalled = linkConfig.isInstalled(project[platform], dependency[platform]);
|
||||
const isInstalled = linkConfig.isInstalled(project[platform], packageName, dependency[platform]);
|
||||
|
||||
if (!isInstalled) {
|
||||
log.info(`Platform '${platform}' module ${packageName} is not installed`);
|
||||
@@ -76,37 +46,14 @@ const unlinkDependencyPlatforms = (platforms, project, dependency, packageName)
|
||||
linkConfig.unregister(
|
||||
packageName,
|
||||
dependency[platform],
|
||||
project[platform]
|
||||
project[platform],
|
||||
otherDependencies
|
||||
);
|
||||
|
||||
log.info(`Platform '${platform}' module ${dependency.name} has been successfully unlinked`);
|
||||
});
|
||||
};
|
||||
|
||||
const unlinkDependencyIOS = (iOSProject, dependency, packageName, iOSDependencies) => {
|
||||
if (!iOSProject || !dependency.ios) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isIosInstalled = isInstalledIOS(iOSProject, dependency.ios);
|
||||
const isPodInstalled = isInstalledPods(iOSProject, dependency.ios);
|
||||
if (!isIosInstalled && !isPodInstalled) {
|
||||
log.info(`iOS module ${packageName} is not installed`);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(`Unlinking ${packageName} ios dependency`);
|
||||
|
||||
if (isIosInstalled) {
|
||||
unregisterDependencyIOS(dependency.ios, iOSProject, iOSDependencies);
|
||||
}
|
||||
else if (isPodInstalled) {
|
||||
unregisterDependencyPods(dependency.ios, iOSProject);
|
||||
}
|
||||
|
||||
log.info(`iOS module ${packageName} has been successfully unlinked`);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates project and unlink specific dependency
|
||||
*
|
||||
@@ -143,13 +90,10 @@ function unlink(args, config) {
|
||||
|
||||
const allDependencies = getDependencyConfig(config, getProjectDependencies());
|
||||
const otherDependencies = filter(allDependencies, d => d.name !== packageName);
|
||||
const iOSDependencies = compact(otherDependencies.map(d => d.config.ios));
|
||||
|
||||
const tasks = [
|
||||
() => promisify(dependency.commands.preunlink || commandStub),
|
||||
() => unlinkDependencyAndroid(project.android, dependency, packageName),
|
||||
() => unlinkDependencyIOS(project.ios, dependency, packageName, iOSDependencies),
|
||||
() => unlinkDependencyPlatforms(platforms, project, dependency, packageName),
|
||||
() => unlinkDependency(platforms, project, dependency, packageName, otherDependencies),
|
||||
() => promisify(dependency.commands.postunlink || commandStub)
|
||||
];
|
||||
|
||||
@@ -166,15 +110,16 @@ function unlink(args, config) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (project.ios) {
|
||||
log.info('Unlinking assets from ios project');
|
||||
unlinkAssetsIOS(assets, project.ios);
|
||||
}
|
||||
|
||||
if (project.android) {
|
||||
log.info('Unlinking assets from android project');
|
||||
unlinkAssetsAndroid(assets, project.android.assetsPath);
|
||||
}
|
||||
Object.keys(platforms || {})
|
||||
.forEach(platform => {
|
||||
const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig();
|
||||
if (!linkConfig || !linkConfig.unlinkAssets) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(`Unlinking assets from ${platform} project`);
|
||||
linkConfig.unlinkAssets(assets, project[platform]);
|
||||
});
|
||||
|
||||
log.info(
|
||||
`${packageName} assets has been successfully unlinked from your project`
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
pre: new Map(),
|
||||
post: new Map(),
|
||||
modules: new Map(),
|
||||
id: undefined,
|
||||
};
|
||||
this._initialized = false;
|
||||
this._lastNumModifiedFiles = 0;
|
||||
@@ -68,6 +69,7 @@
|
||||
pre: new Map(),
|
||||
post: new Map(),
|
||||
modules: new Map(),
|
||||
id: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,9 +84,15 @@
|
||||
this._patchMap(this._lastBundle.post, deltaBundle.post);
|
||||
this._patchMap(this._lastBundle.modules, deltaBundle.delta);
|
||||
|
||||
this._lastBundle.id = deltaBundle.id;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
getLastBundleId() {
|
||||
return this._lastBundle.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of modified files in the last received Delta. This is
|
||||
* currently used to populate the `X-Metro-Files-Changed-Count` HTTP header
|
||||
|
||||
@@ -22,31 +22,34 @@
|
||||
* whole JS bundle Blob.
|
||||
*/
|
||||
async function deltaUrlToBlobUrl(deltaUrl) {
|
||||
let cachedBundle = cachedBundleUrls.get(deltaUrl);
|
||||
const client = global.DeltaPatcher.get(deltaUrl);
|
||||
|
||||
const deltaBundleId = cachedBundle
|
||||
? `&deltaBundleId=${cachedBundle.id}`
|
||||
const deltaBundleId = client.getLastBundleId()
|
||||
? `&deltaBundleId=${client.getLastBundleId()}`
|
||||
: '';
|
||||
|
||||
const data = await fetch(deltaUrl + deltaBundleId);
|
||||
const bundle = await data.json();
|
||||
|
||||
const deltaPatcher = global.DeltaPatcher.get(bundle.id).applyDelta({
|
||||
const deltaPatcher = client.applyDelta({
|
||||
id: bundle.id,
|
||||
pre: new Map(bundle.pre),
|
||||
post: new Map(bundle.post),
|
||||
delta: new Map(bundle.delta),
|
||||
reset: bundle.reset,
|
||||
});
|
||||
|
||||
let cachedBundle = cachedBundleUrls.get(deltaUrl);
|
||||
|
||||
// If nothing changed, avoid recreating a bundle blob by reusing the
|
||||
// previous one.
|
||||
if (deltaPatcher.getLastNumModifiedFiles() === 0 && cachedBundle) {
|
||||
return cachedBundle.url;
|
||||
return cachedBundle;
|
||||
}
|
||||
|
||||
// Clean up the previous bundle URL to not leak memory.
|
||||
if (cachedBundle) {
|
||||
URL.revokeObjectURL(cachedBundle.url);
|
||||
URL.revokeObjectURL(cachedBundle);
|
||||
}
|
||||
|
||||
// To make Source Maps work correctly, we need to add a newline between
|
||||
@@ -60,13 +63,10 @@
|
||||
type: 'application/javascript',
|
||||
});
|
||||
|
||||
const bundleUrl = URL.createObjectURL(blob);
|
||||
cachedBundleUrls.set(deltaUrl, {
|
||||
id: bundle.id,
|
||||
url: bundleUrl,
|
||||
});
|
||||
const bundleContents = URL.createObjectURL(blob);
|
||||
cachedBundleUrls.set(deltaUrl, bundleContents);
|
||||
|
||||
return bundleUrl;
|
||||
return bundleContents;
|
||||
}
|
||||
|
||||
global.deltaUrlToBlobUrl = deltaUrlToBlobUrl;
|
||||
|
||||
@@ -17,7 +17,7 @@ const getPolyfills = require('../../rn-get-polyfills');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
const path = require('path');
|
||||
|
||||
const {Config: MetroConfig} = require('metro');
|
||||
const {Config: MetroConfig, createBlacklist} = require('metro');
|
||||
|
||||
const RN_CLI_CONFIG = 'rn-cli.config.js';
|
||||
|
||||
@@ -56,6 +56,10 @@ const getProjectRoots = () => {
|
||||
return resolveSymlinksForRoots([getProjectPath()]);
|
||||
};
|
||||
|
||||
const getBlacklistRE = () => {
|
||||
return createBlacklist([/.*\/__fixtures__\/.*/]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Module capable of getting the configuration out of a given file.
|
||||
*
|
||||
@@ -67,6 +71,7 @@ const getProjectRoots = () => {
|
||||
const Config = {
|
||||
DEFAULT: ({
|
||||
...MetroConfig.DEFAULT,
|
||||
getBlacklistRE,
|
||||
getProjectRoots,
|
||||
getPolyfills,
|
||||
getModulesRunBeforeMainModule: () => [
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"version": "1000.0.0",
|
||||
"version": "0.54.4",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": {
|
||||
@@ -143,7 +143,7 @@
|
||||
"react-native": "local-cli/wrong-react-native.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.3.0-alpha.0"
|
||||
"react": "^16.3.0-alpha.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"absolute-path": "^0.0.0",
|
||||
@@ -175,8 +175,8 @@
|
||||
"graceful-fs": "^4.1.3",
|
||||
"inquirer": "^3.0.6",
|
||||
"lodash": "^4.17.5",
|
||||
"metro": "^0.25.1",
|
||||
"metro-core": "^0.25.1",
|
||||
"metro": "^0.28.0",
|
||||
"metro-core": "^0.28.0",
|
||||
"mime": "^1.3.4",
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
@@ -219,9 +219,9 @@
|
||||
"jest": "22.2.1",
|
||||
"jest-junit": "3.5.0",
|
||||
"prettier": "1.9.1",
|
||||
"react": "^16.3.0-alpha.0",
|
||||
"react-test-renderer": "^16.3.0-alpha.0",
|
||||
"react": "^16.3.0-alpha.1",
|
||||
"react-test-renderer": "^16.3.0-alpha.1",
|
||||
"shelljs": "^0.7.8",
|
||||
"sinon": "^2.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user