From 6a4e113736615ea6783b0acd7908f02ffa04ffb5 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Wed, 3 May 2017 06:38:40 -0700 Subject: [PATCH] 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 --- local-cli/bundle/buildBundle.js | 2 +- local-cli/cliEntry.js | 4 +- local-cli/commands.js | 6 +- local-cli/core/default.config.js | 19 +------ local-cli/core/index.js | 62 ++------------------- local-cli/link/link.js | 4 +- local-cli/util/Config.js | 95 +++++++++++++++++++++++++++++--- 7 files changed, 100 insertions(+), 92 deletions(-) diff --git a/local-cli/bundle/buildBundle.js b/local-cli/bundle/buildBundle.js index 4501f4dca..3aa739ab3 100644 --- a/local-cli/bundle/buildBundle.js +++ b/local-cli/bundle/buildBundle.js @@ -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( diff --git a/local-cli/cliEntry.js b/local-cli/cliEntry.js index 1e74b9233..641254199 100644 --- a/local-cli/cliEntry.js +++ b/local-cli/cliEntry.js @@ -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 diff --git a/local-cli/commands.js b/local-cli/commands.js index 9b3f40586..e4aa44467 100644 --- a/local-cli/commands.js +++ b/local-cli/commands.js @@ -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, config: ConfigT, args: Object) => ?Promise, + func: (argv: Array, config: RNConfig, args: Object) => ?Promise, options?: Array<{ command: string, description?: string, parse?: (val: string) => any, - default?: (config: ConfigT) => any | any, + default?: (config: RNConfig) => any | any, }>, examples?: Array<{ desc: string, diff --git a/local-cli/core/default.config.js b/local-cli/core/default.config.js index d01bde262..ecfbed982 100644 --- a/local-cli/core/default.config.js +++ b/local-cli/core/default.config.js @@ -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) { diff --git a/local-cli/core/index.js b/local-cli/core/index.js index 8f362146b..5973fbf53 100644 --- a/local-cli/core/index.js +++ b/local-cli/core/index.js @@ -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, - /** - * 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, - /** - * Specify any additional node modules that should be processed for - * providesModule declarations. - */ - getProvidesModuleNodeModules?: () => Array, - /** - * 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, - getAssetExts(): Array, +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 /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) diff --git a/local-cli/link/link.js b/local-cli/link/link.js index f597c9079..2f990f6c2 100644 --- a/local-cli/link/link.js +++ b/local-cli/link/link.js @@ -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, config: ConfigT) { +function link(args: Array, config: RNConfig) { var project; try { project = config.getProjectConfig(); diff --git a/local-cli/util/Config.js b/local-cli/util/Config.js index 81a11c145..746533166 100644 --- a/local-cli/util/Config.js +++ b/local-cli/util/Config.js @@ -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, + + /** + * 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, + + getProjectRoots(): Array, + + /** + * Specify any additional node modules that should be processed for + * providesModule declarations. + */ + getProvidesModuleNodeModules?: () => Array, + /** + * 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}; }, };