mirror of https://github.com/status-im/metro.git
Prepare metro to build production bundles using the Delta Bundler
Reviewed By: davidaurelio Differential Revision: D6186012 fbshipit-source-id: a9c2757211345881e3feba331bdbe66cdc0f6b97
This commit is contained in:
parent
775867445a
commit
ff7ec2e6bf
|
@ -248,6 +248,10 @@ class Bundler {
|
|||
this._getTransformOptions = opts.getTransformOptions;
|
||||
}
|
||||
|
||||
getAssetServer(): AssetServer {
|
||||
return this._assetServer;
|
||||
}
|
||||
|
||||
end() {
|
||||
this._transformer.kill();
|
||||
/* $FlowFixMe(>=0.54.0 site=react_native_fb) This comment suppresses an
|
||||
|
|
|
@ -16,8 +16,10 @@ const DeltaPatcher = require('./DeltaPatcher');
|
|||
|
||||
const {fromRawMappings} = require('../Bundler/source-map');
|
||||
|
||||
import type {AssetData} from '../AssetServer';
|
||||
import type {BundleOptions} from '../Server';
|
||||
import type {MappingsMap} from '../lib/SourceMap';
|
||||
import type {ModuleTransportLike} from '../shared/types.flow';
|
||||
import type DeltaBundler, {Options as BuildOptions} from './';
|
||||
import type {DeltaEntry, DeltaTransformResponse} from './DeltaTransformer';
|
||||
|
||||
|
@ -25,6 +27,14 @@ export type Options = BundleOptions & {
|
|||
deltaBundleId: ?string,
|
||||
};
|
||||
|
||||
export type RamModule = ModuleTransportLike;
|
||||
|
||||
export type RamBundleInfo = {
|
||||
startupModules: $ReadOnlyArray<ModuleTransportLike>,
|
||||
lazyModules: $ReadOnlyArray<ModuleTransportLike>,
|
||||
groups: Map<number, Set<number>>,
|
||||
};
|
||||
|
||||
/**
|
||||
* This module contains many serializers for the Delta Bundler. Each serializer
|
||||
* returns a string representation for any specific type of bundle, which can
|
||||
|
@ -115,7 +125,7 @@ async function fullBundle(
|
|||
async function getAllModules(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: Options,
|
||||
): Promise<Array<DeltaEntry>> {
|
||||
): Promise<$ReadOnlyArray<DeltaEntry>> {
|
||||
const {id, delta} = await _build(deltaBundler, {
|
||||
...options,
|
||||
wrapModules: true,
|
||||
|
@ -126,6 +136,59 @@ async function getAllModules(
|
|||
.getAllModules();
|
||||
}
|
||||
|
||||
async function getRamBundleInfo(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: Options,
|
||||
): Promise<RamBundleInfo> {
|
||||
let modules = await getAllModules(deltaBundler, options);
|
||||
|
||||
modules = modules.map(module => {
|
||||
const map = fromRawMappings([module]).toMap(module.path, {
|
||||
excludeSource: options.excludeSource,
|
||||
});
|
||||
|
||||
return {
|
||||
id: module.id,
|
||||
code: module.code,
|
||||
map,
|
||||
name: module.name,
|
||||
sourcePath: module.path,
|
||||
source: module.source,
|
||||
type: module.type,
|
||||
};
|
||||
});
|
||||
|
||||
const startupModules = modules.filter(module => {
|
||||
return module.type === 'script' || module.type === 'require';
|
||||
});
|
||||
const lazyModules = modules.filter(module => {
|
||||
return module.type === 'asset' || module.type === 'module';
|
||||
});
|
||||
|
||||
// TODO: Implement RAM groups functionality in Delta Bundler.
|
||||
return {startupModules, lazyModules, groups: new Map()};
|
||||
}
|
||||
|
||||
async function getAssets(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: Options,
|
||||
): Promise<$ReadOnlyArray<AssetData>> {
|
||||
const modules = await getAllModules(deltaBundler, options);
|
||||
|
||||
const assets = await Promise.all(
|
||||
modules.map(async module => {
|
||||
if (module.type === 'asset') {
|
||||
return await deltaBundler
|
||||
.getAssetServer()
|
||||
.getAssetData(module.path, options.platform);
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
);
|
||||
|
||||
return assets.filter(Boolean);
|
||||
}
|
||||
|
||||
async function _build(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: BuildOptions,
|
||||
|
@ -146,4 +209,6 @@ module.exports = {
|
|||
fullSourceMap,
|
||||
fullSourceMapObject,
|
||||
getAllModules,
|
||||
getAssets,
|
||||
getRamBundleInfo,
|
||||
};
|
||||
|
|
|
@ -22,9 +22,12 @@ describe('Serializers', () => {
|
|||
let deltaBundler;
|
||||
|
||||
const deltaResponse = {
|
||||
pre: new Map([[1, {code: 'pre;'}]]),
|
||||
post: new Map([[2, {code: 'post;'}]]),
|
||||
delta: new Map([[3, {code: 'module3;'}], [4, {code: 'another;'}]]),
|
||||
pre: new Map([[1, {type: 'script', code: 'pre;', id: 1, path: '/pre.js'}]]),
|
||||
post: new Map([[2, {type: 'require', code: 'post;', id: 2, path: '/p'}]]),
|
||||
delta: new Map([
|
||||
[3, {type: 'module', code: 'module3;', id: 3, path: '/3.js'}],
|
||||
[4, {type: 'module', code: 'another;', id: 4, path: '/4.js'}],
|
||||
]),
|
||||
inverseDependencies: [],
|
||||
reset: true,
|
||||
};
|
||||
|
@ -45,6 +48,13 @@ describe('Serializers', () => {
|
|||
},
|
||||
};
|
||||
},
|
||||
getAssetServer() {
|
||||
return {
|
||||
async getAssetData(path, platform) {
|
||||
return {path, platform, assetData: true};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
setCurrentTime(CURRENT_TIME);
|
||||
|
@ -133,4 +143,60 @@ describe('Serializers', () => {
|
|||
await Serializers.getAllModules(deltaBundler, {deltaBundleId: 10}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return the RAM bundle info', async () => {
|
||||
expect(
|
||||
await Serializers.getRamBundleInfo(deltaBundler, {deltaBundleId: 10}),
|
||||
).toMatchSnapshot();
|
||||
|
||||
getDelta.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
delta: new Map([
|
||||
[3, {type: 'module', code: 'modified;', id: 3, path: '/foo/3.js'}],
|
||||
[7, {type: 'asset', code: 'code', id: 7, path: '/foo/path.png'}],
|
||||
[8, {type: 'module', code: 'code', id: 8, path: '/foo/8.js'}],
|
||||
[9, {type: 'asset', code: 'code', id: 9, path: '/foo/path3.png'}],
|
||||
]),
|
||||
pre: new Map([
|
||||
[5, {type: 'script', code: 'more pre;', id: 5, path: '/foo/5.js'}],
|
||||
]),
|
||||
post: new Map([
|
||||
[6, {type: 'require', code: 'bananas;', id: 6, path: '/foo/6.js'}],
|
||||
[10, {type: 'comment', code: 'bananas;', id: 10, path: '/foo/10.js'}],
|
||||
]),
|
||||
inverseDependencies: [],
|
||||
}),
|
||||
);
|
||||
|
||||
expect(
|
||||
await Serializers.getRamBundleInfo(deltaBundler, {deltaBundleId: 10}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return the bundle assets', async () => {
|
||||
expect(
|
||||
await Serializers.getAllModules(deltaBundler, {deltaBundleId: 10}),
|
||||
).toMatchSnapshot();
|
||||
|
||||
getDelta.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
delta: new Map([
|
||||
[3, {code: 'modified module;'}],
|
||||
[7, {code: 'code', type: 'asset', path: '/foo/path.png'}],
|
||||
[8, {code: 'code', type: 'module', path: '/foo/path2.png'}],
|
||||
[9, {code: 'code', type: 'asset', path: '/foo/path3.png'}],
|
||||
]),
|
||||
pre: new Map([[5, {code: 'more pre;'}]]),
|
||||
post: new Map([[6, {code: 'bananas;'}]]),
|
||||
inverseDependencies: [],
|
||||
}),
|
||||
);
|
||||
|
||||
expect(
|
||||
await Serializers.getAssets(deltaBundler, {
|
||||
deltaBundleId: 10,
|
||||
platform: 'ios',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,15 +32,27 @@ exports[`Serializers should return all the bundle modules 1`] = `
|
|||
Array [
|
||||
Object {
|
||||
"code": "pre;",
|
||||
"id": 1,
|
||||
"path": "/pre.js",
|
||||
"type": "script",
|
||||
},
|
||||
Object {
|
||||
"code": "module3;",
|
||||
"id": 3,
|
||||
"path": "/3.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "another;",
|
||||
"id": 4,
|
||||
"path": "/4.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "post;",
|
||||
"id": 2,
|
||||
"path": "/p",
|
||||
"type": "require",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
@ -49,6 +61,9 @@ exports[`Serializers should return all the bundle modules 2`] = `
|
|||
Array [
|
||||
Object {
|
||||
"code": "pre;",
|
||||
"id": 1,
|
||||
"path": "/pre.js",
|
||||
"type": "script",
|
||||
},
|
||||
Object {
|
||||
"code": "more pre;",
|
||||
|
@ -58,6 +73,9 @@ Array [
|
|||
},
|
||||
Object {
|
||||
"code": "post;",
|
||||
"id": 2,
|
||||
"path": "/p",
|
||||
"type": "require",
|
||||
},
|
||||
Object {
|
||||
"code": "bananas;",
|
||||
|
@ -68,6 +86,278 @@ Array [
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`Serializers should return the RAM bundle info 1`] = `
|
||||
Object {
|
||||
"groups": Map {},
|
||||
"lazyModules": Array [
|
||||
Object {
|
||||
"code": "module3;",
|
||||
"id": 3,
|
||||
"map": Object {
|
||||
"file": "/3.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/3.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "another;",
|
||||
"id": 4,
|
||||
"map": Object {
|
||||
"file": "/4.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/4.js",
|
||||
"type": "module",
|
||||
},
|
||||
],
|
||||
"startupModules": Array [
|
||||
Object {
|
||||
"code": "pre;",
|
||||
"id": 1,
|
||||
"map": Object {
|
||||
"file": "/pre.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/pre.js",
|
||||
"type": "script",
|
||||
},
|
||||
Object {
|
||||
"code": "post;",
|
||||
"id": 2,
|
||||
"map": Object {
|
||||
"file": "/p",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/p",
|
||||
"type": "require",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Serializers should return the RAM bundle info 2`] = `
|
||||
Object {
|
||||
"groups": Map {},
|
||||
"lazyModules": Array [
|
||||
Object {
|
||||
"code": "modified;",
|
||||
"id": 3,
|
||||
"map": Object {
|
||||
"file": "/foo/3.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/foo/3.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "another;",
|
||||
"id": 4,
|
||||
"map": Object {
|
||||
"file": "/4.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/4.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "code",
|
||||
"id": 7,
|
||||
"map": Object {
|
||||
"file": "/foo/path.png",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/foo/path.png",
|
||||
"type": "asset",
|
||||
},
|
||||
Object {
|
||||
"code": "code",
|
||||
"id": 8,
|
||||
"map": Object {
|
||||
"file": "/foo/8.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/foo/8.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "code",
|
||||
"id": 9,
|
||||
"map": Object {
|
||||
"file": "/foo/path3.png",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/foo/path3.png",
|
||||
"type": "asset",
|
||||
},
|
||||
],
|
||||
"startupModules": Array [
|
||||
Object {
|
||||
"code": "pre;",
|
||||
"id": 1,
|
||||
"map": Object {
|
||||
"file": "/pre.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/pre.js",
|
||||
"type": "script",
|
||||
},
|
||||
Object {
|
||||
"code": "more pre;",
|
||||
"id": 5,
|
||||
"map": Object {
|
||||
"file": "/foo/5.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/foo/5.js",
|
||||
"type": "script",
|
||||
},
|
||||
Object {
|
||||
"code": "post;",
|
||||
"id": 2,
|
||||
"map": Object {
|
||||
"file": "/p",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/p",
|
||||
"type": "require",
|
||||
},
|
||||
Object {
|
||||
"code": "bananas;",
|
||||
"id": 6,
|
||||
"map": Object {
|
||||
"file": "/foo/6.js",
|
||||
"mappings": "",
|
||||
"names": Array [],
|
||||
"sources": Array [],
|
||||
"sourcesContent": Array [],
|
||||
"version": 3,
|
||||
},
|
||||
"name": undefined,
|
||||
"source": undefined,
|
||||
"sourcePath": "/foo/6.js",
|
||||
"type": "require",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Serializers should return the bundle assets 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"code": "pre;",
|
||||
"id": 1,
|
||||
"path": "/pre.js",
|
||||
"type": "script",
|
||||
},
|
||||
Object {
|
||||
"code": "module3;",
|
||||
"id": 3,
|
||||
"path": "/3.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "another;",
|
||||
"id": 4,
|
||||
"path": "/4.js",
|
||||
"type": "module",
|
||||
},
|
||||
Object {
|
||||
"code": "post;",
|
||||
"id": 2,
|
||||
"path": "/p",
|
||||
"type": "require",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Serializers should return the bundle assets 2`] = `
|
||||
Array [
|
||||
Object {
|
||||
"assetData": true,
|
||||
"path": "/foo/path.png",
|
||||
"platform": "ios",
|
||||
},
|
||||
Object {
|
||||
"assetData": true,
|
||||
"path": "/foo/path3.png",
|
||||
"platform": "ios",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Serializers should return the stringified delta bundle 1`] = `
|
||||
Object {
|
||||
"bundle": "{\\"id\\":\\"1234\\",\\"pre\\":[[1,\\"pre;\\"]],\\"post\\":[[2,\\"post;\\"]],\\"delta\\":[[3,\\"module3;\\"],[4,\\"another;\\"]],\\"reset\\":true}",
|
||||
|
|
|
@ -50,6 +50,10 @@ class DeltaBundler {
|
|||
this._deltaTransformers = new Map();
|
||||
}
|
||||
|
||||
getAssetServer() {
|
||||
return this._bundler.getAssetServer();
|
||||
}
|
||||
|
||||
async getDeltaTransformer(
|
||||
options: Options,
|
||||
): Promise<{deltaTransformer: DeltaTransformer, id: string}> {
|
||||
|
|
|
@ -47,6 +47,8 @@ import type {
|
|||
import type {TransformCache} from '../lib/TransformCaching';
|
||||
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||
import type {SourceMap, Symbolicate} from './symbolicate';
|
||||
import type {AssetData} from '../AssetServer';
|
||||
import type {RamBundleInfo} from '../DeltaBundler/Serializers';
|
||||
|
||||
const {
|
||||
createActionStartEntry,
|
||||
|
@ -348,6 +350,31 @@ class Server {
|
|||
return bundle;
|
||||
}
|
||||
|
||||
async build(options: BundleOptions): Promise<{code: string, map: string}> {
|
||||
options = {
|
||||
...options,
|
||||
deltaBundleId: null,
|
||||
};
|
||||
|
||||
return {
|
||||
code: (await Serializers.fullBundle(this._deltaBundler, options)).bundle,
|
||||
map: await Serializers.fullSourceMap(this._deltaBundler, options),
|
||||
};
|
||||
}
|
||||
|
||||
async getRamBundleInfo(options: BundleOptions): Promise<RamBundleInfo> {
|
||||
options = {...options, deltaBundleId: null};
|
||||
|
||||
return await Serializers.getRamBundleInfo(this._deltaBundler, options);
|
||||
}
|
||||
|
||||
async getAssets(options: BundleOptions): Promise<$ReadOnlyArray<AssetData>> {
|
||||
return await Serializers.getAssets(this._deltaBundler, {
|
||||
...options,
|
||||
deltaBundleId: null,
|
||||
});
|
||||
}
|
||||
|
||||
buildBundleFromUrl(reqUrl: string): Promise<Bundle> {
|
||||
const options = this._getOptionsFromUrl(reqUrl);
|
||||
return this.buildBundle(options);
|
||||
|
|
Loading…
Reference in New Issue