kill `shouldThrowOnUnresolvedErrors` option

Summary: Removes the `shouldThrowOnUnresolvedErrors` option, as now it is only ever `() => true`

Reviewed By: davidaurelio

Differential Revision: D4237711

fbshipit-source-id: 9460f0f0c50dc0d08d17cb7bdeb995825f7051f3
This commit is contained in:
Christoph Pojer 2016-11-30 10:10:34 -08:00 committed by Facebook Github Bot
parent 1b4bdf0bac
commit 17ccb9b8c4
5 changed files with 172 additions and 222 deletions

View File

@ -37,7 +37,6 @@ type ResolveOptions = {|
|}; |};
const platforms = new Set(defaults.platforms); const platforms = new Set(defaults.platforms);
const returnTrue = () => true;
exports.createResolveFn = function(options: ResolveOptions): ResolveFn { exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
const { const {
@ -87,7 +86,6 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
platform, platform,
platforms, platforms,
preferNativePlatform: true, preferNativePlatform: true,
shouldThrowOnUnresolvedErrors: returnTrue,
}); });
} }

View File

@ -98,7 +98,6 @@ class Resolver {
preferNativePlatform: true, preferNativePlatform: true,
watch: opts.watch, watch: opts.watch,
cache: opts.cache, cache: opts.cache,
shouldThrowOnUnresolvedErrors: () => true,
transformCode: opts.transformCode, transformCode: opts.transformCode,
transformCacheKey: opts.transformCacheKey, transformCacheKey: opts.transformCacheKey,
extraNodeModules: opts.extraNodeModules, extraNodeModules: opts.extraNodeModules,

View File

@ -27,8 +27,6 @@ import type Module from '../Module';
import type ModuleCache from '../ModuleCache'; import type ModuleCache from '../ModuleCache';
import type ResolutionResponse from './ResolutionResponse'; import type ResolutionResponse from './ResolutionResponse';
const emptyModule = require.resolve('./assets/empty-module.js');
type DirExistsFn = (filePath: string) => boolean; type DirExistsFn = (filePath: string) => boolean;
type Options = { type Options = {
@ -43,7 +41,6 @@ type Options = {
platform: string, platform: string,
platforms: Set<string>, platforms: Set<string>,
preferNativePlatform: boolean, preferNativePlatform: boolean,
shouldThrowOnUnresolvedErrors: () => boolean,
}; };
class ResolutionRequest { class ResolutionRequest {
@ -58,7 +55,7 @@ class ResolutionRequest {
_platform: string; _platform: string;
_platforms: Set<string>; _platforms: Set<string>;
_preferNativePlatform: boolean; _preferNativePlatform: boolean;
_shouldThrowOnUnresolvedErrors: () => boolean; static emptyModule: string;
constructor({ constructor({
dirExists, dirExists,
@ -71,7 +68,6 @@ class ResolutionRequest {
platform, platform,
platforms, platforms,
preferNativePlatform, preferNativePlatform,
shouldThrowOnUnresolvedErrors,
}: Options) { }: Options) {
this._dirExists = dirExists; this._dirExists = dirExists;
this._entryPath = entryPath; this._entryPath = entryPath;
@ -83,7 +79,6 @@ class ResolutionRequest {
this._platform = platform; this._platform = platform;
this._platforms = platforms; this._platforms = platforms;
this._preferNativePlatform = preferNativePlatform; this._preferNativePlatform = preferNativePlatform;
this._shouldThrowOnUnresolvedErrors = shouldThrowOnUnresolvedErrors;
this._resetResolutionCache(); this._resetResolutionCache();
} }
@ -109,38 +104,16 @@ class ResolutionRequest {
return result; return result;
}; };
const forgive = (error) => {
if (
error.type !== 'UnableToResolveError' ||
this._shouldThrowOnUnresolvedErrors(this._entryPath, this._platform)
) {
throw error;
}
debug(
'Unable to resolve module %s from %s',
toModuleName,
fromModule.path
);
return null;
};
if (!this._helpers.isNodeModulesDir(fromModule.path) if (!this._helpers.isNodeModulesDir(fromModule.path)
&& !(isRelativeImport(toModuleName) || isAbsolutePath(toModuleName))) { && !(isRelativeImport(toModuleName) || isAbsolutePath(toModuleName))) {
return this._tryResolve( return this._tryResolve(
() => this._resolveHasteDependency(fromModule, toModuleName), () => this._resolveHasteDependency(fromModule, toModuleName),
() => this._resolveNodeDependency(fromModule, toModuleName) () => this._resolveNodeDependency(fromModule, toModuleName)
).then( ).then(cacheResult);
cacheResult,
forgive,
);
} }
return this._resolveNodeDependency(fromModule, toModuleName) return this._resolveNodeDependency(fromModule, toModuleName)
.then( .then(cacheResult);
cacheResult,
forgive,
);
} }
getOrderedDependencies({ getOrderedDependencies({
@ -311,7 +284,11 @@ class ResolutionRequest {
return this._redirectRequire(fromModule, potentialModulePath).then( return this._redirectRequire(fromModule, potentialModulePath).then(
realModuleName => { realModuleName => {
if (realModuleName === false) { if (realModuleName === false) {
return this._loadAsFile(emptyModule, fromModule, toModuleName); return this._loadAsFile(
ResolutionRequest.emptyModule,
fromModule,
toModuleName,
);
} }
return this._tryResolve( return this._tryResolve(
@ -330,7 +307,11 @@ class ResolutionRequest {
realModuleName => { realModuleName => {
// exclude // exclude
if (realModuleName === false) { if (realModuleName === false) {
return this._loadAsFile(emptyModule, fromModule, toModuleName); return this._loadAsFile(
ResolutionRequest.emptyModule,
fromModule,
toModuleName,
);
} }
if (isRelativeImport(realModuleName) || isAbsolutePath(realModuleName)) { if (isRelativeImport(realModuleName) || isAbsolutePath(realModuleName)) {
@ -526,4 +507,6 @@ function isRelativeImport(filePath) {
return /^[.][.]?(?:[/]|$)/.test(filePath); return /^[.][.]?(?:[/]|$)/.test(filePath);
} }
ResolutionRequest.emptyModule = require.resolve('./assets/empty-module.js');
module.exports = ResolutionRequest; module.exports = ResolutionRequest;

View File

@ -26,6 +26,11 @@ jest.mock('../../JSTransformer/worker/extract-dependencies', () => extractDepend
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
const path = require('path'); const path = require('path');
const mockStat = {
isDirectory: () => false,
};
beforeEach(() => { beforeEach(() => {
jest.resetModules(); jest.resetModules();
@ -34,6 +39,7 @@ beforeEach(() => {
describe('DependencyGraph', function() { describe('DependencyGraph', function() {
let Module; let Module;
let ResolutionRequest;
let defaults; let defaults;
function getOrderedDependenciesAsJSON(dgraph, entryPath, platform, recursive = true) { function getOrderedDependenciesAsJSON(dgraph, entryPath, platform, recursive = true) {
@ -58,6 +64,7 @@ describe('DependencyGraph', function() {
jest.resetModules(); jest.resetModules();
Module = require('../Module'); Module = require('../Module');
ResolutionRequest = require('../DependencyGraph/ResolutionRequest');
const Cache = jest.genMockFn().mockImplementation(function() { const Cache = jest.genMockFn().mockImplementation(function() {
this._maps = Object.create(null); this._maps = Object.create(null);
@ -107,7 +114,6 @@ describe('DependencyGraph', function() {
'react-native', 'react-native',
], ],
platforms: ['ios', 'android'], platforms: ['ios', 'android'],
shouldThrowOnUnresolvedErrors: () => false,
useWatchman: false, useWatchman: false,
maxWorkers: 1, maxWorkers: 1,
resetCache: true, resetCache: true,
@ -1151,7 +1157,7 @@ describe('DependencyGraph', function() {
}); });
}); });
it('should be forgiving with missing requires', function() { it('throws when a module is missing', function() {
var root = '/root'; var root = '/root';
setMockFileSystem({ setMockFileSystem({
'root': { 'root': {
@ -1168,21 +1174,11 @@ describe('DependencyGraph', function() {
...defaults, ...defaults,
roots: [root], roots: [root],
}); });
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').catch(
expect(deps) error => {
.toEqual([ expect(error.type).toEqual('UnableToResolveError');
{ }
id: 'index', );
path: '/root/index.js',
dependencies: ['lolomg'],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
resolveDependency: undefined,
},
]);
});
}); });
it('should work with packages with subdirs', function() { it('should work with packages with subdirs', function() {
@ -1908,9 +1904,11 @@ describe('DependencyGraph', function() {
}); });
it('should support browser exclude of a package ("' + fieldName + '")', function() { it('should support browser exclude of a package ("' + fieldName + '")', function() {
ResolutionRequest.emptyModule = '/root/emptyModule.js';
var root = '/root'; var root = '/root';
setMockFileSystem({ setMockFileSystem({
'root': { 'root': {
'emptyModule.js': '',
'index.js': [ 'index.js': [
'/**', '/**',
' * @providesModule index', ' * @providesModule index',
@ -1958,14 +1956,26 @@ describe('DependencyGraph', function() {
isPolyfill: false, isPolyfill: false,
resolution: undefined, resolution: undefined,
}, },
{
dependencies: [],
id: '/root/emptyModule.js',
isAsset: false,
isJSON: false,
isPolyfill: false,
path: '/root/emptyModule.js',
resolution: undefined,
},
]); ]);
}); });
}); });
it('should support browser exclude of a file ("' + fieldName + '")', function() { it('should support browser exclude of a file ("' + fieldName + '")', function() {
ResolutionRequest.emptyModule = '/root/emptyModule.js';
var root = '/root'; var root = '/root';
setMockFileSystem({ setMockFileSystem({
'root': { 'root': {
'emptyModule.js': '',
'index.js': [ 'index.js': [
'/**', '/**',
' * @providesModule index', ' * @providesModule index',
@ -1992,7 +2002,8 @@ describe('DependencyGraph', function() {
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) {
expect(deps) expect(deps)
.toEqual([ .toEqual([
{ id: 'index', {
id: 'index',
path: '/root/index.js', path: '/root/index.js',
dependencies: ['aPackage'], dependencies: ['aPackage'],
isAsset: false, isAsset: false,
@ -2000,7 +2011,8 @@ describe('DependencyGraph', function() {
isPolyfill: false, isPolyfill: false,
resolution: undefined, resolution: undefined,
}, },
{ id: 'aPackage/index.js', {
id: 'aPackage/index.js',
path: '/root/aPackage/index.js', path: '/root/aPackage/index.js',
dependencies: ['./booga'], dependencies: ['./booga'],
isAsset: false, isAsset: false,
@ -2008,6 +2020,15 @@ describe('DependencyGraph', function() {
isPolyfill: false, isPolyfill: false,
resolution: undefined, resolution: undefined,
}, },
{
dependencies: [],
id: '/root/emptyModule.js',
isAsset: false,
isJSON: false,
isPolyfill: false,
path: '/root/emptyModule.js',
resolution: undefined,
},
]); ]);
}); });
}); });
@ -2105,8 +2126,8 @@ describe('DependencyGraph', function() {
const root = '/root'; const root = '/root';
setMockFileSystem({ setMockFileSystem({
[root.slice(1)]: { [root.slice(1)]: {
'index.js': 'require("/root/arbitrary.js");', 'index.js': 'require("/root/apple.js");',
'arbitrary.js': '', 'apple.js': '',
}, },
}); });
@ -2120,15 +2141,15 @@ describe('DependencyGraph', function() {
{ {
id: '/root/index.js', id: '/root/index.js',
path: '/root/index.js', path: '/root/index.js',
dependencies: ['/root/arbitrary.js'], dependencies: ['/root/apple.js'],
isAsset: false, isAsset: false,
isJSON: false, isJSON: false,
isPolyfill: false, isPolyfill: false,
resolution: undefined, resolution: undefined,
}, },
{ {
id: '/root/arbitrary.js', id: '/root/apple.js',
path: '/root/arbitrary.js', path: '/root/apple.js',
dependencies: [], dependencies: [],
isAsset: false, isAsset: false,
isJSON: false, isJSON: false,
@ -2508,8 +2529,8 @@ describe('DependencyGraph', function() {
const root = 'C:\\root'; const root = 'C:\\root';
setMockFileSystem({ setMockFileSystem({
'root': { 'root': {
'index.js': 'require("C:\\\\root\\\\arbitrary.js");', 'index.js': 'require("C:\\\\root\\\\apple.js");',
'arbitrary.js': '', 'apple.js': '',
}, },
}); });
@ -2523,15 +2544,15 @@ describe('DependencyGraph', function() {
{ {
id: 'C:\\root\\index.js', id: 'C:\\root\\index.js',
path: 'C:\\root\\index.js', path: 'C:\\root\\index.js',
dependencies: ['C:\\root\\arbitrary.js'], dependencies: ['C:\\root\\apple.js'],
isAsset: false, isAsset: false,
isJSON: false, isJSON: false,
isPolyfill: false, isPolyfill: false,
resolution: undefined, resolution: undefined,
}, },
{ {
id: 'C:\\root\\arbitrary.js', id: 'C:\\root\\apple.js',
path: 'C:\\root\\arbitrary.js', path: 'C:\\root\\apple.js',
dependencies: [], dependencies: [],
isAsset: false, isAsset: false,
isJSON: false, isJSON: false,
@ -2960,7 +2981,7 @@ describe('DependencyGraph', function() {
it('should selectively ignore providesModule in node_modules', function() { it('should selectively ignore providesModule in node_modules', function() {
var root = '/root'; var root = '/root';
var otherRoot = '/anotherRoot'; var otherRoot = '/anotherRoot';
setMockFileSystem({ const filesystem = {
'root': { 'root': {
'index.js': [ 'index.js': [
'/**', '/**',
@ -3051,77 +3072,86 @@ describe('DependencyGraph', function() {
'wazup()', 'wazup()',
].join('\n'), ].join('\n'),
}, },
}); };
setMockFileSystem(filesystem);
var dgraph = new DependencyGraph({ var dgraph = new DependencyGraph({
...defaults, ...defaults,
roots: [root, otherRoot], roots: [root, otherRoot],
}); });
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').catch(
expect(deps) error => {
.toEqual([ expect(error.type).toEqual('UnableToResolveError');
{ }
id: 'index', ).then(() => {
path: '/root/index.js', filesystem.root['index.js'] = filesystem.root['index.js']
dependencies: [ .replace('require("dontWork")', '')
'shouldWork', .replace('require("wontWork")', '');
'dontWork', dgraph.processFileChange('change', root + '/index.js', mockStat);
'wontWork', return getOrderedDependenciesAsJSON(dgraph, '/root/index.js')
'ember', .then(deps => {
'internalVendoredPackage', expect(deps).toEqual([
'anotherIndex', {
], id: 'index',
isAsset: false, path: '/root/index.js',
isJSON: false, dependencies: [
isPolyfill: false, 'shouldWork',
resolution: undefined, 'ember',
}, 'internalVendoredPackage',
{ 'anotherIndex',
id: 'shouldWork', ],
path: '/root/node_modules/react-haste/main.js', isAsset: false,
dependencies: ['submodule'], isJSON: false,
isAsset: false, isPolyfill: false,
isJSON: false, resolution: undefined,
isPolyfill: false, },
resolution: undefined, {
}, id: 'shouldWork',
{ path: '/root/node_modules/react-haste/main.js',
id: 'submodule/main.js', dependencies: ['submodule'],
path: '/root/node_modules/react-haste/node_modules/submodule/main.js', isAsset: false,
dependencies: [], isJSON: false,
isAsset: false, isPolyfill: false,
isJSON: false, resolution: undefined,
isPolyfill: false, },
resolution: undefined, {
}, id: 'submodule/main.js',
{ path: '/root/node_modules/react-haste/node_modules/submodule/main.js',
id: 'ember/main.js', dependencies: [],
path: '/root/node_modules/ember/main.js', isAsset: false,
dependencies: [], isJSON: false,
isAsset: false, isPolyfill: false,
isJSON: false, resolution: undefined,
isPolyfill: false, },
resolution: undefined, {
}, id: 'ember/main.js',
{ path: '/root/node_modules/ember/main.js',
id: 'internalVendoredPackage', dependencies: [],
path: '/root/vendored_modules/a-vendored-package/main.js', isAsset: false,
dependencies: [], isJSON: false,
isAsset: false, isPolyfill: false,
isJSON: false, resolution: undefined,
isPolyfill: false, },
resolution: undefined, {
}, id: 'internalVendoredPackage',
{ path: '/root/vendored_modules/a-vendored-package/main.js',
id: 'anotherIndex', dependencies: [],
path: '/anotherRoot/index.js', isAsset: false,
dependencies: [], isJSON: false,
isAsset: false, isPolyfill: false,
isJSON: false, resolution: undefined,
isPolyfill: false, },
resolution: undefined, {
}, id: 'anotherIndex',
]); path: '/anotherRoot/index.js',
dependencies: [],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
]);
});
}); });
}); });
@ -3180,50 +3210,6 @@ describe('DependencyGraph', function() {
}); });
}); });
it('should ignore modules it cant find (assumes own require system)', function() {
// For example SourceMap.js implements it's own require system.
var root = '/root';
setMockFileSystem({
'root': {
'index.js': [
'/**',
' * @providesModule index',
' */',
'require("foo/lol");',
].join('\n'),
'node_modules': {
'foo': {
'package.json': JSON.stringify({
name: 'foo',
main: 'main.js',
}),
'main.js': '/* foo module */',
},
},
},
});
var dgraph = new DependencyGraph({
...defaults,
roots: [root],
});
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) {
expect(deps)
.toEqual([
{
id: 'index',
path: '/root/index.js',
dependencies: ['foo/lol'],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
]);
});
});
it('should work with node packages with a .js in the name', function() { it('should work with node packages with a .js in the name', function() {
var root = '/root'; var root = '/root';
setMockFileSystem({ setMockFileSystem({
@ -4522,10 +4508,6 @@ describe('DependencyGraph', function() {
}); });
describe('file watch updating', function() { describe('file watch updating', function() {
var mockStat = {
isDirectory: () => false,
};
const realPlatform = process.platform; const realPlatform = process.platform;
let DependencyGraph; let DependencyGraph;
@ -4549,7 +4531,7 @@ describe('DependencyGraph', function() {
'require("aPackage")', 'require("aPackage")',
'require("foo")', 'require("foo")',
].join('\n'), ].join('\n'),
'foo': [ 'foo.js': [
'/**', '/**',
' * @providesModule foo', ' * @providesModule foo',
' */', ' */',
@ -4694,29 +4676,10 @@ describe('DependencyGraph', function() {
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function() { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function() {
delete filesystem.root.foo; delete filesystem.root.foo;
dgraph.processFileChange('delete', root + '/foo.js'); dgraph.processFileChange('delete', root + '/foo.js');
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js')
expect(deps) .catch(error => {
.toEqual([ expect(error.type).toEqual('UnableToResolveError');
{ });
id: 'index',
path: '/root/index.js',
dependencies: ['aPackage', 'foo'],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
{
id: 'aPackage/main.js',
path: '/root/aPackage/main.js',
dependencies: [],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
]);
});
}); });
}); });
@ -4831,20 +4794,11 @@ describe('DependencyGraph', function() {
assetExts: ['png'], assetExts: ['png'],
}); });
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').catch(
expect(deps) error => {
.toEqual([ expect(error.type).toEqual('UnableToResolveError');
{ id: 'index', }
path: '/root/index.js', ).then(() => {
dependencies: ['./foo.png'],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
resolveDependency: undefined,
},
]);
filesystem.root['foo.png'] = ''; filesystem.root['foo.png'] = '';
dgraph._hasteFS._files[root + '/foo.png'] = ['', 8648460, 1, []]; dgraph._hasteFS._files[root + '/foo.png'] = ['', 8648460, 1, []];
dgraph.processFileChange('add', root + '/foo.png', mockStat); dgraph.processFileChange('add', root + '/foo.png', mockStat);
@ -4964,25 +4918,41 @@ describe('DependencyGraph', function() {
roots: [root], roots: [root],
}); });
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function() { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function() {
filesystem.root['index.js'] = [
'/**',
' * @providesModule index',
' */',
'require("bPackage")',
].join('\n');
filesystem.root.aPackage['package.json'] = JSON.stringify({ filesystem.root.aPackage['package.json'] = JSON.stringify({
name: 'bPackage', name: 'bPackage',
main: 'main.js', main: 'main.js',
}); });
dgraph.processFileChange('change', root + '/index.js', mockStat);
dgraph.processFileChange('change', root + '/aPackage/package.json', mockStat); dgraph.processFileChange('change', root + '/aPackage/package.json', mockStat);
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) {
expect(deps) expect(deps)
.toEqual([ .toEqual([
{ {
dependencies: ['bPackage'],
id: 'index', id: 'index',
path: '/root/index.js',
dependencies: ['aPackage'],
isAsset: false, isAsset: false,
isJSON: false, isJSON: false,
isPolyfill: false, isPolyfill: false,
path: '/root/index.js',
resolution: undefined, resolution: undefined,
resolveDependency: undefined, resolveDependency: undefined,
}, },
{
dependencies: [],
id: 'aPackage/main.js',
isAsset: false,
isJSON: false,
isPolyfill: false,
path: '/root/aPackage/main.js',
resolution: undefined,
},
]); ]);
}); });
}); });
@ -5319,12 +5289,14 @@ describe('DependencyGraph', function() {
}); });
it('allows setting dependencies for asset modules', () => { it('allows setting dependencies for asset modules', () => {
const assetDependencies = ['arbitrary', 'dependencies']; const assetDependencies = ['/root/apple.png', '/root/banana.png'];
setMockFileSystem({ setMockFileSystem({
'root': { 'root': {
'index.js': 'require("./a.png")', 'index.js': 'require("./a.png")',
'a.png' : '', 'a.png' : '',
'apple.png': '',
'banana.png': '',
}, },
}); });

View File

@ -79,7 +79,6 @@ class DependencyGraph {
_loading: Promise<mixed>; _loading: Promise<mixed>;
constructor({ constructor({
// additional arguments for jest-haste-map
assetDependencies, assetDependencies,
assetExts, assetExts,
cache, cache,
@ -297,7 +296,6 @@ class DependencyGraph {
platform, platform,
platforms: this._opts.platforms, platforms: this._opts.platforms,
preferNativePlatform: this._opts.preferNativePlatform, preferNativePlatform: this._opts.preferNativePlatform,
shouldThrowOnUnresolvedErrors: this._opts.shouldThrowOnUnresolvedErrors,
}); });
const response = new ResolutionResponse({transformOptions}); const response = new ResolutionResponse({transformOptions});