Skip to content

Commit

Permalink
Avoid loading files that we know are binary ahead of time
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel Jimenez Esun committed Feb 19, 2018
1 parent 430aebe commit b003b56
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 7 deletions.
24 changes: 24 additions & 0 deletions packages/jest-haste-map/src/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,12 @@ describe('HasteMap', () => {
'/vegetables/melon.js': ['/**', ' * @providesModule Melon', ' */'].join(
'\n',
),
'/video/video.mp4': Buffer.from([0xFA, 0xCE, 0xB0, 0x0C]).toString(),
});
mockClocks = object({
'/fruits': 'c:fake-clock:1',
'/vegetables': 'c:fake-clock:2',
'/video': 'c:fake-clock:3',
});

mockChangedFiles = null;
Expand Down Expand Up @@ -305,6 +307,28 @@ describe('HasteMap', () => {
});
});

it('does not crawl native files even if requested to do so', async () => {
mockFs['/video/i-require-a-video.js'] = [
'/**',
' * @providesModule IRequireAVideo',
' */',
'module.exports = require("./video.mp4");',
].join('\n');

const hasteMap = new HasteMap(
Object.assign({}, defaultConfig, {
extensions: [...defaultConfig.extensions],
roots: [...defaultConfig.roots, '/video'],
}),
);

const {__hasteMapForTest: data} = await hasteMap.build();

expect(data.map.IRequireAVideo).toBeDefined();
expect(data.files['/video/video.mp4']).toBeDefined();
expect(fs.readFileSync).not.toBeCalledWith('/video/video.mp4', 'utf8');
});

it('retains all files if `retainAllFiles` is specified', () => {
mockFs['/fruits/node_modules/fbjs/index.js'] = [
'/**',
Expand Down
65 changes: 65 additions & 0 deletions packages/jest-haste-map/src/blacklist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

// This list is compiled after the MDN list of the most common MIME types (see
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/
// Complete_list_of_MIME_types).
//
// Only MIME types starting with "image/", "video/", "audio/" and "font/" are
// reflected in the list. Adding "application/" is too risky since some text
// file formats (like ".js" and ".json") have an "application/" MIME type.
//
// Feel free to add any extensions that cannot contain any "@providesModule"
// annotation.

const extensions: Set<string> = new Set([
// JSONs are never haste modules, except for "package.json", which is handled.
'.json',

// Image extensions.
'.bmp',
'.gif',
'.ico',
'.jpeg',
'.jpg',
'.png',
'.svg',
'.tiff',
'.tif',
'.webp',

// Video extensions.
'.avi',
'.mp4',
'.mpeg',
'.mpg',
'.ogv',
'.webm',
'.3gp',
'.3g2',

// Audio extensions.
'.aac',
'.midi',
'.mid',
'.mp3',
'.oga',
'.wav',
'.3gp',
'.3g2',

// Font extensions.
'.eot',
'.otf',
'.ttf',
'.woff',
'.woff2',
]);

export default extensions;
21 changes: 14 additions & 7 deletions packages/jest-haste-map/src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import type {HasteImpl, WorkerMessage, WorkerMetadata} from './types';
import path from 'path';
import * as docblock from 'jest-docblock';
import fs from 'graceful-fs';
import blacklist from './blacklist';
import H from './constants';
import extractRequires from './lib/extract_requires';

const JSON_EXTENSION = '.json';
const PACKAGE_JSON = path.sep + 'package' + JSON_EXTENSION;
const PACKAGE_JSON = path.sep + 'package.json';

let hasteImpl: ?HasteImpl = null;
let hasteImplModulePath: ?string = null;
Expand All @@ -35,26 +35,33 @@ export async function worker(data: WorkerMessage): Promise<WorkerMetadata> {
}

const filePath = data.filePath;
const content = fs.readFileSync(filePath, 'utf8');
let module;
let id: ?string;
let dependencies;

if (filePath.endsWith(PACKAGE_JSON)) {
const fileData = JSON.parse(content);
const fileData = JSON.parse(fs.readFileSync(filePath, 'utf8'));

if (fileData.name) {
id = fileData.name;
module = [filePath, H.PACKAGE];
}
} else if (!filePath.endsWith(JSON_EXTENSION)) {

return {dependencies, id, module};
}

if (!blacklist.has(filePath.substr(filePath.lastIndexOf('.')))) {
const content = fs.readFileSync(filePath, 'utf8');

if (hasteImpl) {
id = hasteImpl.getHasteName(filePath);
} else {
const doc = docblock.parse(docblock.extract(content));
const idPragmas = [].concat(doc.providesModule || doc.provides);
id = idPragmas[0];
id = [].concat(doc.providesModule || doc.provides)[0];
}

dependencies = extractRequires(content);

if (id) {
module = [filePath, H.MODULE];
}
Expand Down

0 comments on commit b003b56

Please sign in to comment.