mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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:
committed by
Facebook Github Bot
parent
0ecc4047af
commit
a2c84d14ce
@@ -0,0 +1,376 @@
|
||||
/**
|
||||
* Copyright (c) 2016-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';
|
||||
|
||||
jest
|
||||
.disableAutomock()
|
||||
.useRealTimers()
|
||||
.mock('console');
|
||||
|
||||
const {Console} = require('console');
|
||||
const Graph = require('../Graph');
|
||||
const {fn} = require('../test-helpers');
|
||||
|
||||
const {any, objectContaining} = jasmine;
|
||||
const quiet = new Console();
|
||||
|
||||
describe('Graph:', () => {
|
||||
const anyEntry = ['arbitrary/entry/point'];
|
||||
const anyPlatform = 'arbitrary platform';
|
||||
const noOpts = undefined;
|
||||
|
||||
let graph, load, resolve;
|
||||
beforeEach(() => {
|
||||
load = fn();
|
||||
resolve = fn();
|
||||
resolve.stub.yields(null, 'arbitrary file');
|
||||
load.stub.yields(null, createFile('arbitrary file'), []);
|
||||
|
||||
graph = Graph.create(resolve, load);
|
||||
});
|
||||
|
||||
it('calls back an error when called without any entry point', done => {
|
||||
graph([], anyPlatform, {log: quiet}, (error) => {
|
||||
expect(error).toEqual(any(Error));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('resolves the entry point with the passed-in `resolve` function', done => {
|
||||
const entryPoint = '/arbitrary/path';
|
||||
graph([entryPoint], anyPlatform, noOpts, () => {
|
||||
expect(resolve).toBeCalledWith(
|
||||
entryPoint, '', any(String), any(Object), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('allows to specify multiple entry points', done => {
|
||||
const entryPoints = ['Arbitrary', '../entry.js'];
|
||||
graph(entryPoints, anyPlatform, noOpts, () => {
|
||||
expect(resolve).toBeCalledWith(
|
||||
entryPoints[0], '', any(String), any(Object), any(Function));
|
||||
expect(resolve).toBeCalledWith(
|
||||
entryPoints[1], '', any(String), any(Object), any(Function));
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('calls back with an error when called without `platform` option', done => {
|
||||
graph(anyEntry, undefined, {log: quiet}, error => {
|
||||
expect(error).toEqual(any(Error));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards a passed-in `platform` to `resolve`', done => {
|
||||
const platform = 'any';
|
||||
graph(anyEntry, platform, noOpts, () => {
|
||||
expect(resolve).toBeCalledWith(
|
||||
any(String), '', platform, any(Object), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards a passed-in `log` option to `resolve`', done => {
|
||||
const log = new Console();
|
||||
graph(anyEntry, anyPlatform, {log}, () => {
|
||||
expect(resolve).toBeCalledWith(
|
||||
any(String), '', any(String), objectContaining({log}), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with every error produced by `resolve`', done => {
|
||||
const error = Error();
|
||||
resolve.stub.yields(error);
|
||||
graph(anyEntry, anyPlatform, noOpts, e => {
|
||||
expect(e).toBe(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('only calls back once if two parallel invocations of `resolve` fail', done => {
|
||||
load.stub.yields(null, createFile('with two deps'), ['depA', 'depB']);
|
||||
resolve.stub
|
||||
.withArgs('depA').yieldsAsync(new Error())
|
||||
.withArgs('depB').yieldsAsync(new Error());
|
||||
|
||||
let calls = 0;
|
||||
function callback() {
|
||||
if (calls === 0) {
|
||||
process.nextTick(() => {
|
||||
expect(calls).toEqual(1);
|
||||
done();
|
||||
});
|
||||
}
|
||||
++calls;
|
||||
}
|
||||
|
||||
graph(['entryA', 'entryB'], anyPlatform, noOpts, callback);
|
||||
});
|
||||
|
||||
it('passes the files returned by `resolve` on to the `load` function', done => {
|
||||
const modules = new Map([
|
||||
['Arbitrary', '/absolute/path/to/Arbitrary.js'],
|
||||
['../entry.js', '/whereever/is/entry.js'],
|
||||
]);
|
||||
for (const [id, file] of modules) {
|
||||
resolve.stub.withArgs(id).yields(null, file);
|
||||
}
|
||||
const [file1, file2] = modules.values();
|
||||
|
||||
graph(modules.keys(), anyPlatform, noOpts, () => {
|
||||
expect(load).toBeCalledWith(file1, any(Object), any(Function));
|
||||
expect(load).toBeCalledWith(file2, any(Object), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('passes the `optimize` flag on to `load`', done => {
|
||||
graph(anyEntry, anyPlatform, {optimize: true}, () => {
|
||||
expect(load).toBeCalledWith(
|
||||
any(String), objectContaining({optimize: true}), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('uses `false` as the default for the `optimize` flag', done => {
|
||||
graph(anyEntry, anyPlatform, noOpts, () => {
|
||||
expect(load).toBeCalledWith(
|
||||
any(String), objectContaining({optimize: false}), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('forwards a passed-in `log` to `load`', done => {
|
||||
const log = new Console();
|
||||
graph(anyEntry, anyPlatform, {log}, () => {
|
||||
expect(load)
|
||||
.toBeCalledWith(any(String), objectContaining({log}), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with every error produced by `load`', done => {
|
||||
const error = Error();
|
||||
load.stub.yields(error);
|
||||
graph(anyEntry, anyPlatform, noOpts, e => {
|
||||
expect(e).toBe(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('resolves any dependencies provided by `load`', done => {
|
||||
const entryPath = '/path/to/entry.js';
|
||||
const id1 = 'required/id';
|
||||
const id2 = './relative/import';
|
||||
resolve.stub.withArgs('entry').yields(null, entryPath);
|
||||
load.stub.withArgs(entryPath)
|
||||
.yields(null, {path: entryPath}, [id1, id2]);
|
||||
|
||||
graph(['entry'], anyPlatform, noOpts, () => {
|
||||
expect(resolve).toBeCalledWith(
|
||||
id1, entryPath, any(String), any(Object), any(Function));
|
||||
expect(resolve).toBeCalledWith(
|
||||
id2, entryPath, any(String), any(Object), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('loads transitive dependencies', done => {
|
||||
const entryPath = '/path/to/entry.js';
|
||||
const id1 = 'required/id';
|
||||
const id2 = './relative/import';
|
||||
const path1 = '/path/to/dep/1';
|
||||
const path2 = '/path/to/dep/2';
|
||||
|
||||
resolve.stub
|
||||
.withArgs(id1).yields(null, path1)
|
||||
.withArgs(id2).yields(null, path2)
|
||||
.withArgs('entry').yields(null, entryPath);
|
||||
load.stub
|
||||
.withArgs(entryPath).yields(null, {path: entryPath}, [id1])
|
||||
.withArgs(path1).yields(null, {path: path1}, [id2]);
|
||||
|
||||
graph(['entry'], anyPlatform, noOpts, () => {
|
||||
expect(resolve).toBeCalledWith(id2, path1, any(String), any(Object), any(Function));
|
||||
expect(load).toBeCalledWith(path1, any(Object), any(Function));
|
||||
expect(load).toBeCalledWith(path2, any(Object), any(Function));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with an array of modules in depth-first traversal order, regardless of the order of resolution', done => {
|
||||
load.stub.reset();
|
||||
resolve.stub.reset();
|
||||
|
||||
const ids = [
|
||||
'a',
|
||||
'b',
|
||||
'c', 'd',
|
||||
'e',
|
||||
'f', 'g',
|
||||
'h',
|
||||
];
|
||||
ids.forEach(id => {
|
||||
const path = idToPath(id);
|
||||
resolve.stub.withArgs(id).yields(null, path);
|
||||
load.stub.withArgs(path).yields(null, createFile(id), []);
|
||||
});
|
||||
load.stub.withArgs(idToPath('a')).yields(null, createFile('a'), ['b', 'e', 'h']);
|
||||
load.stub.withArgs(idToPath('b')).yields(null, createFile('b'), ['c', 'd']);
|
||||
load.stub.withArgs(idToPath('e')).yields(null, createFile('e'), ['f', 'g']);
|
||||
|
||||
// load certain ids later
|
||||
['b', 'e', 'h'].forEach(id => resolve.stub.withArgs(id).resetBehavior());
|
||||
resolve.stub.withArgs('h').func = (a, b, c, d, callback) => {
|
||||
callback(null, idToPath('h'));
|
||||
['e', 'b'].forEach(
|
||||
id => resolve.stub.withArgs(id).yield(null, idToPath(id)));
|
||||
};
|
||||
|
||||
graph(['a'], anyPlatform, noOpts, (error, result) => {
|
||||
expect(error).toEqual(null);
|
||||
expect(result.modules).toEqual([
|
||||
createModule('a', ['b', 'e', 'h']),
|
||||
createModule('b', ['c', 'd']),
|
||||
createModule('c'),
|
||||
createModule('d'),
|
||||
createModule('e', ['f', 'g']),
|
||||
createModule('f'),
|
||||
createModule('g'),
|
||||
createModule('h'),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with the resolved modules of the entry points', done => {
|
||||
load.stub.reset();
|
||||
resolve.stub.reset();
|
||||
|
||||
load.stub.withArgs(idToPath('a')).yields(null, createFile('a'), ['b']);
|
||||
load.stub.withArgs(idToPath('b')).yields(null, createFile('b'), []);
|
||||
load.stub.withArgs(idToPath('c')).yields(null, createFile('c'), ['d']);
|
||||
load.stub.withArgs(idToPath('d')).yields(null, createFile('d'), []);
|
||||
|
||||
'abcd'.split('')
|
||||
.forEach(id => resolve.stub.withArgs(id).yields(null, idToPath(id)));
|
||||
|
||||
graph(['a', 'c'], anyPlatform, noOpts, (error, result) => {
|
||||
expect(result.entryModules).toEqual([
|
||||
createModule('a', ['b']),
|
||||
createModule('c', ['d']),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls back with the resolved modules of the entry points if one entry point is a dependency of another', done => {
|
||||
load.stub.reset();
|
||||
resolve.stub.reset();
|
||||
|
||||
load.stub.withArgs(idToPath('a')).yields(null, createFile('a'), ['b']);
|
||||
load.stub.withArgs(idToPath('b')).yields(null, createFile('b'), []);
|
||||
|
||||
'ab'.split('')
|
||||
.forEach(id => resolve.stub.withArgs(id).yields(null, idToPath(id)));
|
||||
|
||||
graph(['a', 'b'], anyPlatform, noOpts, (error, result) => {
|
||||
expect(result.entryModules).toEqual([
|
||||
createModule('a', ['b']),
|
||||
createModule('b', []),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not include dependencies more than once', done => {
|
||||
const ids = ['a', 'b', 'c', 'd'];
|
||||
ids.forEach(id => {
|
||||
const path = idToPath(id);
|
||||
resolve.stub.withArgs(id).yields(null, path);
|
||||
load.stub.withArgs(path).yields(null, createFile(id), []);
|
||||
});
|
||||
['a', 'd'].forEach(id =>
|
||||
load.stub
|
||||
.withArgs(idToPath(id)).yields(null, createFile(id), ['b', 'c']));
|
||||
|
||||
graph(['a', 'd', 'b'], anyPlatform, noOpts, (error, result) => {
|
||||
expect(error).toEqual(null);
|
||||
expect(result.modules).toEqual([
|
||||
createModule('a', ['b', 'c']),
|
||||
createModule('b'),
|
||||
createModule('c'),
|
||||
createModule('d', ['b', 'c']),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('handles dependency cycles', done => {
|
||||
resolve.stub
|
||||
.withArgs('a').yields(null, idToPath('a'))
|
||||
.withArgs('b').yields(null, idToPath('b'))
|
||||
.withArgs('c').yields(null, idToPath('c'));
|
||||
load.stub
|
||||
.withArgs(idToPath('a')).yields(null, createFile('a'), ['b'])
|
||||
.withArgs(idToPath('b')).yields(null, createFile('b'), ['c'])
|
||||
.withArgs(idToPath('c')).yields(null, createFile('c'), ['a']);
|
||||
|
||||
graph(['a'], anyPlatform, noOpts, (error, result) => {
|
||||
expect(result.modules).toEqual([
|
||||
createModule('a', ['b']),
|
||||
createModule('b', ['c']),
|
||||
createModule('c', ['a']),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can skip files', done => {
|
||||
['a', 'b', 'c', 'd', 'e'].forEach(
|
||||
id => resolve.stub.withArgs(id).yields(null, idToPath(id)));
|
||||
load.stub
|
||||
.withArgs(idToPath('a')).yields(null, createFile('a'), ['b', 'c', 'd'])
|
||||
.withArgs(idToPath('b')).yields(null, createFile('b'), ['e']);
|
||||
['c', 'd', 'e'].forEach(id =>
|
||||
load.stub.withArgs(idToPath(id)).yields(null, createFile(id), []));
|
||||
const skip = new Set([idToPath('b'), idToPath('c')]);
|
||||
|
||||
graph(['a'], anyPlatform, {skip}, (error, result) => {
|
||||
expect(result.modules).toEqual([
|
||||
createModule('a', ['b', 'c', 'd']),
|
||||
createModule('d', []),
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createDependency(id) {
|
||||
return {id, path: idToPath(id)};
|
||||
}
|
||||
|
||||
function createFile(id) {
|
||||
return {ast: {}, path: idToPath(id)};
|
||||
}
|
||||
|
||||
function createModule(id, dependencies = []): Module {
|
||||
return {
|
||||
file: createFile(id),
|
||||
dependencies: dependencies.map(createDependency)
|
||||
};
|
||||
}
|
||||
|
||||
function idToPath(id) {
|
||||
return '/path/to/' + id;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Copyright (c) 2017-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';
|
||||
|
||||
jest.disableAutomock();
|
||||
|
||||
const ModuleGraph = require('../ModuleGraph');
|
||||
const defaults = require('../../../defaults');
|
||||
|
||||
const FILE_TYPE = 'module';
|
||||
|
||||
describe('build setup', () => {
|
||||
const buildSetup = ModuleGraph.createBuildSetup(graph);
|
||||
const noOptions = {};
|
||||
const noEntryPoints = [];
|
||||
|
||||
it('adds a prelude containing start time and `__DEV__` to the build', done => {
|
||||
buildSetup(noEntryPoints, noOptions, (error, result) => {
|
||||
expect(error).toEqual(null);
|
||||
|
||||
const [prelude] = result.modules;
|
||||
expect(prelude).toEqual({
|
||||
dependencies: [],
|
||||
file: {
|
||||
code: 'var __DEV__=true,__BUNDLE_START_TIME__=Date.now();',
|
||||
path: '',
|
||||
type: 'script',
|
||||
},
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('sets `__DEV__` to false in the prelude if optimization is enabled', done => {
|
||||
buildSetup(noEntryPoints, {optimize: true}, (error, result) => {
|
||||
const [prelude] = result.modules;
|
||||
expect(prelude.file.code)
|
||||
.toEqual('var __DEV__=false,__BUNDLE_START_TIME__=Date.now();');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('places the module system implementation directly after the prelude', done => {
|
||||
buildSetup(noEntryPoints, noOptions, (error, result) => {
|
||||
const [, moduleSystem] = result.modules;
|
||||
expect(moduleSystem).toEqual({
|
||||
dependencies: [],
|
||||
file: {
|
||||
code: '',
|
||||
path: defaults.moduleSystem,
|
||||
type: FILE_TYPE,
|
||||
},
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('places polyfills after the module system', done => {
|
||||
buildSetup(noEntryPoints, noOptions, (error, result) => {
|
||||
const polyfills =
|
||||
Array.from(result.modules).slice(2, 2 + defaults.polyfills.length);
|
||||
expect(polyfills).toEqual(defaults.polyfills.map(moduleFromPath));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('places all modules from `defaults.runBeforeMainModule` after the polyfills', done => {
|
||||
buildSetup(noEntryPoints, noOptions, (error, result) => {
|
||||
const additionalModules =
|
||||
Array.from(result.modules).slice(-defaults.runBeforeMainModule.length);
|
||||
expect(additionalModules)
|
||||
.toEqual(defaults.runBeforeMainModule.map(moduleFromPath));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('places all entry points at the end', done => {
|
||||
const entryPoints = ['a', 'b', 'c'];
|
||||
buildSetup(entryPoints, noOptions, (error, result) => {
|
||||
expect(Array.from(result.modules).slice(-3))
|
||||
.toEqual(entryPoints.map(moduleFromPath));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('concatenates `runBeforeMainModule` and entry points as `entryModules`', done => {
|
||||
const entryPoints = ['a', 'b', 'c'];
|
||||
buildSetup(entryPoints, noOptions, (error, result) => {
|
||||
expect(Array.from(result.entryModules)).toEqual(
|
||||
defaults.runBeforeMainModule.concat(entryPoints).map(moduleFromPath));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function moduleFromPath(path) {
|
||||
return {
|
||||
dependencies: [],
|
||||
file: {
|
||||
code: '',
|
||||
path,
|
||||
type: FILE_TYPE,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function graph(entryPoints, platform, options, callback) {
|
||||
const modules = Array.from(entryPoints, moduleFromPath);
|
||||
callback(null, {
|
||||
entryModules: modules,
|
||||
modules,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user