mirror of https://github.com/status-im/metro.git
Updates from Thu 9 Apr
- [React Native] Fix RCTText crashes | Alex Akers - Ensure that NSLocationWhenInUseUsageDescription is set, throw error if not | Alex Kotliarskyi - [ReactNative] fix exception handler method name | Spencer Ahrens - [ReactNative] Re-configure horizontal swipe animations | Eric Vicenti - [ReactNative] <Text>: apply the fontWeight correctly if fontFamily style is also present | Kevin Gozali - [MAdMan] Dimensions.get('window') considered harmful | Philipp von Weitershausen - Navigator: Changed transitioner background color to 'transparent' | Eric Vicenti - [react-native] Listen on all IPv6 interfaces | Ben Alpert - [react-packager] Don't depend on error.stack being available | Amjad Masad - [ReactNative] fixup AnimationExperimental a bit | Spencer Ahrens - [react-packager] Implement new style asset packaging (with dimensions) | Amjad Masad - [React Native] RCT_EXPORT lvl.2 | Alex Akers - [react_native] Implement TextInput end editing | Andrei Coman - [react_native] Make TextInput focus, blur, dismiss and show keyboard work | Andrei Coman - Added non-class-scanning-based approach fror registering js methods | Nick Lockwood - [ReactNative] Update package.json | Christopher Chedeau - [ReactNative] Do flow check when running packager | Spencer Ahrens - [ReactNative] Fix typo/bug in Navigator._completeTransition | Eric Vicenti - [ReactNative] Fix Navigator exception when touching during transition | Eric Vicenti - [ReactNative] Remove bridge retaining cycles | Tadeu Zagallo - [ReactNative] Fix and re-add WebView executor | Tadeu Zagallo
This commit is contained in:
parent
0c6c300c0d
commit
caa89c36f0
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* 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';
|
||||||
|
|
||||||
|
var exec = require('child_process').exec;
|
||||||
|
|
||||||
|
function getFlowTypeCheckMiddleware(options) {
|
||||||
|
return function(req, res, next) {
|
||||||
|
if (options.skipflow) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
if (options.flowroot || options.projectRoots.length === 1) {
|
||||||
|
var flowroot = options.flowroot || options.projectRoots[0];
|
||||||
|
} else {
|
||||||
|
console.warn('flow: No suitable root');
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
exec('command -v flow >/dev/null 2>&1', function(error, stdout) {
|
||||||
|
if (error) {
|
||||||
|
console.warn('flow: Skipping because not installed. Install with ' +
|
||||||
|
'`brew install flow`.');
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
return doFlowTypecheck(res, flowroot, next);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function doFlowTypecheck(res, flowroot, next) {
|
||||||
|
var flowCmd = 'cd "' + flowroot + '" && flow --json --timeout 20';
|
||||||
|
var start = Date.now();
|
||||||
|
console.log('flow: Running static typechecks.');
|
||||||
|
exec(flowCmd, function(flowError, stdout) {
|
||||||
|
if (!flowError) {
|
||||||
|
console.log('flow: Typechecks passed (' + (Date.now() - start) + 'ms).');
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var flowResponse = JSON.parse(stdout);
|
||||||
|
var errors = [];
|
||||||
|
var errorNum = 1;
|
||||||
|
flowResponse.errors.forEach(function(err) {
|
||||||
|
// flow errors are paired across callsites, so we indent and prefix to
|
||||||
|
// group them
|
||||||
|
var indent = '';
|
||||||
|
err.message.forEach(function(msg) {
|
||||||
|
errors.push({
|
||||||
|
description: indent + 'E' + errorNum + ': ' + msg.descr,
|
||||||
|
filename: msg.path,
|
||||||
|
lineNumber: msg.line,
|
||||||
|
column: msg.start,
|
||||||
|
});
|
||||||
|
indent = ' ';
|
||||||
|
});
|
||||||
|
errorNum++;
|
||||||
|
});
|
||||||
|
var message = 'Flow found type errors. If you think these are wrong, ' +
|
||||||
|
'make sure flow is up to date, or disable with --skipflow.';
|
||||||
|
} catch (e) {
|
||||||
|
var message =
|
||||||
|
'Flow failed to provide parseable output:\n\n`' + stdout + '`';
|
||||||
|
console.error(message, '\nException: `', e, '`\n\n');
|
||||||
|
}
|
||||||
|
var error = {
|
||||||
|
status: 500,
|
||||||
|
message: message,
|
||||||
|
type: 'FlowError',
|
||||||
|
errors: errors,
|
||||||
|
};
|
||||||
|
console.error('flow: Error running command `' + flowCmd + '`:\n', error);
|
||||||
|
res.writeHead(error.status, {
|
||||||
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
|
});
|
||||||
|
res.end(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = getFlowTypeCheckMiddleware;
|
|
@ -13,6 +13,8 @@ var path = require('path');
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
|
|
||||||
|
var getFlowTypeCheckMiddleware = require('./getFlowTypeCheckMiddleware');
|
||||||
|
|
||||||
if (!fs.existsSync(path.resolve(__dirname, '..', 'node_modules'))) {
|
if (!fs.existsSync(path.resolve(__dirname, '..', 'node_modules'))) {
|
||||||
console.log(
|
console.log(
|
||||||
'\n' +
|
'\n' +
|
||||||
|
@ -40,6 +42,9 @@ var options = parseCommandLine([{
|
||||||
}, {
|
}, {
|
||||||
command: 'assetRoots',
|
command: 'assetRoots',
|
||||||
description: 'specify the root directories of app assets'
|
description: 'specify the root directories of app assets'
|
||||||
|
}, {
|
||||||
|
command: 'skipflow',
|
||||||
|
description: 'Disable flow checks'
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
if (options.projectRoots) {
|
if (options.projectRoots) {
|
||||||
|
@ -203,6 +208,7 @@ function runServer(
|
||||||
.use(openStackFrameInEditor)
|
.use(openStackFrameInEditor)
|
||||||
.use(getDevToolsLauncher(options))
|
.use(getDevToolsLauncher(options))
|
||||||
.use(statusPageMiddleware)
|
.use(statusPageMiddleware)
|
||||||
|
.use(getFlowTypeCheckMiddleware(options))
|
||||||
.use(getAppMiddleware(options));
|
.use(getAppMiddleware(options));
|
||||||
|
|
||||||
options.projectRoots.forEach(function(root) {
|
options.projectRoots.forEach(function(root) {
|
||||||
|
@ -213,5 +219,5 @@ function runServer(
|
||||||
.use(connect.compress())
|
.use(connect.compress())
|
||||||
.use(connect.errorHandler());
|
.use(connect.errorHandler());
|
||||||
|
|
||||||
return http.createServer(app).listen(options.port, readyCallback);
|
return http.createServer(app).listen(options.port, '::', readyCallback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,13 @@ function ModuleDescriptor(fields) {
|
||||||
|
|
||||||
this.isPolyfill = fields.isPolyfill || false;
|
this.isPolyfill = fields.isPolyfill || false;
|
||||||
|
|
||||||
|
this.isAsset_DEPRECATED = fields.isAsset_DEPRECATED || false;
|
||||||
this.isAsset = fields.isAsset || false;
|
this.isAsset = fields.isAsset || false;
|
||||||
|
|
||||||
|
if (this.isAsset_DEPRECATED && this.isAsset) {
|
||||||
|
throw new Error('Cannot be an asset and a deprecated asset');
|
||||||
|
}
|
||||||
|
|
||||||
this.altId = fields.altId;
|
this.altId = fields.altId;
|
||||||
|
|
||||||
this._fields = fields;
|
this._fields = fields;
|
||||||
|
|
|
@ -92,7 +92,7 @@ describe('DependencyGraph', function() {
|
||||||
{ id: 'image!a',
|
{ id: 'image!a',
|
||||||
path: '/root/imgs/a.png',
|
path: '/root/imgs/a.png',
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
isAsset: true
|
isAsset_DEPRECATED: true
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -183,7 +183,7 @@ describe('DependencyGraph', function() {
|
||||||
id: 'image!a',
|
id: 'image!a',
|
||||||
path: '/root/imgs/a.png',
|
path: '/root/imgs/a.png',
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
isAsset: true
|
isAsset_DEPRECATED: true
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -954,7 +954,7 @@ describe('DependencyGraph', function() {
|
||||||
{ id: 'image!foo',
|
{ id: 'image!foo',
|
||||||
path: '/root/foo.png',
|
path: '/root/foo.png',
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
isAsset: true,
|
isAsset_DEPRECATED: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -596,7 +596,7 @@ DependecyGraph.prototype._processAsset_DEPRECATED = function(file) {
|
||||||
this._assetMap_DEPRECATED[name] = new ModuleDescriptor({
|
this._assetMap_DEPRECATED[name] = new ModuleDescriptor({
|
||||||
id: 'image!' + name,
|
id: 'image!' + name,
|
||||||
path: path.resolve(file),
|
path: path.resolve(file),
|
||||||
isAsset: true,
|
isAsset_DEPRECATED: true,
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ function formatError(err, filename, source) {
|
||||||
function formatGenericError(err, filename) {
|
function formatGenericError(err, filename) {
|
||||||
var msg = 'TransformError: ' + filename + ': ' + err.message;
|
var msg = 'TransformError: ' + filename + ': ' + err.message;
|
||||||
var error = new TransformError();
|
var error = new TransformError();
|
||||||
var stack = err.stack.split('\n').slice(0, -1);
|
var stack = (err.stack || '').split('\n').slice(0, -1);
|
||||||
stack.push(msg);
|
stack.push(msg);
|
||||||
error.stack = stack.join('\n');
|
error.stack = stack.join('\n');
|
||||||
error.message = msg;
|
error.message = msg;
|
||||||
|
|
|
@ -43,14 +43,21 @@ describe('Packager', function() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
var packager = new Packager({projectRoots: []});
|
var packager = new Packager({projectRoots: ['/root']});
|
||||||
var modules = [
|
var modules = [
|
||||||
{id: 'foo', path: '/root/foo.js', dependencies: []},
|
{id: 'foo', path: '/root/foo.js', dependencies: []},
|
||||||
{id: 'bar', path: '/root/bar.js', dependencies: []},
|
{id: 'bar', path: '/root/bar.js', dependencies: []},
|
||||||
{ id: 'image!img',
|
{
|
||||||
|
id: 'image!img',
|
||||||
path: '/root/img/img.png',
|
path: '/root/img/img.png',
|
||||||
isAsset: true,
|
isAsset_DEPRECATED: true,
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'new_image.png',
|
||||||
|
path: '/root/img/new_image.png',
|
||||||
|
isAsset: true,
|
||||||
|
dependencies: []
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -74,6 +81,10 @@ describe('Packager', function() {
|
||||||
return 'lol ' + code + ' lol';
|
return 'lol ' + code + ' lol';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
require('image-size').mockImpl(function(path, cb) {
|
||||||
|
cb(null, { width: 50, height: 100 });
|
||||||
|
});
|
||||||
|
|
||||||
return packager.package('/root/foo.js', true, 'source_map_url')
|
return packager.package('/root/foo.js', true, 'source_map_url')
|
||||||
.then(function(p) {
|
.then(function(p) {
|
||||||
expect(p.addModule.mock.calls[0]).toEqual([
|
expect(p.addModule.mock.calls[0]).toEqual([
|
||||||
|
@ -96,6 +107,24 @@ describe('Packager', function() {
|
||||||
'/root/img/img.png'
|
'/root/img/img.png'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
var imgModule = {
|
||||||
|
isStatic: true,
|
||||||
|
path: '/root/img/new_image.png',
|
||||||
|
uri: 'img/new_image.png',
|
||||||
|
width: 50,
|
||||||
|
height: 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(p.addModule.mock.calls[3]).toEqual([
|
||||||
|
'lol module.exports = ' +
|
||||||
|
JSON.stringify(imgModule) +
|
||||||
|
'; lol',
|
||||||
|
'module.exports = ' +
|
||||||
|
JSON.stringify(imgModule) +
|
||||||
|
';',
|
||||||
|
'/root/img/new_image.png'
|
||||||
|
]);
|
||||||
|
|
||||||
expect(p.finalize.mock.calls[0]).toEqual([
|
expect(p.finalize.mock.calls[0]).toEqual([
|
||||||
{runMainModule: true}
|
{runMainModule: true}
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -18,6 +18,7 @@ var _ = require('underscore');
|
||||||
var Package = require('./Package');
|
var Package = require('./Package');
|
||||||
var Activity = require('../Activity');
|
var Activity = require('../Activity');
|
||||||
var declareOpts = require('../lib/declareOpts');
|
var declareOpts = require('../lib/declareOpts');
|
||||||
|
var imageSize = require('image-size');
|
||||||
|
|
||||||
var validateOpts = declareOpts({
|
var validateOpts = declareOpts({
|
||||||
projectRoots: {
|
projectRoots: {
|
||||||
|
@ -88,6 +89,8 @@ function Packager(options) {
|
||||||
transformModulePath: opts.transformModulePath,
|
transformModulePath: opts.transformModulePath,
|
||||||
nonPersistent: opts.nonPersistent,
|
nonPersistent: opts.nonPersistent,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._projectRoots = opts.projectRoots;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packager.prototype.kill = function() {
|
Packager.prototype.kill = function() {
|
||||||
|
@ -138,8 +141,13 @@ Packager.prototype.getDependencies = function(main, isDev) {
|
||||||
Packager.prototype._transformModule = function(module) {
|
Packager.prototype._transformModule = function(module) {
|
||||||
var transform;
|
var transform;
|
||||||
|
|
||||||
if (module.isAsset) {
|
if (module.isAsset_DEPRECATED) {
|
||||||
transform = Promise.resolve(generateAssetModule(module));
|
transform = Promise.resolve(generateAssetModule_DEPRECATED(module));
|
||||||
|
} else if (module.isAsset) {
|
||||||
|
transform = generateAssetModule(
|
||||||
|
module,
|
||||||
|
getPathRelativeToRoot(this._projectRoots, module.path)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
transform = this._transformer.loadFileAndTransform(
|
transform = this._transformer.loadFileAndTransform(
|
||||||
path.resolve(module.path)
|
path.resolve(module.path)
|
||||||
|
@ -166,7 +174,7 @@ Packager.prototype.getGraphDebugInfo = function() {
|
||||||
return this._resolver.getDebugInfo();
|
return this._resolver.getDebugInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateAssetModule(module) {
|
function generateAssetModule_DEPRECATED(module) {
|
||||||
var code = 'module.exports = ' + JSON.stringify({
|
var code = 'module.exports = ' + JSON.stringify({
|
||||||
uri: module.id.replace(/^[^!]+!/, ''),
|
uri: module.id.replace(/^[^!]+!/, ''),
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
|
@ -179,4 +187,39 @@ function generateAssetModule(module) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sizeOf = Promise.promisify(imageSize);
|
||||||
|
|
||||||
|
function generateAssetModule(module, relPath) {
|
||||||
|
return sizeOf(module.path).then(function(dimensions) {
|
||||||
|
var img = {
|
||||||
|
isStatic: true,
|
||||||
|
path: module.path, //TODO(amasad): this should be path inside tar file.
|
||||||
|
uri: relPath,
|
||||||
|
width: dimensions.width,
|
||||||
|
height: dimensions.height,
|
||||||
|
};
|
||||||
|
|
||||||
|
var code = 'module.exports = ' + JSON.stringify(img) + ';';
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: code,
|
||||||
|
sourceCode: code,
|
||||||
|
sourcePath: module.path,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPathRelativeToRoot(roots, absPath) {
|
||||||
|
for (var i = 0; i < roots.length; i++) {
|
||||||
|
var relPath = path.relative(roots[i], absPath);
|
||||||
|
if (relPath[0] !== '.') {
|
||||||
|
return relPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
'Expected root module to be relative to one of the project roots'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Packager;
|
module.exports = Packager;
|
||||||
|
|
|
@ -320,6 +320,12 @@ function handleError(res, error) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error.type === 'TransformError' || error.type === 'NotFoundError') {
|
if (error.type === 'TransformError' || error.type === 'NotFoundError') {
|
||||||
|
error.errors = [{
|
||||||
|
description: error.description,
|
||||||
|
filename: error.filename,
|
||||||
|
lineNumber: error.lineNumber,
|
||||||
|
}];
|
||||||
|
console.error(error);
|
||||||
res.end(JSON.stringify(error));
|
res.end(JSON.stringify(error));
|
||||||
} else {
|
} else {
|
||||||
console.error(error.stack || error);
|
console.error(error.stack || error);
|
||||||
|
|
Loading…
Reference in New Issue