Remove react-packager indirection.

Summary:
This moves the `src` directory one level up and removes the `react-packager` folder. Personally, I always disliked this indirection. I'm reorganizing some things in RNP, so this seems to make sense.

Not sure if I forgot to update any paths. Can anyone advice if there are more places that need change?

Reviewed By: jeanlauliac

Differential Revision: D4487867

fbshipit-source-id: d63f9c79d6238300df9632d2e6a4e6a4196d5ccb
This commit is contained in:
Christoph Pojer
2017-02-02 05:30:03 -08:00
committed by Facebook Github Bot
parent 0ecc4047af
commit a2c84d14ce
156 changed files with 121 additions and 81 deletions
@@ -0,0 +1,80 @@
/**
* 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.
*
* @flow
*/
'use strict';
const {dirname, join, parse} = require('path');
module.exports = class HasteFS {
directories: Set<string>;
directoryEntries: Map<string, Array<string>>;
files: Set<string>;
constructor(files: Array<string>) {
this.directories = buildDirectorySet(files);
this.directoryEntries = buildDirectoryEntries(files.map(parse));
this.files = new Set(files);
}
closest(path: string, fileName: string): ?string {
let {dir, root} = parse(path);
do {
const candidate = join(dir, fileName);
if (this.files.has(candidate)) {
return candidate;
}
dir = dirname(dir);
} while (dir !== '.' && dir !== root);
return null;
}
dirExists(path: string) {
return this.directories.has(path);
}
exists(path: string) {
return this.files.has(path);
}
getAllFiles() {
return Array.from(this.files.keys());
}
matches(directory: string, pattern: RegExp) {
const entries = this.directoryEntries.get(directory);
return entries ? entries.filter(pattern.test, pattern) : [];
}
};
function buildDirectorySet(files) {
const directories = new Set();
files.forEach(path => {
let {dir, root} = parse(path);
while (dir !== '.' && dir !== root && !directories.has(dir)) {
directories.add(dir);
dir = dirname(dir);
}
});
return directories;
}
function buildDirectoryEntries(files) {
const directoryEntries = new Map();
files.forEach(({base, dir}) => {
const entries = directoryEntries.get(dir);
if (entries) {
entries.push(base);
} else {
directoryEntries.set(dir, [base]);
}
});
return directoryEntries;
}
@@ -0,0 +1,51 @@
/**
* 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.
*
* @flow
*/
'use strict';
import type {TransformedFile} from '../types.flow';
import type {ModuleCache} from './node-haste.flow';
module.exports = class Module {
hasteID: Promise<?string>;
moduleCache: ModuleCache;
name: Promise<string>;
path: string;
type: 'Module';
constructor(
path: string,
moduleCache: ModuleCache,
info: Promise<TransformedFile>,
) {
this.hasteID = info.then(({hasteID}) => hasteID);
this.moduleCache = moduleCache;
this.name = this.hasteID.then(name => name || getName(path));
this.path = path;
this.type = 'Module';
}
getName() {
return this.name;
}
getPackage() {
return this.moduleCache.getPackageOf(this.path);
}
isHaste() {
return this.hasteID.then(Boolean);
}
};
function getName(path) {
return path.replace(/^.*[\/\\]node_modules[\///]/, '');
}
@@ -0,0 +1,65 @@
/**
* 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.
*
* @flow
*/
'use strict';
const Module = require('./Module');
const Package = require('./Package');
import type {PackageData, TransformedFile} from '../types.flow';
type GetFn<T> = (path: string) => Promise<T>;
type GetClosestPackageFn = (filePath: string) => ?string;
module.exports = class ModuleCache {
_getClosestPackage: GetClosestPackageFn;
getPackageData: GetFn<PackageData>;
getTransformedFile: GetFn<TransformedFile>;
modules: Map<string, Module>;
packages: Map<string, Package>;
constructor(getClosestPackage: GetClosestPackageFn, getTransformedFile: GetFn<TransformedFile>) {
this._getClosestPackage = getClosestPackage;
this.getTransformedFile = getTransformedFile;
this.getPackageData = path => getTransformedFile(path).then(
f => f.package || Promise.reject(new Error(`"${path}" does not exist`))
);
this.modules = new Map();
this.packages = new Map();
}
getAssetModule(path: string) {
return this.getModule(path);
}
getModule(path: string) {
let m = this.modules.get(path);
if (!m) {
m = new Module(path, this, this.getTransformedFile(path));
this.modules.set(path, m);
}
return m;
}
getPackage(path: string) {
let p = this.packages.get(path);
if (!p) {
p = new Package(path, this.getPackageData(path));
this.packages.set(path, p);
}
return p;
}
getPackageOf(filePath: string) {
const candidate = this._getClosestPackage(filePath);
return candidate != null ? this.getPackage(candidate) : null;
}
};
@@ -0,0 +1,138 @@
/**
* 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.
*
* @flow
*/
'use strict';
const path = require('path');
import type {PackageData} from '../types.flow';
module.exports = class Package {
data: Promise<PackageData>;
path: string;
root: string;
type: 'Package';
constructor(packagePath: string, data: Promise<PackageData>) {
this.data = data;
this.path = packagePath;
this.root = path.dirname(packagePath);
this.type = 'Package';
}
getMain() {
// Copied from node-haste/Package.js
return this.data.then(data => {
const replacements = getReplacements(data);
if (typeof replacements === 'string') {
return path.join(this.root, replacements);
}
let main = getMain(data);
if (replacements && typeof replacements === 'object') {
main = replacements[main] ||
replacements[main + '.js'] ||
replacements[main + '.json'] ||
replacements[main.replace(/(\.js|\.json)$/, '')] ||
main;
}
return path.join(this.root, main);
});
}
getName() {
return this.data.then(p => p.name);
}
isHaste() {
return this.data.then(p => !!p.name);
}
redirectRequire(name: string) {
// Copied from node-haste/Package.js
return this.data.then(data => {
const replacements = getReplacements(data);
if (!replacements || typeof replacements !== 'object') {
return name;
}
if (!path.isAbsolute(name)) {
const replacement = replacements[name];
// support exclude with "someDependency": false
return replacement === false
? false
: replacement || name;
}
let relPath = './' + path.relative(this.root, name);
if (path.sep !== '/') {
relPath = relPath.replace(new RegExp('\\' + path.sep, 'g'), '/');
}
let redirect = replacements[relPath];
// false is a valid value
if (redirect == null) {
redirect = replacements[relPath + '.js'];
if (redirect == null) {
redirect = replacements[relPath + '.json'];
}
}
// support exclude with "./someFile": false
if (redirect === false) {
return false;
}
if (redirect) {
return path.join(
this.root,
redirect
);
}
return name;
});
}
};
function getMain(pkg) {
return pkg.main || 'index';
}
// Copied from node-haste/Package.js
function getReplacements(pkg) {
let rn = pkg['react-native'];
let browser = pkg.browser;
if (rn == null) {
return browser;
}
if (browser == null) {
return rn;
}
const main = getMain(pkg);
if (typeof rn !== 'object') {
rn = { [main]: rn };
}
if (typeof browser !== 'object') {
browser = { [main]: browser };
}
// merge with "browser" as default,
// "react-native" as override
return { ...browser, ...rn };
}
@@ -0,0 +1,71 @@
/**
* 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.
*
* @flow
*/
'use strict';
'use strict';
import DependencyGraphHelpers from '../../node-haste/DependencyGraph/DependencyGraphHelpers';
type ModuleID = string;
export type Path = string;
type Platform = string;
type Platforms = Set<Platform>;
export type Extensions = Array<string>;
export type Module = {
path: Path,
type: 'Module',
getName(): Promise<ModuleID>,
getPackage(): ?Package,
isHaste(): Promise<boolean>,
};
export type Package = {
path: Path,
root: Path,
type: 'Package',
getMain(): Promise<Path>,
getName(): Promise<ModuleID>,
isHaste(): Promise<boolean>,
redirectRequire(id: ModuleID): Promise<Path | false>,
};
// when changing this to `type`, the code does not typecheck any more
export interface ModuleCache {
getAssetModule(path: Path): Module,
getModule(path: Path): Module,
getPackage(path: Path): Package,
getPackageOf(path: Path): ?Package,
}
export type FastFS = {
dirExists(path: Path): boolean,
closest(path: string, fileName: string): ?string,
fileExists(path: Path): boolean,
getAllFiles(): Array<Path>,
matches(directory: Path, pattern: RegExp): Array<Path>,
};
type HasteMapOptions = {|
extensions: Extensions,
files: Array<string>,
helpers: DependencyGraphHelpers,
moduleCache: ModuleCache,
platforms: Platforms,
preferNativePlatform: true,
|};
declare class HasteMap {
// node-haste/DependencyGraph/HasteMap.js
build(): Promise<Object>,
constructor(options: HasteMapOptions): void,
}
@@ -0,0 +1,101 @@
/**
* 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.
*
* @flow
*/
'use strict';
import type { // eslint-disable-line sort-requires
Extensions,
Path,
} from './node-haste.flow';
import type {
ResolveFn,
TransformedFile,
} from '../types.flow';
const DependencyGraphHelpers = require('../../node-haste/DependencyGraph/DependencyGraphHelpers');
const HasteFS = require('./HasteFS');
const HasteMap = require('../../node-haste/DependencyGraph/HasteMap');
const Module = require('./Module');
const ModuleCache = require('./ModuleCache');
const ResolutionRequest = require('../../node-haste/DependencyGraph/ResolutionRequest');
const defaults = require('../../../defaults');
type ResolveOptions = {|
assetExts: Extensions,
extraNodeModules: {[id: string]: string},
transformedFiles: {[path: Path]: TransformedFile},
|};
const platforms = new Set(defaults.platforms);
exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
const {
assetExts,
extraNodeModules,
transformedFiles,
} = options;
const files = Object.keys(transformedFiles);
const getTransformedFile =
path => Promise.resolve(
transformedFiles[path] || Promise.reject(new Error(`"${path} does not exist`))
);
const helpers = new DependencyGraphHelpers({
assetExts,
providesModuleNodeModules: defaults.providesModuleNodeModules,
});
const hasteFS = new HasteFS(files);
const moduleCache = new ModuleCache(
filePath => hasteFS.closest(filePath, 'package.json'),
getTransformedFile,
);
const hasteMap = new HasteMap({
extensions: ['js', 'json'],
files,
helpers,
moduleCache,
platforms,
preferNativePlatform: true,
});
const hasteMapBuilt = hasteMap.build();
const resolutionRequests = {};
return (id, source, platform, _, callback) => {
let resolutionRequest = resolutionRequests[platform];
if (!resolutionRequest) {
resolutionRequest = resolutionRequests[platform] = new ResolutionRequest({
dirExists: filePath => hasteFS.dirExists(filePath),
entryPath: '',
extraNodeModules,
/* $FlowFixMe: object is missing matchFiles method */
hasteFS,
hasteMap,
helpers,
moduleCache,
platform,
platforms,
preferNativePlatform: true,
});
}
const from = new Module(source, moduleCache, getTransformedFile(source));
hasteMapBuilt
.then(() => resolutionRequest.resolveDependency(from, id))
.then(
// nextTick to escape promise error handling
module => process.nextTick(callback, null, module.path),
error => process.nextTick(callback, error),
);
};
};
@@ -0,0 +1 @@
{"main":"node-haste.js"}