mirror of https://github.com/status-im/metro.git
Use the new Graph object for generating assets
Reviewed By: mjesun Differential Revision: D7275601 fbshipit-source-id: b7c03ec35ea1994e2441da2889a44466e9e2aa0f
This commit is contained in:
parent
ce2ee5a19c
commit
0520fb254b
|
@ -14,13 +14,10 @@ const DeltaPatcher = require('../DeltaPatcher');
|
|||
const RamBundle = require('./RamBundle');
|
||||
|
||||
const stableHash = require('metro-cache/src/stableHash');
|
||||
const toLocalPath = require('../../node-haste/lib/toLocalPath');
|
||||
|
||||
const {getAssetData} = require('../../Assets');
|
||||
const {createRamBundleGroups} = require('../../Bundler/util');
|
||||
const {fromRawMappings} = require('metro-source-map');
|
||||
|
||||
import type {AssetData} from '../../Assets';
|
||||
import type {GetTransformOptions} from '../../Bundler';
|
||||
import type {BundleOptions, ModuleTransportLike} from '../../shared/types.flow';
|
||||
import type DeltaBundler from '../';
|
||||
|
@ -241,32 +238,6 @@ async function getRamBundleInfo(
|
|||
};
|
||||
}
|
||||
|
||||
async function getAssets(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: BundleOptions,
|
||||
projectRoots: $ReadOnlyArray<string>,
|
||||
): Promise<$ReadOnlyArray<AssetData>> {
|
||||
const {modules} = await _getAllModules(deltaBundler, options);
|
||||
|
||||
const assets = await Promise.all(
|
||||
modules.map(async module => {
|
||||
if (module.type === 'asset') {
|
||||
const localPath = toLocalPath(projectRoots, module.path);
|
||||
|
||||
return getAssetData(
|
||||
module.path,
|
||||
localPath,
|
||||
options.assetPlugins,
|
||||
options.platform,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
);
|
||||
|
||||
return assets.filter(Boolean);
|
||||
}
|
||||
|
||||
async function _build(
|
||||
deltaBundler: DeltaBundler,
|
||||
clientId: string,
|
||||
|
@ -294,6 +265,5 @@ module.exports = {
|
|||
fullSourceMap,
|
||||
fullSourceMapObject,
|
||||
getAllModules,
|
||||
getAssets,
|
||||
getRamBundleInfo,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
jest.mock('../../../node-haste/lib/toLocalPath');
|
||||
jest.mock('../../../Assets');
|
||||
|
||||
const {getAssetData} = require('../../../Assets');
|
||||
const toLocalPath = require('../../../node-haste/lib/toLocalPath');
|
||||
|
||||
const CURRENT_TIME = 1482363367000;
|
||||
|
@ -61,14 +60,6 @@ describe('Serializers', () => {
|
|||
},
|
||||
};
|
||||
|
||||
getAssetData.mockImplementation(
|
||||
(path, localPath, assetDataPlugins, platform) => ({
|
||||
path,
|
||||
platform,
|
||||
assetData: true,
|
||||
}),
|
||||
);
|
||||
|
||||
toLocalPath.mockImplementation((roots, path) => path.replace(roots[0], ''));
|
||||
|
||||
setCurrentTime(CURRENT_TIME);
|
||||
|
@ -235,35 +226,6 @@ describe('Serializers', () => {
|
|||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return the bundle assets', async () => {
|
||||
expect(await Serializers.getAllModules(deltaBundler, {})).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: [],
|
||||
reset: true,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(
|
||||
await Serializers.getAssets(
|
||||
deltaBundler,
|
||||
{
|
||||
platform: 'ios',
|
||||
},
|
||||
['/foo'],
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should post-process the modules', async () => {
|
||||
postProcessModules.mockImplementation(modules => {
|
||||
return modules.sort(
|
||||
|
|
|
@ -345,50 +345,6 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
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}",
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+javascript_foundation
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
jest.mock('../../../Assets');
|
||||
|
||||
const getAssets = require('../getAssets');
|
||||
|
||||
const {getAssetData} = require('../../../Assets');
|
||||
|
||||
beforeEach(() => {
|
||||
getAssetData.mockImplementation(async (path, localPath) => ({
|
||||
path,
|
||||
localPath,
|
||||
}));
|
||||
});
|
||||
|
||||
it('should return the bundle assets', async () => {
|
||||
const graph = {
|
||||
dependencies: new Map([
|
||||
['/tmp/1.js', {path: '/tmp/1.js', output: {type: 'module'}}],
|
||||
['/tmp/2.js', {path: '/tmp/2.js', output: {type: 'module'}}],
|
||||
['/tmp/3.png', {path: '/tmp/3.png', output: {type: 'asset'}}],
|
||||
['/tmp/4.js', {path: '/tmp/2.js', output: {type: 'module'}}],
|
||||
['/tmp/5.mov', {path: '/tmp/5.mov', output: {type: 'asset'}}],
|
||||
]),
|
||||
};
|
||||
|
||||
expect(await getAssets(graph, {projectRoots: ['/tmp']})).toEqual([
|
||||
{path: '/tmp/3.png', localPath: '3.png'},
|
||||
{path: '/tmp/5.mov', localPath: '5.mov'},
|
||||
]);
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const toLocalPath = require('../../node-haste/lib/toLocalPath');
|
||||
|
||||
const {getAssetData} = require('../../Assets');
|
||||
|
||||
import type {AssetData} from '../../Assets';
|
||||
import type {Graph} from '../DeltaCalculator';
|
||||
|
||||
type Options = {|
|
||||
assetPlugins: $ReadOnlyArray<string>,
|
||||
platform: ?string,
|
||||
projectRoots: $ReadOnlyArray<string>,
|
||||
|};
|
||||
|
||||
async function getAssets(
|
||||
graph: Graph,
|
||||
options: Options,
|
||||
): Promise<$ReadOnlyArray<AssetData>> {
|
||||
const assets = await Promise.all(
|
||||
Array.from(graph.dependencies.values()).map(async module => {
|
||||
if (module.output.type === 'asset') {
|
||||
return getAssetData(
|
||||
module.path,
|
||||
toLocalPath(options.projectRoots, module.path),
|
||||
options.assetPlugins,
|
||||
options.platform,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
);
|
||||
|
||||
return assets.filter(Boolean);
|
||||
}
|
||||
|
||||
module.exports = getAssets;
|
|
@ -16,6 +16,7 @@ const MultipartResponse = require('./MultipartResponse');
|
|||
const Serializers = require('../DeltaBundler/Serializers/Serializers');
|
||||
|
||||
const defaultCreateModuleIdFactory = require('../lib/createModuleIdFactory');
|
||||
const getAssets = require('../DeltaBundler/Serializers/getAssets');
|
||||
const plainJSBundle = require('../DeltaBundler/Serializers/plainJSBundle');
|
||||
const sourceMapString = require('../DeltaBundler/Serializers/sourceMapString');
|
||||
const debug = require('debug')('Metro:Server');
|
||||
|
@ -52,6 +53,7 @@ import type {
|
|||
PostProcessBundleSourcemap,
|
||||
} from '../Bundler';
|
||||
import type {CacheStore} from 'metro-cache';
|
||||
import type {Graph} from '../DeltaBundler';
|
||||
import type {MetroSourceMap} from 'metro-source-map';
|
||||
import type {TransformCache} from '../lib/TransformCaching';
|
||||
import type {Symbolicate} from './symbolicate/symbolicate';
|
||||
|
@ -64,6 +66,11 @@ const {
|
|||
|
||||
type ResolveSync = (path: string, opts: ?{baseDir?: string}) => string;
|
||||
|
||||
type GraphInfo = {|
|
||||
graph: Graph,
|
||||
prepend: $ReadOnlyArray<DependencyEdge>,
|
||||
|};
|
||||
|
||||
function debounceAndBatch(fn, delay) {
|
||||
let timeout;
|
||||
return () => {
|
||||
|
@ -243,49 +250,22 @@ class Server {
|
|||
}
|
||||
|
||||
async build(options: BundleOptions): Promise<{code: string, map: string}> {
|
||||
const {prepend, graph} = await this._buildGraph(options);
|
||||
|
||||
const entryPoint = getAbsolutePath(
|
||||
options.entryFile,
|
||||
this._opts.projectRoots,
|
||||
);
|
||||
|
||||
const crawlingOptions = {
|
||||
assetPlugins: options.assetPlugins,
|
||||
customTransformOptions: options.customTransformOptions,
|
||||
dev: options.dev,
|
||||
entryPoints: [entryPoint],
|
||||
hot: options.hot,
|
||||
minify: options.minify,
|
||||
onProgress: options.onProgress,
|
||||
platform: options.platform,
|
||||
type: 'module',
|
||||
};
|
||||
|
||||
let graph = await this._deltaBundler.buildGraph(crawlingOptions);
|
||||
let prependScripts = await getPrependedScripts(
|
||||
this._opts,
|
||||
crawlingOptions,
|
||||
this._deltaBundler,
|
||||
);
|
||||
|
||||
if (options.minify) {
|
||||
prependScripts = await Promise.all(
|
||||
prependScripts.map(script => this._minifyModule(script)),
|
||||
);
|
||||
|
||||
graph = await mapGraph(graph, module => this._minifyModule(module));
|
||||
}
|
||||
|
||||
return {
|
||||
code: plainJSBundle(entryPoint, prependScripts, graph, {
|
||||
code: plainJSBundle(entryPoint, prepend, graph, {
|
||||
createModuleId: this._opts.createModuleId,
|
||||
dev: options.dev,
|
||||
runBeforeMainModule: this._opts.getModulesRunBeforeMainModule(
|
||||
options.entryFile,
|
||||
),
|
||||
runBeforeMainModule: options.runBeforeMainModule,
|
||||
runModule: options.runModule,
|
||||
sourceMapUrl: options.sourceMapUrl,
|
||||
}),
|
||||
map: sourceMapString(prependScripts, graph, {
|
||||
map: sourceMapString(prepend, graph, {
|
||||
excludeSource: options.excludeSource,
|
||||
}),
|
||||
};
|
||||
|
@ -303,14 +283,16 @@ class Server {
|
|||
}
|
||||
|
||||
async getAssets(options: BundleOptions): Promise<$ReadOnlyArray<AssetData>> {
|
||||
return await Serializers.getAssets(
|
||||
this._deltaBundler,
|
||||
{
|
||||
const {graph} = await this._buildGraph({
|
||||
...options,
|
||||
entryFile: getAbsolutePath(options.entryFile, this._opts.projectRoots),
|
||||
},
|
||||
this._opts.projectRoots,
|
||||
);
|
||||
minify: false, // minification does not affect the assets.
|
||||
});
|
||||
|
||||
return await getAssets(graph, {
|
||||
assetPlugins: options.assetPlugins,
|
||||
platform: options.platform,
|
||||
projectRoots: this._opts.projectRoots,
|
||||
});
|
||||
}
|
||||
|
||||
async getOrderedDependencyPaths(options: {
|
||||
|
@ -336,6 +318,45 @@ class Server {
|
|||
return await getOrderedDependencyPaths(this._deltaBundler, bundleOptions);
|
||||
}
|
||||
|
||||
async _buildGraph(options: BundleOptions): Promise<GraphInfo> {
|
||||
const entryPoint = getAbsolutePath(
|
||||
options.entryFile,
|
||||
this._opts.projectRoots,
|
||||
);
|
||||
|
||||
const crawlingOptions = {
|
||||
assetPlugins: options.assetPlugins,
|
||||
customTransformOptions: options.customTransformOptions,
|
||||
dev: options.dev,
|
||||
entryPoints: [entryPoint],
|
||||
hot: options.hot,
|
||||
minify: options.minify,
|
||||
onProgress: options.onProgress,
|
||||
platform: options.platform,
|
||||
type: 'module',
|
||||
};
|
||||
|
||||
let graph = await this._deltaBundler.buildGraph(crawlingOptions);
|
||||
let prepend = await getPrependedScripts(
|
||||
this._opts,
|
||||
crawlingOptions,
|
||||
this._deltaBundler,
|
||||
);
|
||||
|
||||
if (options.minify) {
|
||||
prepend = await Promise.all(
|
||||
prepend.map(script => this._minifyModule(script)),
|
||||
);
|
||||
|
||||
graph = await mapGraph(graph, module => this._minifyModule(module));
|
||||
}
|
||||
|
||||
return {
|
||||
prepend,
|
||||
graph,
|
||||
};
|
||||
}
|
||||
|
||||
async _minifyModule(module: DependencyEdge): Promise<DependencyEdge> {
|
||||
const {code, map} = await this._bundler.minifyModule(
|
||||
module.path,
|
||||
|
|
Loading…
Reference in New Issue