Permalink
Browse files

Use new configuration in react-native public cli

Summary: Change the public react-native CLI to use the new configuration of Metro.

Reviewed By: rafeca

Differential Revision: D8801217

fbshipit-source-id: 112e4812b430ebee1ed41489f803b90c182ccdb4
  • Loading branch information...
CompuIves authored and facebook-github-bot committed Jul 25, 2018
1 parent f0daaf3 commit a32620dc3b7a0ebd53feeaf7794051705d80f49e
@@ -14,15 +14,12 @@ const log = require('../util/log').out('bundle');
/* $FlowFixMe(site=react_native_oss) */
const Server = require('metro/src/Server');
const {convert} = require('metro-config');
/* $FlowFixMe(site=react_native_oss) */
const outputBundle = require('metro/src/shared/output/bundle');
const {convert} = require('metro-config');
const path = require('path');
const saveAssets = require('./saveAssets');
const {ASSET_REGISTRY_PATH} = require('../core/Constants');
import type {RequestOptions, OutputOptions} from './types.flow';
import type {ConfigT} from 'metro-config/src/configTypes.flow';
@@ -48,6 +45,10 @@ async function buildBundle(
sourceMapUrl = path.basename(sourceMapUrl);
}
config.transformModulePath = args.transformer
? path.resolve(args.transformer)
: config.transformModulePath;
const requestOpts: RequestOptions = {
entryFile: args.entryFile,
sourceMapUrl,
@@ -56,13 +57,6 @@ async function buildBundle(
platform: args.platform,
};
const transformModulePath = args.transformer
? path.resolve(args.transformer)
: config.transformModulePath;
config.transformModulePath = transformModulePath;
config.transformer.assetRegistryPath = ASSET_REGISTRY_PATH;
const {serverOptions} = convert.convertNewToOld(config);
const server = new Server(serverOptions);
View
@@ -10,7 +10,7 @@
'use strict';
const config = require('./core');
const {configPromise} = require('./core');
const assertRequiredOptions = require('./util/assertRequiredOptions');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
@@ -137,7 +137,8 @@ const addCommand = (command: CommandT, cfg: RNConfig) => {
cmd.option('--config [string]', 'Path to the CLI configuration file');
};
function run() {
async function run() {
const config = await configPromise;
const setupEnvScript = /^win/.test(process.platform)
? 'setup_env.bat'
: 'setup_env.sh';
View
@@ -16,6 +16,7 @@ const findPlugins = require('./findPlugins');
const findAssets = require('./findAssets');
const ios = require('./ios');
const wrapCommands = require('./wrapCommands');
const {ASSET_REGISTRY_PATH} = require('./Constants');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
* found when Flow v0.54 was deployed. To see the error delete this comment and
@@ -28,18 +29,14 @@ const minimist = require('minimist');
const path = require('path');
import type {CommandT} from '../commands';
import type {ConfigT} from 'metro';
import type {ConfigT} from 'metro-config/src/configTypes.flow';
export type RNConfig = {
...ConfigT,
/**
* Returns an object with all platform configurations.
*/
getPlatformConfig(): Object,
/**
* Returns an array of project commands used by the CLI to load
*/
getProjectCommands(): Array<CommandT>,
/**
* Returns project config from the current working directory
*/
@@ -69,7 +66,7 @@ const pluginPlatforms = plugins.platforms.reduce((acc, pathToPlatforms) => {
);
}, {});
const defaultRNConfig = {
const defaultConfig = {
hasteImplModulePath: require.resolve('../../jest/hasteImpl'),
getPlatforms(): Array<string> {
@@ -79,20 +76,9 @@ const defaultRNConfig = {
getProvidesModuleNodeModules(): Array<string> {
return ['react-native', 'react-native-windows'];
},
};
getProjectCommands(): Array<CommandT> {
const commands = plugins.commands.map(pathToCommands => {
const name = pathToCommands.split(path.sep)[0];
return attachPackage(
require(path.join(appRoot, 'node_modules', pathToCommands)),
require(path.join(appRoot, 'node_modules', name, 'package.json')),
);
});
return flatten(commands);
},
const defaultRNConfig = {
getPlatformConfig(): Object {
return {
ios,
@@ -141,14 +127,33 @@ const defaultRNConfig = {
/**
* Loads the CLI configuration
*/
function getCliConfig(): RNConfig {
async function getCliConfig(): Promise<RNConfig> {
const cliArgs = minimist(process.argv.slice(2));
const config =
cliArgs.config != null
? Config.load(path.resolve(__dirname, cliArgs.config))
: Config.findOptional(__dirname);
const config = await Config.load(path.resolve(__dirname, cliArgs.config));

This comment has been minimized.

Show comment
Hide comment
@janicduplessis

janicduplessis Jul 27, 2018

Collaborator

This crashes when the config option is not passed to the CLI (this is the default for OSS).

I’m also having issues with my custom rn-cli.config.js, the file gets parsed but seems like none of the method gets called, did the format change? We will want to document this.

@janicduplessis

janicduplessis Jul 27, 2018

Collaborator

This crashes when the config option is not passed to the CLI (this is the default for OSS).

I’m also having issues with my custom rn-cli.config.js, the file gets parsed but seems like none of the method gets called, did the format change? We will want to document this.

This comment has been minimized.

Show comment
Hide comment
@janicduplessis
@janicduplessis

This comment has been minimized.

Show comment
Hide comment
@rafeca

rafeca Jul 29, 2018

Member

Thanks for the report! @CompuIves we should add a simple check here

@rafeca

rafeca Jul 29, 2018

Member

Thanks for the report! @CompuIves we should add a simple check here

config.transformer.assetRegistryPath = ASSET_REGISTRY_PATH;
config.resolver.hasteImplModulePath = defaultConfig.hasteImplModulePath;
config.resolver.platforms = defaultConfig.getPlatforms();
config.resolver.providesModuleNodeModules = defaultConfig.getProvidesModuleNodeModules();
return {...defaultRNConfig, ...config};
}
module.exports = getCliConfig();
/**
* Returns an array of project commands used by the CLI to load
*/
function getProjectCommands(): Array<CommandT> {
const commands = plugins.commands.map(pathToCommands => {
const name = pathToCommands.split(path.sep)[0];
return attachPackage(
require(path.join(appRoot, 'node_modules', pathToCommands)),
require(path.join(appRoot, 'node_modules', name, 'package.json')),
);
});
return flatten(commands);
}
module.exports.configPromise = getCliConfig();
module.exports.getProjectCommands = getProjectCommands;
@@ -16,8 +16,6 @@ const denodeify = require('denodeify');
const fs = require('fs');
const path = require('path');
const {ASSET_REGISTRY_PATH} = require('../core/Constants');
async function dependencies(argv, configPromise, args, packagerInstance) {
const rootModuleAbsolutePath = args.entryFile;
const config = await configPromise;
@@ -31,12 +29,9 @@ async function dependencies(argv, configPromise, args, packagerInstance) {
config.transformModulePath = args.transformer
? path.resolve(args.transformer)
: config.transformModulePath;
config.transformer.transformModulePath = ASSET_REGISTRY_PATH;
const {serverOptions: packageOpts} = convert.convertNewToOld(config);
const relativePath = path.relative(
packageOpts.projectRoot,
config.projectRoot,
rootModuleAbsolutePath,
);
@@ -53,18 +48,20 @@ async function dependencies(argv, configPromise, args, packagerInstance) {
? fs.createWriteStream(args.output)
: process.stdout;
const {serverOptions} = convert.convertNewToOld(config);
return Promise.resolve(
(packagerInstance
? packagerInstance.getOrderedDependencyPaths(options)
: Metro.getOrderedDependencyPaths(packageOpts, options)
: Metro.getOrderedDependencyPaths(serverOptions, options)
).then(deps => {
deps.forEach(modulePath => {
// Temporary hack to disable listing dependencies not under this directory.
// Long term, we need either
// (a) JS code to not depend on anything outside this directory, or
// (b) Come up with a way to declare this dependency in Buck.
const isInsideProjectRoots =
packageOpts.watchFolders.filter(root => modulePath.startsWith(root))
config.watchFolders.filter(root => modulePath.startsWith(root))
.length > 0;
if (isInsideProjectRoots) {
@@ -21,11 +21,8 @@ const morgan = require('morgan');
const path = require('path');
const webSocketProxy = require('./util/webSocketProxy');
const MiddlewareManager = require('./middleware/MiddlewareManager');
const {convertOldToNew} = require('metro-config/src/convertConfig');
const {ASSET_REGISTRY_PATH} = require('../core/Constants');
import type {ConfigT} from 'metro';
import type {ConfigT} from 'metro-config/src/configTypes.flow';
export type Args = {|
+assetExts: $ReadOnlyArray<string>,
@@ -57,23 +54,14 @@ async function runServer(args: Args, config: ConfigT) {
args.watchFolders.forEach(middlewareManager.serveStatic);
config.maxWorkers = args.maxWorkers;
config.server.port = args.port;
config.reporter = reporter;
config.server.enhanceMiddleware = middleware =>
middlewareManager.getConnectInstance().use(middleware);
const serverInstance = await Metro.runServer({
config: convertOldToNew({
config: {
...config,
assetRegistryPath: ASSET_REGISTRY_PATH,
enhanceMiddleware: middleware =>
middlewareManager.getConnectInstance().use(middleware),
transformModulePath: args.transformer
? path.resolve(args.transformer)
: config.getTransformModulePath(),
},
maxWorkers: args.maxWorkers,
port: args.port,
reporter,
}),
hmrEnabled: true,
config,
host: args.host,
secure: args.https,
secureCert: args.cert,
View
@@ -13,7 +13,7 @@
const runServer = require('./runServer');
import type {RNConfig} from '../core';
import type {ConfigT} from 'metro';
import type {ConfigT} from 'metro-config/src/configTypes.flow';
import type {Args as RunServerArgs} from './runServer';
/**
@@ -43,7 +43,7 @@ module.exports = {
command: '--projectRoot [string]',
description: 'Specify the main project root',
default: (config: ConfigT) => {
return config.getProjectRoot();
return config.projectRoot;
},
},
{
@@ -52,40 +52,39 @@ module.exports = {
'Specify any additional folders to be added to the watch list',
parse: (val: string) => val.split(','),
default: (config: ConfigT) => {
return config.getWatchFolders();
return config.watchFolders;
},
},
{
command: '--assetExts [list]',
description:
'Specify any additional asset extensions to be used by the packager',
parse: (val: string) => val.split(','),
default: (config: ConfigT) => config.getAssetExts(),
default: (config: ConfigT) => config.resolver.assetExts,
},
{
command: '--sourceExts [list]',
description:
'Specify any additional source extensions to be used by the packager',
parse: (val: string) => val.split(','),
default: (config: ConfigT) => config.getSourceExts(),
default: (config: ConfigT) => config.resolver.sourceExts,
},
{
command: '--platforms [list]',
description:
'Specify any additional platforms to be used by the packager',
parse: (val: string) => val.split(','),
default: (config: ConfigT) => config.getPlatforms(),
default: (config: ConfigT) => config.resolver.platforms,
},
{
command: '--providesModuleNodeModules [list]',
description:
'Specify any npm packages that import dependencies with providesModule',
parse: (val: string) => val.split(','),
default: (config: RNConfig) => {
if (typeof config.getProvidesModuleNodeModules === 'function') {
return config.getProvidesModuleNodeModules();
}
return null;
return config.resolver
? config.resolver.providesModuleNodeModules
: undefined;
},
},
{
Oops, something went wrong.

0 comments on commit a32620d

Please sign in to comment.