mirror of https://github.com/status-im/metro.git
Use the new Graph object for generating dev bundle/sourcemaps
Reviewed By: mjesun Differential Revision: D7275599 fbshipit-source-id: 4889d259005b3df19977925a6729805b9df68113
This commit is contained in:
parent
12fe345e1b
commit
b9b541542b
|
@ -71,17 +71,6 @@ async function deltaBundle(
|
|||
};
|
||||
}
|
||||
|
||||
async function fullSourceMap(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: BundleOptions,
|
||||
): Promise<string> {
|
||||
const {modules} = await _getAllModules(deltaBundler, options);
|
||||
|
||||
return fromRawMappings(modules).toString(undefined, {
|
||||
excludeSource: options.excludeSource,
|
||||
});
|
||||
}
|
||||
|
||||
async function fullSourceMapObject(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: BundleOptions,
|
||||
|
@ -93,27 +82,6 @@ async function fullSourceMapObject(
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full JS bundle, which can be directly parsed by a JS interpreter
|
||||
*/
|
||||
async function fullBundle(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: BundleOptions,
|
||||
): Promise<{bundle: string, numModifiedFiles: number, lastModified: Date}> {
|
||||
const {modules, numModifiedFiles, lastModified} = await _getAllModules(
|
||||
deltaBundler,
|
||||
options,
|
||||
);
|
||||
|
||||
const code = modules.map(m => m.code);
|
||||
|
||||
return {
|
||||
bundle: code.join('\n'),
|
||||
lastModified,
|
||||
numModifiedFiles,
|
||||
};
|
||||
}
|
||||
|
||||
async function _getAllModules(
|
||||
deltaBundler: DeltaBundler,
|
||||
options: BundleOptions,
|
||||
|
@ -252,8 +220,6 @@ async function _build(
|
|||
|
||||
module.exports = {
|
||||
deltaBundle,
|
||||
fullBundle,
|
||||
fullSourceMap,
|
||||
fullSourceMapObject,
|
||||
getRamBundleInfo,
|
||||
};
|
||||
|
|
|
@ -86,61 +86,6 @@ describe('Serializers', () => {
|
|||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should build the full JS bundle', async () => {
|
||||
expect(
|
||||
await Serializers.fullBundle(deltaBundler, {
|
||||
sourceMapUrl: 'http://localhost:8081/myBundle.js',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
|
||||
getDelta.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
id: '1234',
|
||||
delta: new Map([[3, {code: 'modified module;'}], [4, null]]),
|
||||
pre: new Map([[5, {code: 'more pre;'}]]),
|
||||
post: new Map([[6, {code: 'bananas;'}], [7, {code: 'apples;'}]]),
|
||||
inverseDependencies: [],
|
||||
}),
|
||||
);
|
||||
setCurrentTime(CURRENT_TIME + 5000);
|
||||
|
||||
expect(
|
||||
await Serializers.fullBundle(deltaBundler, {
|
||||
sourceMapUrl: 'http://localhost:8081/myBundle.js',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should pass the sourcemapURL param to the transformer', async () => {
|
||||
await Serializers.fullBundle(deltaBundler, {
|
||||
sourceMapUrl: 'http://localhost:8081/myBundle.js',
|
||||
});
|
||||
|
||||
expect(deltaBundler.getDeltaTransformer.mock.calls[0][1]).toEqual({
|
||||
deltaBundleId: '1234',
|
||||
sourceMapUrl: 'http://localhost:8081/myBundle.js',
|
||||
});
|
||||
});
|
||||
|
||||
// This test actually does not test the sourcemaps generation logic, which
|
||||
// is already tested in the source-map file.
|
||||
it('should build the full Source Maps', async () => {
|
||||
expect(await Serializers.fullSourceMap(deltaBundler, {})).toMatchSnapshot();
|
||||
|
||||
getDelta.mockReturnValueOnce(
|
||||
Promise.resolve({
|
||||
id: '1234',
|
||||
delta: new Map([[3, {code: 'modified module;'}], [4, null]]),
|
||||
pre: new Map([[5, {code: 'more pre;'}]]),
|
||||
post: new Map([[6, {code: 'bananas;'}], [7, {code: 'apples;'}]]),
|
||||
inverseDependencies: [],
|
||||
}),
|
||||
);
|
||||
setCurrentTime(CURRENT_TIME + 5000);
|
||||
|
||||
expect(await Serializers.fullSourceMap(deltaBundler, {})).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should return the RAM bundle info', async () => {
|
||||
expect(
|
||||
await Serializers.getRamBundleInfo(deltaBundler, {}),
|
||||
|
|
|
@ -1,33 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Serializers should build the full JS bundle 1`] = `
|
||||
Object {
|
||||
"bundle": "pre;
|
||||
module3;
|
||||
another;
|
||||
post;",
|
||||
"lastModified": 2016-12-21T23:36:07.000Z,
|
||||
"numModifiedFiles": 4,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Serializers should build the full JS bundle 2`] = `
|
||||
Object {
|
||||
"bundle": "pre;
|
||||
more pre;
|
||||
modified module;
|
||||
post;
|
||||
bananas;
|
||||
apples;",
|
||||
"lastModified": 2016-12-21T23:36:12.000Z,
|
||||
"numModifiedFiles": 5,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Serializers should build the full Source Maps 1`] = `"{\\"version\\":3,\\"sources\\":[],\\"sourcesContent\\":[],\\"names\\":[],\\"mappings\\":\\"\\"}"`;
|
||||
|
||||
exports[`Serializers should build the full Source Maps 2`] = `"{\\"version\\":3,\\"sources\\":[],\\"sourcesContent\\":[],\\"names\\":[],\\"mappings\\":\\"\\"}"`;
|
||||
|
||||
exports[`Serializers should return the RAM bundle info 1`] = `
|
||||
Object {
|
||||
"getDependencies": [Function],
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* 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';
|
||||
|
||||
const sourceMapString = require('../sourceMapString');
|
||||
|
||||
const polyfill = {
|
||||
path: '/root/pre.js',
|
||||
output: {
|
||||
type: 'script',
|
||||
code: '__d(function() {/* code for polyfill */});',
|
||||
map: [],
|
||||
source: 'source pre',
|
||||
},
|
||||
};
|
||||
|
||||
const fooModule = {
|
||||
path: '/root/foo.js',
|
||||
dependencies: new Map([['./bar', 'bar']]),
|
||||
output: {
|
||||
code: '__d(function() {/* code for foo */});',
|
||||
map: [],
|
||||
source: 'source foo',
|
||||
},
|
||||
};
|
||||
|
||||
const barModule = {
|
||||
path: '/root/bar.js',
|
||||
dependencies: new Map(),
|
||||
output: {
|
||||
code: '__d(function() {/* code for bar */});',
|
||||
map: [],
|
||||
source: 'source bar',
|
||||
},
|
||||
};
|
||||
|
||||
it('should serialize a very simple bundle', () => {
|
||||
expect(
|
||||
JSON.parse(
|
||||
sourceMapString(
|
||||
[polyfill],
|
||||
{
|
||||
dependencies: new Map([['foo', fooModule], ['bar', barModule]]),
|
||||
entryPoints: ['foo'],
|
||||
},
|
||||
{excludesSource: false},
|
||||
),
|
||||
),
|
||||
).toEqual({
|
||||
version: 3,
|
||||
sources: ['/root/pre.js', '/root/foo.js', '/root/bar.js'],
|
||||
sourcesContent: ['source pre', 'source foo', 'source bar'],
|
||||
names: [],
|
||||
mappings: '',
|
||||
});
|
||||
});
|
|
@ -20,16 +20,14 @@ function fullSourceMap(
|
|||
graph: Graph,
|
||||
options: {|+excludeSource: boolean|},
|
||||
): string {
|
||||
const modules = pre.concat(...graph.dependencies.values());
|
||||
|
||||
const modulesWithMaps = modules.map(module => {
|
||||
const modules = [...pre, ...graph.dependencies.values()].map(module => {
|
||||
return {
|
||||
...module.output,
|
||||
path: module.path,
|
||||
};
|
||||
});
|
||||
|
||||
return fromRawMappings(modulesWithMaps).toString(undefined, {
|
||||
return fromRawMappings(modules).toString(undefined, {
|
||||
excludeSource: options.excludeSource,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ jest
|
|||
createWorker: jest.fn().mockReturnValue(jest.fn()),
|
||||
}))
|
||||
.mock('../../Bundler')
|
||||
.mock('../../DeltaBundler')
|
||||
.mock('../../Assets')
|
||||
.mock('../../lib/getPrependedScripts')
|
||||
.mock('../../node-haste/DependencyGraph')
|
||||
|
@ -34,7 +35,8 @@ describe('processRequest', () => {
|
|||
let symbolicate;
|
||||
let Serializers;
|
||||
let DeltaBundler;
|
||||
const lastModified = new Date();
|
||||
|
||||
const NativeDate = global.Date;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
|
@ -84,42 +86,58 @@ describe('processRequest', () => {
|
|||
),
|
||||
);
|
||||
|
||||
const invalidatorFunc = jest.fn();
|
||||
let requestHandler;
|
||||
|
||||
beforeEach(() => {
|
||||
DeltaBundler.prototype.buildGraph = jest.fn().mockReturnValue(
|
||||
global.Date = NativeDate;
|
||||
|
||||
DeltaBundler.prototype.buildGraph.mockReturnValue(
|
||||
Promise.resolve({
|
||||
entryPoints: [''],
|
||||
dependencies: new Map(),
|
||||
entryPoints: ['/root/mybundle.js'],
|
||||
dependencies: new Map([
|
||||
[
|
||||
'/root/mybundle.js',
|
||||
{
|
||||
path: '/root/mybundle.js',
|
||||
dependencies: new Map([['foo', '/root/foo.js']]),
|
||||
output: {
|
||||
code: '__d(function() {entry();});',
|
||||
map: [],
|
||||
source: 'code-mybundle',
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'/root/foo.js',
|
||||
{
|
||||
path: '/root/foo.js',
|
||||
dependencies: new Map(),
|
||||
output: {
|
||||
code: '__d(function() {foo();});',
|
||||
map: [],
|
||||
source: 'code-foo',
|
||||
},
|
||||
},
|
||||
],
|
||||
]),
|
||||
}),
|
||||
);
|
||||
|
||||
getPrependedScripts.mockReturnValue(Promise.resolve([]));
|
||||
|
||||
Serializers.fullBundle.mockReturnValue(
|
||||
Promise.resolve({
|
||||
bundle: 'this is the source',
|
||||
numModifiedFiles: 38,
|
||||
lastModified,
|
||||
}),
|
||||
getPrependedScripts.mockReturnValue(
|
||||
Promise.resolve([
|
||||
{
|
||||
path: 'require-js',
|
||||
dependencies: new Map(),
|
||||
output: {
|
||||
code: 'function () {require();}',
|
||||
map: [],
|
||||
type: 'script',
|
||||
source: 'code-require',
|
||||
},
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
Serializers.fullSourceMap.mockReturnValue(
|
||||
Promise.resolve('this is the source map'),
|
||||
);
|
||||
|
||||
Bundler.prototype.bundle = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
getModules: () => [],
|
||||
getSource: () => 'this is the source',
|
||||
getSourceMap: () => ({version: 3}),
|
||||
getSourceMapString: () => 'this is the source map',
|
||||
getEtag: () => 'this is an etag',
|
||||
}),
|
||||
);
|
||||
|
||||
Bundler.prototype.invalidateFile = invalidatorFunc;
|
||||
Bundler.prototype.getDependencyGraph = jest.fn().mockReturnValue(
|
||||
Promise.resolve({
|
||||
getHasteMap: jest.fn().mockReturnValue({on: jest.fn()}),
|
||||
|
@ -131,17 +149,38 @@ describe('processRequest', () => {
|
|||
requestHandler = server.processRequest.bind(server);
|
||||
});
|
||||
|
||||
it('returns JS bundle source on request of *.bundle', () => {
|
||||
return makeRequest(
|
||||
it('returns JS bundle source on request of *.bundle', async () => {
|
||||
const response = await makeRequest(
|
||||
requestHandler,
|
||||
'mybundle.bundle?runModule=true',
|
||||
null,
|
||||
).then(response => expect(response.body).toEqual('this is the source'));
|
||||
);
|
||||
|
||||
expect(response.body).toEqual(
|
||||
[
|
||||
'function () {require();}',
|
||||
'__d(function() {entry();},0,[1],"mybundle.js");',
|
||||
'__d(function() {foo();},1,[],"foo.js");',
|
||||
'require(0);',
|
||||
'//# sourceMappingURL=http://localhost:8081/mybundle.map?runModule=true',
|
||||
].join('\n'),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns JS bundle source on request of *.bundle (compat)', () => {
|
||||
return makeRequest(requestHandler, 'mybundle.runModule.bundle').then(
|
||||
response => expect(response.body).toEqual('this is the source'),
|
||||
it('returns JS bundle without the initial require() call', async () => {
|
||||
const response = await makeRequest(
|
||||
requestHandler,
|
||||
'mybundle.bundle?runModule=false',
|
||||
null,
|
||||
);
|
||||
|
||||
expect(response.body).toEqual(
|
||||
[
|
||||
'function () {require();}',
|
||||
'__d(function() {entry();},0,[1],"mybundle.js");',
|
||||
'__d(function() {foo();},1,[],"foo.js");',
|
||||
'//# sourceMappingURL=http://localhost:8081/mybundle.map?runModule=false',
|
||||
].join('\n'),
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -153,12 +192,13 @@ describe('processRequest', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('returns build info headers on request of *.bundle', () => {
|
||||
return makeRequest(requestHandler, 'mybundle.bundle?runModule=true').then(
|
||||
response => {
|
||||
expect(response.getHeader('X-Metro-Files-Changed-Count')).toEqual('38');
|
||||
},
|
||||
it('returns build info headers on request of *.bundle', async () => {
|
||||
const response = await makeRequest(
|
||||
requestHandler,
|
||||
'mybundle.bundle?runModule=true',
|
||||
);
|
||||
|
||||
expect(response.getHeader('X-Metro-Files-Changed-Count')).toEqual('3');
|
||||
});
|
||||
|
||||
it('returns Content-Length header on request of *.bundle', () => {
|
||||
|
@ -171,47 +211,133 @@ describe('processRequest', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('returns 304 on request of *.bundle when if-modified-since equals Last-Modified', () => {
|
||||
it('returns 304 on request of *.bundle when if-modified-since equals Last-Modified', async () => {
|
||||
const response = await makeRequest(
|
||||
requestHandler,
|
||||
'mybundle.bundle?runModule=true',
|
||||
);
|
||||
const lastModified = response.headers['Last-Modified'];
|
||||
|
||||
DeltaBundler.prototype.getDelta.mockReturnValue(
|
||||
Promise.resolve({
|
||||
modified: new Map(),
|
||||
deleted: new Set(),
|
||||
reset: false,
|
||||
}),
|
||||
);
|
||||
|
||||
global.Date = class {
|
||||
constructor() {
|
||||
return new NativeDate('2017-07-07T00:10:20.000Z');
|
||||
}
|
||||
now() {
|
||||
return NativeDate.now();
|
||||
}
|
||||
};
|
||||
|
||||
return makeRequest(requestHandler, 'mybundle.bundle?runModule=true', {
|
||||
headers: {'if-modified-since': lastModified.toUTCString()},
|
||||
headers: {'if-modified-since': lastModified},
|
||||
}).then(response => {
|
||||
expect(response.statusCode).toEqual(304);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns sourcemap on request of *.map', () => {
|
||||
return makeRequest(requestHandler, 'mybundle.map?runModule=true').then(
|
||||
response => expect(response.body).toEqual('this is the source map'),
|
||||
it('returns 200 on request of *.bundle when something changes (ignoring if-modified-since headers)', async () => {
|
||||
const response = await makeRequest(
|
||||
requestHandler,
|
||||
'mybundle.bundle?runModule=true',
|
||||
);
|
||||
const lastModified = response.headers['Last-Modified'];
|
||||
|
||||
DeltaBundler.prototype.getDelta.mockReturnValue(
|
||||
Promise.resolve({
|
||||
modified: new Map([
|
||||
[0, '__d(function() {entry();},0,[1],"mybundle.js");'],
|
||||
]),
|
||||
deleted: new Set(),
|
||||
reset: false,
|
||||
}),
|
||||
);
|
||||
|
||||
global.Date = class {
|
||||
constructor() {
|
||||
return new NativeDate('2017-07-07T00:10:20.000Z');
|
||||
}
|
||||
now() {
|
||||
return NativeDate.now();
|
||||
}
|
||||
};
|
||||
|
||||
return makeRequest(requestHandler, 'mybundle.bundle?runModule=true', {
|
||||
headers: {'if-modified-since': lastModified},
|
||||
}).then(response => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.getHeader('X-Metro-Files-Changed-Count')).toEqual('1');
|
||||
});
|
||||
});
|
||||
|
||||
it('returns sourcemap on request of *.map', async () => {
|
||||
const response = await makeRequest(requestHandler, 'mybundle.map');
|
||||
|
||||
expect(JSON.parse(response.body)).toEqual({
|
||||
version: 3,
|
||||
sources: ['require-js', '/root/mybundle.js', '/root/foo.js'],
|
||||
sourcesContent: ['code-require', 'code-mybundle', 'code-foo'],
|
||||
names: [],
|
||||
mappings: '',
|
||||
});
|
||||
});
|
||||
|
||||
it('does not rebuild the graph when requesting the sourcemaps after having requested the same bundle', async () => {
|
||||
expect(
|
||||
(await makeRequest(requestHandler, 'mybundle.bundle?platform=ios'))
|
||||
.statusCode,
|
||||
).toBe(200);
|
||||
|
||||
DeltaBundler.prototype.buildGraph.mockClear();
|
||||
DeltaBundler.prototype.getDelta.mockClear();
|
||||
|
||||
expect(
|
||||
(await makeRequest(requestHandler, 'mybundle.map?platform=ios'))
|
||||
.statusCode,
|
||||
).toBe(200);
|
||||
|
||||
expect(DeltaBundler.prototype.buildGraph.mock.calls.length).toBe(0);
|
||||
expect(DeltaBundler.prototype.getDelta.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('does rebuild the graph when requesting the sourcemaps if the bundle has not been built yet', async () => {
|
||||
expect(
|
||||
(await makeRequest(requestHandler, 'mybundle.bundle?platform=ios'))
|
||||
.statusCode,
|
||||
).toBe(200);
|
||||
|
||||
DeltaBundler.prototype.buildGraph.mockClear();
|
||||
DeltaBundler.prototype.getDelta.mockClear();
|
||||
|
||||
// request the map of a different bundle
|
||||
expect(
|
||||
(await makeRequest(requestHandler, 'mybundle.map?platform=android'))
|
||||
.statusCode,
|
||||
).toBe(200);
|
||||
|
||||
expect(DeltaBundler.prototype.buildGraph.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('works with .ios.js extension', () => {
|
||||
return makeRequest(requestHandler, 'index.ios.includeRequire.bundle').then(
|
||||
response => {
|
||||
expect(response.body).toEqual('this is the source');
|
||||
expect(Serializers.fullBundle).toBeCalledWith(
|
||||
expect.any(DeltaBundler),
|
||||
{
|
||||
assetPlugins: [],
|
||||
bundleType: 'bundle',
|
||||
customTransformOptions: {},
|
||||
dev: true,
|
||||
entryFile: '/root/index.ios.js',
|
||||
entryModuleOnly: false,
|
||||
excludeSource: false,
|
||||
hot: true,
|
||||
inlineSourceMap: false,
|
||||
isolateModuleIDs: false,
|
||||
minify: false,
|
||||
onProgress: jasmine.any(Function),
|
||||
platform: null,
|
||||
resolutionResponse: null,
|
||||
runBeforeMainModule: ['InitializeCore'],
|
||||
runModule: true,
|
||||
sourceMapUrl: 'http://localhost:8081/index.ios.includeRequire.map',
|
||||
unbundle: false,
|
||||
},
|
||||
);
|
||||
expect(DeltaBundler.prototype.buildGraph).toBeCalledWith({
|
||||
assetPlugins: [],
|
||||
customTransformOptions: {},
|
||||
dev: true,
|
||||
entryPoints: ['/root/index.ios.js'],
|
||||
hot: true,
|
||||
minify: false,
|
||||
onProgress: jasmine.any(Function),
|
||||
platform: null,
|
||||
type: 'module',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -219,30 +345,17 @@ describe('processRequest', () => {
|
|||
it('passes in the platform param', function() {
|
||||
return makeRequest(requestHandler, 'index.bundle?platform=ios').then(
|
||||
function(response) {
|
||||
expect(response.body).toEqual('this is the source');
|
||||
expect(Serializers.fullBundle).toBeCalledWith(
|
||||
expect.any(DeltaBundler),
|
||||
{
|
||||
assetPlugins: [],
|
||||
bundleType: 'bundle',
|
||||
customTransformOptions: {},
|
||||
dev: true,
|
||||
entryFile: '/root/index.js',
|
||||
entryModuleOnly: false,
|
||||
excludeSource: false,
|
||||
hot: true,
|
||||
inlineSourceMap: false,
|
||||
isolateModuleIDs: false,
|
||||
minify: false,
|
||||
onProgress: jasmine.any(Function),
|
||||
platform: 'ios',
|
||||
resolutionResponse: null,
|
||||
runBeforeMainModule: ['InitializeCore'],
|
||||
runModule: true,
|
||||
sourceMapUrl: 'http://localhost:8081/index.map?platform=ios',
|
||||
unbundle: false,
|
||||
},
|
||||
);
|
||||
expect(DeltaBundler.prototype.buildGraph).toBeCalledWith({
|
||||
assetPlugins: [],
|
||||
customTransformOptions: {},
|
||||
dev: true,
|
||||
entryPoints: ['/root/index.js'],
|
||||
hot: true,
|
||||
minify: false,
|
||||
onProgress: jasmine.any(Function),
|
||||
platform: 'ios',
|
||||
type: 'module',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -252,27 +365,16 @@ describe('processRequest', () => {
|
|||
requestHandler,
|
||||
'index.bundle?assetPlugin=assetPlugin1&assetPlugin=assetPlugin2',
|
||||
).then(function(response) {
|
||||
expect(response.body).toEqual('this is the source');
|
||||
expect(Serializers.fullBundle).toBeCalledWith(expect.any(DeltaBundler), {
|
||||
expect(DeltaBundler.prototype.buildGraph).toBeCalledWith({
|
||||
assetPlugins: ['assetPlugin1', 'assetPlugin2'],
|
||||
bundleType: 'bundle',
|
||||
customTransformOptions: {},
|
||||
dev: true,
|
||||
entryFile: '/root/index.js',
|
||||
entryModuleOnly: false,
|
||||
excludeSource: false,
|
||||
entryPoints: ['/root/index.js'],
|
||||
hot: true,
|
||||
inlineSourceMap: false,
|
||||
isolateModuleIDs: false,
|
||||
minify: false,
|
||||
onProgress: jasmine.any(Function),
|
||||
platform: null,
|
||||
resolutionResponse: null,
|
||||
runBeforeMainModule: ['InitializeCore'],
|
||||
runModule: true,
|
||||
sourceMapUrl:
|
||||
'http://localhost:8081/index.map?assetPlugin=assetPlugin1&assetPlugin=assetPlugin2',
|
||||
unbundle: false,
|
||||
type: 'module',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`processRequest Generate delta bundle endpoint should send the correct deltaBundlerId to the bundler 1`] = `"{\\"sourceMapUrl\\":null,\\"bundleType\\":\\"delta\\",\\"customTransformOptions\\":{},\\"entryFile\\":\\"/root/index.js\\",\\"deltaBundleId\\":null,\\"dev\\":true,\\"minify\\":false,\\"excludeSource\\":null,\\"hot\\":true,\\"runBeforeMainModule\\":[\\"InitializeCore\\"],\\"runModule\\":true,\\"inlineSourceMap\\":false,\\"isolateModuleIDs\\":false,\\"platform\\":\\"ios\\",\\"resolutionResponse\\":null,\\"entryModuleOnly\\":false,\\"assetPlugins\\":[],\\"onProgress\\":null,\\"unbundle\\":false}"`;
|
||||
exports[`processRequest Generate delta bundle endpoint should send the correct deltaBundlerId to the bundler 1`] = `"{\\"sourceMapUrl\\":null,\\"bundleType\\":null,\\"customTransformOptions\\":{},\\"entryFile\\":\\"/root/index.js\\",\\"deltaBundleId\\":null,\\"dev\\":true,\\"minify\\":false,\\"excludeSource\\":null,\\"hot\\":true,\\"runBeforeMainModule\\":[\\"InitializeCore\\"],\\"runModule\\":true,\\"inlineSourceMap\\":false,\\"isolateModuleIDs\\":false,\\"platform\\":\\"ios\\",\\"resolutionResponse\\":null,\\"entryModuleOnly\\":false,\\"assetPlugins\\":[],\\"onProgress\\":null,\\"unbundle\\":false}"`;
|
||||
|
|
|
@ -69,6 +69,7 @@ type ResolveSync = (path: string, opts: ?{baseDir?: string}) => string;
|
|||
type GraphInfo = {|
|
||||
graph: Graph,
|
||||
prepend: $ReadOnlyArray<DependencyEdge>,
|
||||
lastModified: Date,
|
||||
|};
|
||||
|
||||
function debounceAndBatch(fn, delay) {
|
||||
|
@ -125,6 +126,7 @@ class Server {
|
|||
_platforms: Set<string>;
|
||||
_nextBundleBuildID: number;
|
||||
_deltaBundler: DeltaBundler;
|
||||
_graphs: Map<string, GraphInfo> = new Map();
|
||||
|
||||
constructor(options: Options) {
|
||||
const reporter =
|
||||
|
@ -353,9 +355,37 @@ class Server {
|
|||
return {
|
||||
prepend,
|
||||
graph,
|
||||
lastModified: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
async _getGraphInfo(
|
||||
options: BundleOptions,
|
||||
{rebuild}: {rebuild: boolean},
|
||||
): Promise<{...GraphInfo, numModifiedFiles: number}> {
|
||||
const id = this._optionsHash(options);
|
||||
let graphInfo = this._graphs.get(id);
|
||||
let numModifiedFiles = 0;
|
||||
|
||||
if (!graphInfo) {
|
||||
graphInfo = await this._buildGraph(options);
|
||||
this._graphs.set(id, graphInfo);
|
||||
numModifiedFiles =
|
||||
graphInfo.prepend.length + graphInfo.graph.dependencies.size;
|
||||
} else if (rebuild) {
|
||||
const delta = await this._deltaBundler.getDelta(graphInfo.graph, {
|
||||
reset: false,
|
||||
});
|
||||
numModifiedFiles = delta.modified.size;
|
||||
|
||||
if (numModifiedFiles > 0) {
|
||||
graphInfo.lastModified = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
return {...graphInfo, numModifiedFiles};
|
||||
}
|
||||
|
||||
async _minifyModule(module: DependencyEdge): Promise<DependencyEdge> {
|
||||
const {code, map} = await this._bundler.minifyModule(
|
||||
module.path,
|
||||
|
@ -487,6 +517,7 @@ class Server {
|
|||
// List of option parameters that won't affect the build result, so they
|
||||
// can be ignored to calculate the options hash.
|
||||
const ignoredParams = {
|
||||
bundleType: null,
|
||||
onProgress: null,
|
||||
deltaBundleId: null,
|
||||
excludeSource: null,
|
||||
|
@ -649,7 +680,24 @@ class Server {
|
|||
let result;
|
||||
|
||||
try {
|
||||
result = await Serializers.fullBundle(this._deltaBundler, options);
|
||||
const {
|
||||
graph,
|
||||
prepend,
|
||||
lastModified,
|
||||
numModifiedFiles,
|
||||
} = await this._getGraphInfo(options, {rebuild: true});
|
||||
|
||||
result = {
|
||||
bundle: plainJSBundle(options.entryFile, prepend, graph, {
|
||||
createModuleId: this._opts.createModuleId,
|
||||
dev: options.dev,
|
||||
runBeforeMainModule: options.runBeforeMainModule,
|
||||
runModule: options.runModule,
|
||||
sourceMapUrl: options.sourceMapUrl,
|
||||
}),
|
||||
numModifiedFiles,
|
||||
lastModified,
|
||||
};
|
||||
} catch (error) {
|
||||
this._handleError(mres, this._optionsHash(options), error);
|
||||
|
||||
|
@ -713,7 +761,13 @@ class Server {
|
|||
let sourceMap;
|
||||
|
||||
try {
|
||||
sourceMap = await Serializers.fullSourceMap(this._deltaBundler, options);
|
||||
const {graph, prepend} = await this._getGraphInfo(options, {
|
||||
rebuild: false,
|
||||
});
|
||||
|
||||
sourceMap = sourceMapString(prepend, graph, {
|
||||
excludeSource: options.excludeSource,
|
||||
});
|
||||
} catch (error) {
|
||||
this._handleError(mres, this._optionsHash(options), error);
|
||||
|
||||
|
|
Loading…
Reference in New Issue