mirror of https://github.com/status-im/metro.git
Get rid of AssetServer
Reviewed By: mjesun Differential Revision: D6488612 fbshipit-source-id: e6144f0e143c0008d47342077b4a2c6c15765edc
This commit is contained in:
parent
5bff35f09e
commit
758ce871e6
|
@ -1,177 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2013-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.
|
||||
*
|
||||
* @emails oncall+javascript_foundation
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
jest.mock('fs');
|
||||
jest.mock('image-size');
|
||||
|
||||
const AssetServer = require('../');
|
||||
const fs = require('fs');
|
||||
|
||||
require('image-size').mockReturnValue({
|
||||
width: 300,
|
||||
height: 200,
|
||||
});
|
||||
|
||||
describe('AssetServer', () => {
|
||||
describe('assetServer.get', () => {
|
||||
it('should work for the simple case', () => {
|
||||
const server = new AssetServer({
|
||||
projectRoots: ['/root'],
|
||||
});
|
||||
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.png': 'b image',
|
||||
'b@2x.png': 'b2 image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
server.get('imgs/b.png'),
|
||||
server.get('imgs/b@1x.png'),
|
||||
]).then(resp => resp.forEach(data => expect(data).toBe('b image')));
|
||||
});
|
||||
|
||||
it('should work for the simple case with platform ext', () => {
|
||||
const server = new AssetServer({
|
||||
projectRoots: ['/root'],
|
||||
});
|
||||
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.ios.png': 'b ios image',
|
||||
'b.android.png': 'b android image',
|
||||
'c.png': 'c general image',
|
||||
'c.android.png': 'c android image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
server
|
||||
.get('imgs/b.png', 'ios')
|
||||
.then(data => expect(data).toBe('b ios image')),
|
||||
server
|
||||
.get('imgs/b.png', 'android')
|
||||
.then(data => expect(data).toBe('b android image')),
|
||||
server
|
||||
.get('imgs/c.png', 'android')
|
||||
.then(data => expect(data).toBe('c android image')),
|
||||
server
|
||||
.get('imgs/c.png', 'ios')
|
||||
.then(data => expect(data).toBe('c general image')),
|
||||
server
|
||||
.get('imgs/c.png')
|
||||
.then(data => expect(data).toBe('c general image')),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should work for the simple case with jpg', () => {
|
||||
const server = new AssetServer({
|
||||
projectRoots: ['/root'],
|
||||
});
|
||||
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.png': 'png image',
|
||||
'b.jpg': 'jpeg image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
server.get('imgs/b.jpg'),
|
||||
server.get('imgs/b.png'),
|
||||
]).then(data => expect(data).toEqual(['jpeg image', 'png image']));
|
||||
});
|
||||
|
||||
it('should pick the bigger one', () => {
|
||||
const server = new AssetServer({
|
||||
projectRoots: ['/root'],
|
||||
});
|
||||
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b@1x.png': 'b1 image',
|
||||
'b@2x.png': 'b2 image',
|
||||
'b@4x.png': 'b4 image',
|
||||
'b@4.5x.png': 'b4.5 image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return server
|
||||
.get('imgs/b@3x.png')
|
||||
.then(data => expect(data).toBe('b4 image'));
|
||||
});
|
||||
|
||||
it('should pick the bigger one with platform ext', () => {
|
||||
const server = new AssetServer({
|
||||
projectRoots: ['/root'],
|
||||
});
|
||||
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b@1x.png': 'b1 image',
|
||||
'b@2x.png': 'b2 image',
|
||||
'b@4x.png': 'b4 image',
|
||||
'b@4.5x.png': 'b4.5 image',
|
||||
'b@1x.ios.png': 'b1 ios image',
|
||||
'b@2x.ios.png': 'b2 ios image',
|
||||
'b@4x.ios.png': 'b4 ios image',
|
||||
'b@4.5x.ios.png': 'b4.5 ios image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
server.get('imgs/b@3x.png').then(data => expect(data).toBe('b4 image')),
|
||||
server
|
||||
.get('imgs/b@3x.png', 'ios')
|
||||
.then(data => expect(data).toBe('b4 ios image')),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should support multiple project roots', () => {
|
||||
const server = new AssetServer({
|
||||
projectRoots: ['/root', '/root2'],
|
||||
});
|
||||
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.png': 'b image',
|
||||
},
|
||||
},
|
||||
root2: {
|
||||
newImages: {
|
||||
imgs: {
|
||||
'b@1x.png': 'b1 image',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return server
|
||||
.get('newImages/imgs/b.png')
|
||||
.then(data => expect(data).toBe('b1 image'));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const AssetPaths = require('../node-haste/lib/AssetPaths');
|
||||
|
||||
const denodeify = require('denodeify');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const {findRoot, getAbsoluteAssetRecord} = require('./util');
|
||||
|
||||
export type AssetData = {|
|
||||
__packager_asset: boolean,
|
||||
fileSystemLocation: string,
|
||||
httpServerLocation: string,
|
||||
width: ?number,
|
||||
height: ?number,
|
||||
scales: Array<number>,
|
||||
files: Array<string>,
|
||||
hash: string,
|
||||
name: string,
|
||||
type: string,
|
||||
|};
|
||||
|
||||
const readFile = denodeify(fs.readFile);
|
||||
|
||||
class AssetServer {
|
||||
_roots: $ReadOnlyArray<string>;
|
||||
|
||||
constructor(options: {|+projectRoots: $ReadOnlyArray<string>|}) {
|
||||
this._roots = options.projectRoots;
|
||||
}
|
||||
|
||||
get(assetPath: string, platform: ?string = null): Promise<Buffer> {
|
||||
const assetData = AssetPaths.parse(
|
||||
assetPath,
|
||||
new Set(platform != null ? [platform] : []),
|
||||
);
|
||||
return this._getAssetRecord(assetPath, platform).then(record => {
|
||||
for (let i = 0; i < record.scales.length; i++) {
|
||||
if (record.scales[i] >= assetData.resolution) {
|
||||
return readFile(record.files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return readFile(record.files[record.files.length - 1]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a request for an image by path. That could contain a resolution
|
||||
* postfix, we need to find that image (or the closest one to it's resolution)
|
||||
* in one of the project roots:
|
||||
*
|
||||
* 1. We first parse the directory of the asset
|
||||
* 2. We check to find a matching directory in one of the project roots
|
||||
* 3. We then build a map of all assets and their scales in this directory
|
||||
* 4. Then try to pick platform-specific asset records
|
||||
* 5. Then pick the closest resolution (rounding up) to the requested one
|
||||
*/
|
||||
async _getAssetRecord(
|
||||
assetPath: string,
|
||||
platform: ?string = null,
|
||||
): Promise<{|
|
||||
files: Array<string>,
|
||||
scales: Array<number>,
|
||||
|}> {
|
||||
const dir = await findRoot(this._roots, path.dirname(assetPath), assetPath);
|
||||
|
||||
return await getAbsoluteAssetRecord(
|
||||
path.join(dir, path.basename(assetPath)),
|
||||
platform,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AssetServer;
|
|
@ -15,7 +15,7 @@
|
|||
jest.mock('fs');
|
||||
jest.mock('image-size');
|
||||
|
||||
const {getAssetData} = require('../util');
|
||||
const {getAssetData, getAsset} = require('../');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
|
||||
|
@ -24,6 +24,129 @@ require('image-size').mockReturnValue({
|
|||
height: 200,
|
||||
});
|
||||
|
||||
describe('getAsset', () => {
|
||||
it('should work for the simple case', () => {
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.png': 'b image',
|
||||
'b@2x.png': 'b2 image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
getAsset('imgs/b.png', ['/root']),
|
||||
getAsset('imgs/b@1x.png', ['/root']),
|
||||
]).then(resp => resp.forEach(data => expect(data).toBe('b image')));
|
||||
});
|
||||
|
||||
it('should work for the simple case with platform ext', async () => {
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.ios.png': 'b ios image',
|
||||
'b.android.png': 'b android image',
|
||||
'c.png': 'c general image',
|
||||
'c.android.png': 'c android image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
await Promise.all([
|
||||
getAsset('imgs/b.png', ['/root'], 'ios'),
|
||||
getAsset('imgs/b.png', ['/root'], 'android'),
|
||||
getAsset('imgs/c.png', ['/root'], 'android'),
|
||||
getAsset('imgs/c.png', ['/root'], 'ios'),
|
||||
getAsset('imgs/c.png', ['/root']),
|
||||
]),
|
||||
).toEqual([
|
||||
'b ios image',
|
||||
'b android image',
|
||||
'c android image',
|
||||
'c general image',
|
||||
'c general image',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should work for the simple case with jpg', () => {
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.png': 'png image',
|
||||
'b.jpg': 'jpeg image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
getAsset('imgs/b.jpg', ['/root']),
|
||||
getAsset('imgs/b.png', ['/root']),
|
||||
]).then(data => expect(data).toEqual(['jpeg image', 'png image']));
|
||||
});
|
||||
|
||||
it('should pick the bigger one', async () => {
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b@1x.png': 'b1 image',
|
||||
'b@2x.png': 'b2 image',
|
||||
'b@4x.png': 'b4 image',
|
||||
'b@4.5x.png': 'b4.5 image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(await getAsset('imgs/b@3x.png', ['/root'])).toBe('b4 image');
|
||||
});
|
||||
|
||||
it('should pick the bigger one with platform ext', async () => {
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b@1x.png': 'b1 image',
|
||||
'b@2x.png': 'b2 image',
|
||||
'b@4x.png': 'b4 image',
|
||||
'b@4.5x.png': 'b4.5 image',
|
||||
'b@1x.ios.png': 'b1 ios image',
|
||||
'b@2x.ios.png': 'b2 ios image',
|
||||
'b@4x.ios.png': 'b4 ios image',
|
||||
'b@4.5x.ios.png': 'b4.5 ios image',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
await Promise.all([
|
||||
getAsset('imgs/b@3x.png', ['/root']),
|
||||
getAsset('imgs/b@3x.png', ['/root'], 'ios'),
|
||||
]),
|
||||
).toEqual(['b4 image', 'b4 ios image']);
|
||||
});
|
||||
|
||||
it('should support multiple project roots', async () => {
|
||||
fs.__setMockFilesystem({
|
||||
root: {
|
||||
imgs: {
|
||||
'b.png': 'b image',
|
||||
},
|
||||
},
|
||||
root2: {
|
||||
newImages: {
|
||||
imgs: {
|
||||
'b@1x.png': 'b1 image',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(await getAsset('newImages/imgs/b.png', ['/root', '/root2'])).toBe(
|
||||
'b1 image',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAssetData', () => {
|
||||
it('should get assetData', () => {
|
||||
fs.__setMockFilesystem({
|
|
@ -24,9 +24,22 @@ const {isAssetTypeAnImage} = require('../Bundler/util');
|
|||
|
||||
const stat = denodeify(fs.stat);
|
||||
const readDir = denodeify(fs.readdir);
|
||||
const readFile = denodeify(fs.readFile);
|
||||
|
||||
import type {AssetPath} from '../node-haste/lib/AssetPaths';
|
||||
import type {AssetData} from './';
|
||||
|
||||
export type AssetData = {|
|
||||
__packager_asset: boolean,
|
||||
fileSystemLocation: string,
|
||||
httpServerLocation: string,
|
||||
width: ?number,
|
||||
height: ?number,
|
||||
scales: Array<number>,
|
||||
files: Array<string>,
|
||||
hash: string,
|
||||
name: string,
|
||||
type: string,
|
||||
|};
|
||||
|
||||
export type AssetInfo = {|
|
||||
files: Array<string>,
|
||||
|
@ -61,7 +74,7 @@ function buildAssetMap(
|
|||
|},
|
||||
> {
|
||||
const platforms = new Set(platform != null ? [platform] : []);
|
||||
const assets = files.map(getAssetDataFromName.bind(this, platforms));
|
||||
const assets = files.map(file => AssetPaths.tryParse(file, platforms));
|
||||
const map = new Map();
|
||||
assets.forEach(function(asset, i) {
|
||||
if (asset == null) {
|
||||
|
@ -93,13 +106,6 @@ function buildAssetMap(
|
|||
return map;
|
||||
}
|
||||
|
||||
function getAssetDataFromName(
|
||||
platforms: Set<string>,
|
||||
file: string,
|
||||
): ?AssetPath {
|
||||
return AssetPaths.tryParse(file, platforms);
|
||||
}
|
||||
|
||||
function getAssetKey(assetName, platform) {
|
||||
if (platform != null) {
|
||||
return `${assetName} : ${platform}`;
|
||||
|
@ -184,6 +190,26 @@ async function findRoot(
|
|||
);
|
||||
}
|
||||
|
||||
async function getAssetRecord(
|
||||
relativePath: string,
|
||||
projectRoots: $ReadOnlyArray<string>,
|
||||
platform: ?string = null,
|
||||
): Promise<{|
|
||||
files: Array<string>,
|
||||
scales: Array<number>,
|
||||
|}> {
|
||||
const dir = await findRoot(
|
||||
projectRoots,
|
||||
path.dirname(relativePath),
|
||||
relativePath,
|
||||
);
|
||||
|
||||
return await getAbsoluteAssetRecord(
|
||||
path.join(dir, path.basename(relativePath)),
|
||||
platform,
|
||||
);
|
||||
}
|
||||
|
||||
async function getAbsoluteAssetInfo(
|
||||
assetPath: string,
|
||||
platform: ?string = null,
|
||||
|
@ -235,6 +261,9 @@ async function getAssetData(
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the associated files (for different resolutions) of an asset.
|
||||
**/
|
||||
async function getAssetFiles(
|
||||
assetPath: string,
|
||||
platform: ?string = null,
|
||||
|
@ -244,9 +273,41 @@ async function getAssetFiles(
|
|||
return assetData.files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a buffer with the actual image given a request for an image by path.
|
||||
* The relativePath can contain a resolution postfix, in this case we need to
|
||||
* find that image (or the closest one to it's resolution) in one of the
|
||||
* project roots:
|
||||
*
|
||||
* 1. We first parse the directory of the asset
|
||||
* 2. We check to find a matching directory in one of the project roots
|
||||
* 3. We then build a map of all assets and their scales in this directory
|
||||
* 4. Then try to pick platform-specific asset records
|
||||
* 5. Then pick the closest resolution (rounding up) to the requested one
|
||||
*/
|
||||
async function getAsset(
|
||||
relativePath: string,
|
||||
projectRoots: $ReadOnlyArray<string>,
|
||||
platform: ?string = null,
|
||||
): Promise<Buffer> {
|
||||
const assetData = AssetPaths.parse(
|
||||
relativePath,
|
||||
new Set(platform != null ? [platform] : []),
|
||||
);
|
||||
|
||||
const record = await getAssetRecord(relativePath, projectRoots, platform);
|
||||
|
||||
for (let i = 0; i < record.scales.length; i++) {
|
||||
if (record.scales[i] >= assetData.resolution) {
|
||||
return readFile(record.files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return readFile(record.files[record.files.length - 1]);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findRoot,
|
||||
getAbsoluteAssetRecord,
|
||||
getAsset,
|
||||
getAssetData,
|
||||
getAssetFiles,
|
||||
};
|
|
@ -26,7 +26,6 @@ const {sep: pathSeparator} = require('path');
|
|||
|
||||
const VERSION = require('../../package.json').version;
|
||||
|
||||
import type AssetServer from '../AssetServer';
|
||||
import type {HasteImpl} from '../node-haste/Module';
|
||||
import type {MappingsMap, SourceMap} from '../lib/SourceMap';
|
||||
import type {Options as JSTransformerOptions} from '../JSTransformer/worker';
|
||||
|
@ -92,7 +91,6 @@ export type PostProcessBundleSourcemap = ({
|
|||
export type Options = {|
|
||||
+assetExts: Array<string>,
|
||||
+assetRegistryPath: string,
|
||||
+assetServer: AssetServer,
|
||||
+blacklistRE?: RegExp,
|
||||
+cacheVersion: string,
|
||||
+enableBabelRCLookup: boolean,
|
||||
|
@ -124,7 +122,6 @@ class Bundler {
|
|||
_transformer: Transformer;
|
||||
_resolverPromise: Promise<Resolver>;
|
||||
_projectRoots: $ReadOnlyArray<string>;
|
||||
_assetServer: AssetServer;
|
||||
_getTransformOptions: void | GetTransformOptions;
|
||||
|
||||
constructor(opts: Options) {
|
||||
|
@ -221,8 +218,6 @@ class Bundler {
|
|||
});
|
||||
|
||||
this._projectRoots = opts.projectRoots;
|
||||
this._assetServer = opts.assetServer;
|
||||
|
||||
this._getTransformOptions = opts.getTransformOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@ const DeltaPatcher = require('./DeltaPatcher');
|
|||
|
||||
const toLocalPath = require('../node-haste/lib/toLocalPath');
|
||||
|
||||
const {getAssetData} = require('../AssetServer/util');
|
||||
const {getAssetData} = require('../Assets');
|
||||
const {fromRawMappings} = require('../Bundler/source-map');
|
||||
const {createRamBundleGroups} = require('../Bundler/util');
|
||||
|
||||
import type {AssetData} from '../AssetServer';
|
||||
import type {AssetData} from '../Assets';
|
||||
import type {MappingsMap} from '../lib/SourceMap';
|
||||
import type {BundleOptions} from '../shared/types.flow';
|
||||
import type {ModuleTransportLike} from '../shared/types.flow';
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
'use strict';
|
||||
|
||||
jest.mock('../../node-haste/lib/toLocalPath');
|
||||
jest.mock('../../AssetServer/util');
|
||||
jest.mock('../../Assets');
|
||||
|
||||
const {getAssetData} = require('../../AssetServer/util');
|
||||
const {getAssetData} = require('../../Assets');
|
||||
const toLocalPath = require('../../node-haste/lib/toLocalPath');
|
||||
|
||||
const CURRENT_TIME = 1482363367000;
|
||||
|
|
|
@ -20,7 +20,7 @@ jest
|
|||
createWorker: jest.fn().mockReturnValue(jest.fn()),
|
||||
}))
|
||||
.mock('../../Bundler')
|
||||
.mock('../../AssetServer')
|
||||
.mock('../../Assets')
|
||||
.mock('../../node-haste/DependencyGraph')
|
||||
.mock('../../Logger')
|
||||
.mock('../../lib/GlobalTransformCache')
|
||||
|
@ -29,7 +29,7 @@ jest
|
|||
describe('processRequest', () => {
|
||||
let Bundler;
|
||||
let Server;
|
||||
let AssetServer;
|
||||
let getAsset;
|
||||
let symbolicate;
|
||||
let Serializers;
|
||||
let DeltaBundler;
|
||||
|
@ -40,7 +40,7 @@ describe('processRequest', () => {
|
|||
jest.resetModules();
|
||||
Bundler = require('../../Bundler');
|
||||
Server = require('../');
|
||||
AssetServer = require('../../AssetServer');
|
||||
getAsset = require('../../Assets').getAsset;
|
||||
symbolicate = require('../symbolicate');
|
||||
Serializers = require('../../DeltaBundler/Serializers');
|
||||
DeltaBundler = require('../../DeltaBundler');
|
||||
|
@ -354,9 +354,7 @@ describe('processRequest', () => {
|
|||
const req = scaffoldReq({url: '/assets/imgs/a.png'});
|
||||
const res = {end: jest.fn(), setHeader: jest.fn()};
|
||||
|
||||
AssetServer.prototype.get.mockImplementation(() =>
|
||||
Promise.resolve('i am image'),
|
||||
);
|
||||
getAsset.mockReturnValue(Promise.resolve('i am image'));
|
||||
|
||||
server.processRequest(req, res);
|
||||
res.end.mockImplementation(value => {
|
||||
|
@ -369,13 +367,11 @@ describe('processRequest', () => {
|
|||
const req = scaffoldReq({url: '/assets/imgs/a.png?platform=ios'});
|
||||
const res = {end: jest.fn(), setHeader: jest.fn()};
|
||||
|
||||
AssetServer.prototype.get.mockImplementation(() =>
|
||||
Promise.resolve('i am image'),
|
||||
);
|
||||
getAsset.mockReturnValue(Promise.resolve('i am image'));
|
||||
|
||||
server.processRequest(req, res);
|
||||
res.end.mockImplementation(value => {
|
||||
expect(AssetServer.prototype.get).toBeCalledWith('imgs/a.png', 'ios');
|
||||
expect(getAsset).toBeCalledWith('imgs/a.png', ['root'], 'ios');
|
||||
expect(value).toBe('i am image');
|
||||
done();
|
||||
});
|
||||
|
@ -389,13 +385,11 @@ describe('processRequest', () => {
|
|||
const res = {end: jest.fn(), writeHead: jest.fn(), setHeader: jest.fn()};
|
||||
const mockData = 'i am image';
|
||||
|
||||
AssetServer.prototype.get.mockImplementation(() =>
|
||||
Promise.resolve(mockData),
|
||||
);
|
||||
getAsset.mockReturnValue(Promise.resolve(mockData));
|
||||
|
||||
server.processRequest(req, res);
|
||||
res.end.mockImplementation(value => {
|
||||
expect(AssetServer.prototype.get).toBeCalledWith('imgs/a.png', 'ios');
|
||||
expect(getAsset).toBeCalledWith('imgs/a.png', ['root'], 'ios');
|
||||
expect(value).toBe(mockData.slice(0, 4));
|
||||
done();
|
||||
});
|
||||
|
@ -407,14 +401,13 @@ describe('processRequest', () => {
|
|||
});
|
||||
const res = {end: jest.fn(), setHeader: jest.fn()};
|
||||
|
||||
AssetServer.prototype.get.mockImplementation(() =>
|
||||
Promise.resolve('i am image'),
|
||||
);
|
||||
getAsset.mockReturnValue(Promise.resolve('i am image'));
|
||||
|
||||
server.processRequest(req, res);
|
||||
res.end.mockImplementation(value => {
|
||||
expect(AssetServer.prototype.get).toBeCalledWith(
|
||||
expect(getAsset).toBeCalledWith(
|
||||
'imgs/\u{4E3B}\u{9875}/logo.png',
|
||||
['root'],
|
||||
undefined,
|
||||
);
|
||||
expect(value).toBe('i am image');
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const AssetServer = require('../AssetServer');
|
||||
const Bundler = require('../Bundler');
|
||||
const DeltaBundler = require('../DeltaBundler');
|
||||
const MultipartResponse = require('./MultipartResponse');
|
||||
|
@ -28,6 +27,8 @@ const path = require('path');
|
|||
const symbolicate = require('./symbolicate');
|
||||
const url = require('url');
|
||||
|
||||
const {getAsset} = require('../Assets');
|
||||
|
||||
import type {CustomError} from '../lib/formatBundlingError';
|
||||
import type {HasteImpl} from '../node-haste/Module';
|
||||
import type {IncomingMessage, ServerResponse} from 'http';
|
||||
|
@ -41,7 +42,7 @@ import type {
|
|||
} from '../Bundler';
|
||||
import type {TransformCache} from '../lib/TransformCaching';
|
||||
import type {SourceMap, Symbolicate} from './symbolicate';
|
||||
import type {AssetData} from '../AssetServer';
|
||||
import type {AssetData} from '../Assets';
|
||||
import type {RamBundleInfo} from '../DeltaBundler/Serializers';
|
||||
import type {PostProcessModules} from '../DeltaBundler';
|
||||
const {
|
||||
|
@ -100,7 +101,6 @@ class Server {
|
|||
res: ServerResponse,
|
||||
}>;
|
||||
_fileChangeListeners: Array<(filePath: string) => mixed>;
|
||||
_assetServer: AssetServer;
|
||||
_bundler: Bundler;
|
||||
_debouncedFileChangeHandler: (filePath: string) => mixed;
|
||||
_reporter: Reporter;
|
||||
|
@ -162,12 +162,7 @@ class Server {
|
|||
this._fileChangeListeners = [];
|
||||
this._platforms = new Set(this._opts.platforms);
|
||||
|
||||
this._assetServer = new AssetServer({
|
||||
projectRoots: this._opts.projectRoots,
|
||||
});
|
||||
|
||||
const bundlerOpts = Object.create(this._opts);
|
||||
bundlerOpts.assetServer = this._assetServer;
|
||||
bundlerOpts.globalTransformCache = options.globalTransformCache;
|
||||
bundlerOpts.watch = this._opts.watch;
|
||||
bundlerOpts.reporter = reporter;
|
||||
|
@ -345,7 +340,7 @@ class Server {
|
|||
return data;
|
||||
}
|
||||
|
||||
_processSingleAssetRequest(req: IncomingMessage, res: ServerResponse) {
|
||||
async _processSingleAssetRequest(req: IncomingMessage, res: ServerResponse) {
|
||||
const urlObj = url.parse(decodeURI(req.url), true);
|
||||
/* $FlowFixMe: could be empty if the url is invalid */
|
||||
const assetPath: string = urlObj.pathname.match(/^\/assets\/(.+)$/);
|
||||
|
@ -357,25 +352,27 @@ class Server {
|
|||
}),
|
||||
);
|
||||
|
||||
/* $FlowFixMe: query may be empty for invalid URLs */
|
||||
this._assetServer.get(assetPath[1], urlObj.query.platform).then(
|
||||
data => {
|
||||
// Tell clients to cache this for 1 year.
|
||||
// This is safe as the asset url contains a hash of the asset.
|
||||
if (process.env.REACT_NATIVE_ENABLE_ASSET_CACHING === true) {
|
||||
res.setHeader('Cache-Control', 'max-age=31536000');
|
||||
}
|
||||
res.end(this._rangeRequestMiddleware(req, res, data, assetPath));
|
||||
process.nextTick(() => {
|
||||
log(createActionEndEntry(processingAssetRequestLogEntry));
|
||||
});
|
||||
},
|
||||
error => {
|
||||
console.error(error.stack);
|
||||
res.writeHead(404);
|
||||
res.end('Asset not found');
|
||||
},
|
||||
);
|
||||
try {
|
||||
const data = await getAsset(
|
||||
assetPath[1],
|
||||
this._opts.projectRoots,
|
||||
/* $FlowFixMe: query may be empty for invalid URLs */
|
||||
urlObj.query.platform,
|
||||
);
|
||||
// Tell clients to cache this for 1 year.
|
||||
// This is safe as the asset url contains a hash of the asset.
|
||||
if (process.env.REACT_NATIVE_ENABLE_ASSET_CACHING === true) {
|
||||
res.setHeader('Cache-Control', 'max-age=31536000');
|
||||
}
|
||||
res.end(this._rangeRequestMiddleware(req, res, data, assetPath));
|
||||
process.nextTick(() => {
|
||||
log(createActionEndEntry(processingAssetRequestLogEntry));
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error.stack);
|
||||
res.writeHead(404);
|
||||
res.end('Asset not found');
|
||||
}
|
||||
}
|
||||
|
||||
_optionsHash(options: {}) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const {getAssetData} = require('./AssetServer/util');
|
||||
const {getAssetData} = require('./Assets');
|
||||
const {generateAssetCodeFileAst} = require('./Bundler/util');
|
||||
|
||||
import type {TransformOptions} from './JSTransformer/worker';
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
'use strict';
|
||||
|
||||
jest.mock('../../DeltaBundler/Serializers');
|
||||
jest.mock('../../AssetServer/util');
|
||||
jest.mock('../../Assets');
|
||||
|
||||
const getOrderedDependencyPaths = require('../getOrderedDependencyPaths');
|
||||
const Serializers = require('../../DeltaBundler/Serializers');
|
||||
|
||||
const {getAssetFiles} = require('../../AssetServer/util');
|
||||
const {getAssetFiles} = require('../../Assets');
|
||||
|
||||
describe('getOrderedDependencyPaths', () => {
|
||||
const deltaBundler = {};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
const Serializers = require('../DeltaBundler/Serializers');
|
||||
|
||||
const {getAssetFiles} = require('../AssetServer/util');
|
||||
const {getAssetFiles} = require('../Assets');
|
||||
|
||||
import type {Options} from '../DeltaBundler/Serializers';
|
||||
import type DeltaBundler from '../DeltaBundler';
|
||||
|
|
Loading…
Reference in New Issue