Stronger config types

Summary:
Splits `ConfigT` into `ConfigT` (core + packager configuration) and `RNConfig` (RN CLI configuration).
Also guarantees that all values on `ConfigT` have a default when loading user configuration.

Reviewed By: jeanlauliac

Differential Revision: D4985965

fbshipit-source-id: bf036e22d6809e49746a9c3aa240ec403a085342
This commit is contained in:
David Aurelio 2017-05-03 06:38:40 -07:00 committed by Facebook Github Bot
parent d2505e7615
commit 6a4e113736
7 changed files with 100 additions and 92 deletions

View File

@ -23,7 +23,7 @@ const defaultPlatforms = require('../../packager/defaults').platforms;
const defaultProvidesModuleNodeModules = require('../../packager/defaults').providesModuleNodeModules;
import type {RequestOptions, OutputOptions} from './types.flow';
import type {ConfigT} from '../core';
import type {ConfigT} from '../util/Config';
function saveBundle(output, bundle, args) {
return Promise.resolve(

View File

@ -22,7 +22,7 @@ const path = require('path');
const pkg = require('../package.json');
import type {CommandT} from './commands';
import type {ConfigT} from './core';
import type {RNConfig} from './core';
commander.version(pkg.version);
@ -91,7 +91,7 @@ function printUnknownCommand(cmdName) {
].join('\n'));
}
const addCommand = (command: CommandT, cfg: ConfigT) => {
const addCommand = (command: CommandT, cfg: RNConfig) => {
const options = command.options || [];
const cmd = commander

View File

@ -12,18 +12,18 @@
const { getProjectCommands } = require('./core');
import type { ConfigT } from './core';
import type { RNConfig } from './core';
export type CommandT = {
name: string,
description?: string,
usage?: string,
func: (argv: Array<string>, config: ConfigT, args: Object) => ?Promise<void>,
func: (argv: Array<string>, config: RNConfig, args: Object) => ?Promise<void>,
options?: Array<{
command: string,
description?: string,
parse?: (val: string) => any,
default?: (config: ConfigT) => any | any,
default?: (config: RNConfig) => any | any,
}>,
examples?: Array<{
desc: string,

View File

@ -12,7 +12,6 @@
const path = require('path');
const flatten = require('lodash').flatten;
const blacklist = require('../../packager/blacklist');
const android = require('./android');
const findAssets = require('./findAssets');
const ios = require('./ios');
@ -21,8 +20,6 @@ const wrapCommands = require('./wrapCommands');
const findPlugins = require('./findPlugins');
const findSymlinksPaths = require('../util/findSymlinksPaths');
import type {ConfigT} from './index';
function getProjectPath() {
if (__dirname.match(/node_modules[\/\\]react-native[\/\\]local-cli[\/\\]core$/)) {
// Packager is running from node_modules.
@ -58,7 +55,7 @@ const resolveSymlink = (roots) =>
* `rn-cli.config.js` on the root of your project with the functions you need
* to tweak.
*/
const config: ConfigT = {
const config = {
getProjectCommands() {
const appRoot = process.cwd();
const plugins = findPlugins([appRoot])
@ -86,7 +83,7 @@ const config: ConfigT = {
assets: findAssets(folder, rnpm.assets),
});
},
getDependencyConfig(packageName) {
getDependencyConfig(packageName: string) {
const folder = path.join(process.cwd(), 'node_modules', packageName);
const rnpm = getRNPMConfig(
path.join(process.cwd(), 'node_modules', packageName)
@ -101,18 +98,6 @@ const config: ConfigT = {
params: rnpm.params || [],
});
},
getAssetExts() {
return [];
},
getPlatforms() {
return [];
},
getBlacklistRE() {
return blacklist();
},
getTransformModulePath() {
return require.resolve('../../packager/transformer');
},
getProjectRoots() {
const root = process.env.REACT_NATIVE_APP_ROOT;
if (root) {

View File

@ -15,46 +15,11 @@ const Config = require('../util/Config');
const defaultConfig = require('./default.config');
const minimist = require('minimist');
import type {GetTransformOptions, PostProcessModules, PostMinifyProcess} from '../../packager/src/Bundler';
import type {HasteImpl} from '../../packager/src/node-haste/Module';
import type {CommandT} from '../commands';
import type {ConfigT} from '../util/Config';
/**
* Configuration file of the CLI.
*/
export type ConfigT = {
extraNodeModules?: { [id: string]: string },
/**
* Specify any additional asset extentions to be used by the packager.
* For example, if you want to include a .ttf file, you would return ['ttf']
* from here and use `require('./fonts/example.ttf')` inside your app.
*/
getAssetExts?: () => Array<string>,
/**
* Specify any additional platforms to be used by the packager.
* For example, if you want to add a "custom" platform, and use modules
* ending in .custom.js, you would return ['custom'] here.
*/
getPlatforms: () => Array<string>,
/**
* Specify any additional node modules that should be processed for
* providesModule declarations.
*/
getProvidesModuleNodeModules?: () => Array<string>,
/**
* Returns the path to a custom transformer. This can also be overridden
* with the --transformer commandline argument.
*/
getTransformModulePath?: () => string,
getTransformOptions?: GetTransformOptions,
transformVariants?: () => {[name: string]: Object},
/**
* Returns a regular expression for modules that should be ignored by the
* packager on a given platform.
*/
getBlacklistRE(): RegExp,
getProjectRoots(): Array<string>,
getAssetExts(): Array<string>,
export type RNConfig = {
...ConfigT,
/**
* Returns an array of project commands used by the CLI to load
*/
@ -67,31 +32,12 @@ export type ConfigT = {
* Returns dependency config from <node_modules>/packageName
*/
getDependencyConfig(pkgName: string): Object,
/**
* An optional function that can modify the module array before the bundle is
* finalized.
*/
postProcessModules?: PostProcessModules,
/**
* An optional function that can modify the code and source map of bundle
* after the minifaction took place.
*/
postMinifyProcess?: PostMinifyProcess,
/**
* A module that exports:
* - a `getHasteName(filePath)` method that returns `hasteName` for module at
* `filePath`, or undefined if `filePath` is not a haste module.
*/
hasteImpl?: HasteImpl,
};
/**
* Loads the CLI configuration
*/
function getCliConfig(): ConfigT {
function getCliConfig(): RNConfig {
const cliArgs = minimist(process.argv.slice(2));
const config = cliArgs.config != null
? Config.loadFile(cliArgs.config, __dirname)

View File

@ -31,7 +31,7 @@ const pollParams = require('./pollParams');
const commandStub = require('./commandStub');
const promisify = require('./promisify');
import type {ConfigT} from '../core';
import type {RNConfig} from '../core';
log.heading = 'rnpm-link';
@ -135,7 +135,7 @@ const linkAssets = (project, assets) => {
* only that package is processed.
* @param config CLI config, see local-cli/core/index.js
*/
function link(args: Array<string>, config: ConfigT) {
function link(args: Array<string>, config: RNConfig) {
var project;
try {
project = config.getProjectConfig();

View File

@ -10,15 +10,92 @@
*/
'use strict';
const blacklist = require('../../packager/blacklist');
const fs = require('fs');
const invariant = require('fbjs/lib/invariant');
const path = require('path');
const {providesModuleNodeModules} = require('../../packager/defaults');
const RN_CLI_CONFIG = 'rn-cli.config.js';
// TODO: @bestander & @grabbou - get rid when internal tests are fixed
import type {ConfigT} from '../core';
export type {ConfigT};
import type {GetTransformOptions, PostMinifyProcess, PostProcessModules} from '../../packager/src/Bundler';
import type {HasteImpl} from '../../packager/src/node-haste/Module';
/**
* Configuration file of the CLI.
*/
export type ConfigT = {
extraNodeModules: {[id: string]: string},
/**
* Specify any additional asset extentions to be used by the packager.
* For example, if you want to include a .ttf file, you would return ['ttf']
* from here and use `require('./fonts/example.ttf')` inside your app.
*/
getAssetExts: () => Array<string>,
/**
* Returns a regular expression for modules that should be ignored by the
* packager on a given platform.
*/
getBlacklistRE(): RegExp,
/**
* Specify any additional platforms to be used by the packager.
* For example, if you want to add a "custom" platform, and use modules
* ending in .custom.js, you would return ['custom'] here.
*/
getPlatforms: () => Array<string>,
getProjectRoots(): Array<string>,
/**
* Specify any additional node modules that should be processed for
* providesModule declarations.
*/
getProvidesModuleNodeModules?: () => Array<string>,
/**
* Returns the path to a custom transformer. This can also be overridden
* with the --transformer commandline argument.
*/
getTransformModulePath: () => string,
getTransformOptions: GetTransformOptions,
/**
* An optional function that can modify the code and source map of bundle
* after the minifaction took place.
*/
postMinifyProcess: PostMinifyProcess,
/**
* An optional function that can modify the module array before the bundle is
* finalized.
*/
postProcessModules: PostProcessModules,
/**
* A module that exports:
* - a `getHasteName(filePath)` method that returns `hasteName` for module at
* `filePath`, or undefined if `filePath` is not a haste module.
*/
hasteImpl?: HasteImpl,
transformVariants: () => {[name: string]: Object},
};
const defaultConfig: ConfigT = {
extraNodeModules: Object.create(null),
getAssetExts: () => [],
getBlacklistRE: () => blacklist(),
getPlatforms: () => [],
getProjectRoots: () => [process.cwd()],
getProvidesModuleNodeModules: () => providesModuleNodeModules.slice(),
getTransformModulePath: () => path.resolve(__dirname, '../../packager/transformer'),
getTransformOptions: async () => ({}),
postMinifyProcess: x => x,
postProcessModules: modules => modules,
transformVariants: () => ({default: {}}),
};
/**
* Module capable of getting the configuration out of a given file.
@ -29,7 +106,7 @@ export type {ConfigT};
* hierarchy, an error will be thrown.
*/
const Config = {
find(startDir: string) {
find(startDir: string): ConfigT {
const configPath = findConfigPath(startDir);
invariant(
configPath,
@ -38,23 +115,23 @@ const Config = {
return this.loadFile(configPath, startDir);
},
findOptional(startDir: string) {
findOptional(startDir: string): ConfigT {
const configPath = findConfigPath(startDir);
return configPath
? this.loadFile(configPath, startDir)
: {cwd: startDir};
: {...defaultConfig, cwd: startDir};
},
loadFile(
pathToConfig: string,
cwd: string,
) {
const config = path.isAbsolute(pathToConfig) ?
): ConfigT {
const config: {} = path.isAbsolute(pathToConfig) ?
// $FlowFixMe nope
require(pathToConfig) :
// $FlowFixMe nope
require(path.join(cwd, pathToConfig));
return {...config, cwd};
return {...defaultConfig, ...config, cwd};
},
};