Martín Bigio 8c9c7e6286 Introduce transforms pipeline
Summary:
public

This diff introduces an internal transforms pipeline that integrates with the external one. This has been a feature we've been looking to implement for a long time to use babel instead of `replace` with regexps on many parts of the packager.

Also, to split the bundle we'll need to run one transform. Internally for Facebook we can run the system-import transform altogether withe the other ones. For OSS we offer `transformer.js` which people can use out of the box if they're writing ES6 code. For those people, `transformer.js` will also run the internal transforms`. However they might want to tune the transforms, or even write the code on another language that compiles to Javascript and use a complete different transformer. On those cases we'll need to run the external transforms first and pipe the output through the internal transforms. Note that the order it's important as the internal transforms assume the code is written in JS, though the original code could be on other scripting languages (CoffeeScript, TypeScript, etc).

Reviewed By: davidaurelio

Differential Revision: D2725109

fb-gh-sync-id: d764e209c78743419c4cb97068495c771372ab90
2016-01-04 11:32:42 -08:00

158 lines
4.5 KiB
JavaScript

/**
* 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';
const chalk = require('chalk');
const checkNodeVersion = require('./checkNodeVersion');
const formatBanner = require('./formatBanner');
const parseCommandLine = require('../util/parseCommandLine');
const path = require('path');
const Promise = require('promise');
const runServer = require('./runServer');
/**
* Starts the React Native Packager Server.
*/
function server(argv, config) {
return new Promise((resolve, reject) => {
_server(argv, config, resolve, reject);
});
}
function _server(argv, config, resolve, reject) {
const args = parseCommandLine([{
command: 'port',
default: 8081,
type: 'string',
}, {
command: 'root',
type: 'string',
description: 'add another root(s) to be used by the packager in this project',
}, {
command: 'projectRoots',
type: 'string',
description: 'override the root(s) to be used by the packager',
},{
command: 'assetRoots',
type: 'string',
description: 'specify the root directories of app assets'
}, {
command: 'skipflow',
description: 'Disable flow checks'
}, {
command: 'nonPersistent',
description: 'Disable file watcher'
}, {
command: 'transformer',
type: 'string',
default: require.resolve('../../packager/transformer'),
description: 'Specify a custom transformer to be used (absolute path)'
}, {
command: 'enable-internal-transforms',
type: 'boolean',
default: false
}, {
command: 'resetCache',
description: 'Removes cached files',
default: false,
}, {
command: 'reset-cache',
description: 'Removes cached files',
default: false,
}, {
command: 'verbose',
description: 'Enables logging',
default: false,
}]);
args.projectRoots = args.projectRoots
? argToArray(args.projectRoots)
: config.getProjectRoots();
if (args.root) {
const additionalRoots = argToArray(args.root);
additionalRoots.forEach(root => {
args.projectRoots.push(path.resolve(root));
});
}
args.assetRoots = args.assetRoots
? argToArray(args.assetRoots).map(dir =>
path.resolve(process.cwd(), dir)
)
: config.getAssetRoots();
checkNodeVersion();
console.log(formatBanner(
'Running packager on port ' + args.port + '.\n\n' +
'Keep this packager running while developing on any JS projects. ' +
'Feel free to close this tab and run your own packager instance if you ' +
'prefer.\n\n' +
'https://github.com/facebook/react-native', {
marginLeft: 1,
marginRight: 1,
paddingBottom: 1,
})
);
console.log(
'Looking for JS files in\n ',
chalk.dim(args.projectRoots.join('\n ')),
'\n'
);
process.on('uncaughtException', error => {
if (error.code === 'EADDRINUSE') {
console.log(
chalk.bgRed.bold(' ERROR '),
chalk.red('Packager can\'t listen on port', chalk.bold(args.port))
);
console.log('Most likely another process is already using this port');
console.log('Run the following command to find out which process:');
console.log('\n ', chalk.bold('lsof -n -i4TCP:' + args.port), '\n');
console.log('You can either shut down the other process:');
console.log('\n ', chalk.bold('kill -9 <PID>'), '\n');
console.log('or run packager on different port.');
} else {
console.log(chalk.bgRed.bold(' ERROR '), chalk.red(error.message));
const errorAttributes = JSON.stringify(error);
if (errorAttributes !== '{}') {
console.error(chalk.red(errorAttributes));
}
console.error(chalk.red(error.stack));
}
console.log('\nSee', chalk.underline('http://facebook.github.io/react-native/docs/troubleshooting.html'));
console.log('for common problems and solutions.');
process.exit(1);
});
// TODO: remove once we deprecate this arg
if (args.resetCache) {
console.log(
'Please start using `--reset-cache` instead. ' +
'We\'ll deprecate this argument soon.'
);
}
startServer(args, config);
}
function startServer(args, config) {
runServer(args, config, () =>
console.log('\nReact packager ready.\n')
);
}
function argToArray(arg) {
return Array.isArray(arg) ? arg : arg.split(',');
}
module.exports = server;