mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-05-11 10:38:00 +08:00
Add flow types for output modules
Summary: Adds flow types for output functionality for easier maintenance and interop with new code Reviewed By: matryoshcow Differential Revision: D4211863 fbshipit-source-id: 591407d3a6d49536054ae94ba31125c18a1e1fa1
This commit is contained in:
committed by
Facebook Github Bot
parent
9712d335e2
commit
f3779502d3
@@ -5,6 +5,8 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
@@ -18,6 +20,9 @@ const writeSourceMap = require('./write-sourcemap');
|
||||
|
||||
const {joinModules} = require('./util');
|
||||
|
||||
import type Bundle from '../../../../packager/react-packager/src/Bundler/Bundle';
|
||||
import type {OutputOptions} from '../../types.flow';
|
||||
|
||||
// must not start with a dot, as that won't go into the apk
|
||||
const MAGIC_UNBUNDLE_FILENAME = 'UNBUNDLE';
|
||||
const MODULES_DIR = 'js-modules';
|
||||
@@ -29,7 +34,11 @@ const MODULES_DIR = 'js-modules';
|
||||
* All other modules go into a 'js-modules' folder that in the same parent
|
||||
* directory as the startup file.
|
||||
*/
|
||||
function saveAsAssets(bundle, options, log) {
|
||||
function saveAsAssets(
|
||||
bundle: Bundle,
|
||||
options: OutputOptions,
|
||||
log: (x: string) => void,
|
||||
): Promise<mixed> {
|
||||
const {
|
||||
bundleOutput,
|
||||
bundleEncoding: encoding,
|
||||
@@ -54,11 +63,14 @@ function saveAsAssets(bundle, options, log) {
|
||||
writeUnbundle.then(() => log('Done writing unbundle output'));
|
||||
|
||||
const sourceMap =
|
||||
buildSourceMapWithMetaData({startupModules, lazyModules});
|
||||
buildSourceMapWithMetaData({
|
||||
startupModules: startupModules.concat(),
|
||||
lazyModules: lazyModules.concat(),
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
writeUnbundle,
|
||||
writeSourceMap(sourcemapOutput, JSON.stringify(sourceMap), log)
|
||||
sourcemapOutput && writeSourceMap(sourcemapOutput, JSON.stringify(sourceMap), log)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -80,8 +92,8 @@ function writeModules(modules, modulesDir, encoding) {
|
||||
|
||||
function writeMagicFlagFile(outputDir) {
|
||||
/* global Buffer: true */
|
||||
const buffer = Buffer(4);
|
||||
buffer.writeUInt32LE(MAGIC_UNBUNDLE_NUMBER);
|
||||
const buffer = new Buffer(4);
|
||||
buffer.writeUInt32LE(MAGIC_UNBUNDLE_NUMBER, 0);
|
||||
return writeFile(path.join(outputDir, MAGIC_UNBUNDLE_FILENAME), buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
@@ -15,6 +17,10 @@ const fs = require('fs');
|
||||
const writeSourceMap = require('./write-sourcemap');
|
||||
|
||||
const {joinModules} = require('./util');
|
||||
|
||||
import type ModuleTransport from '../../../../packager/react-packager/src/lib/ModuleTransport';
|
||||
import type {Bundle, ModuleGroups, OutputOptions} from '../../types.flow';
|
||||
|
||||
const SIZEOF_UINT32 = 4;
|
||||
|
||||
/**
|
||||
@@ -24,18 +30,22 @@ const SIZEOF_UINT32 = 4;
|
||||
* The module id for the startup code (prelude, polyfills etc.) is the
|
||||
* empty string.
|
||||
*/
|
||||
function saveAsIndexedFile(bundle, options, log) {
|
||||
function saveAsIndexedFile(
|
||||
bundle: Bundle,
|
||||
options: OutputOptions,
|
||||
log: (x: string) => void,
|
||||
): Promise<> {
|
||||
const {
|
||||
bundleOutput,
|
||||
bundleEncoding: encoding,
|
||||
sourcemapOutput
|
||||
sourcemapOutput,
|
||||
} = options;
|
||||
|
||||
log('start');
|
||||
const {startupModules, lazyModules, groups} = bundle.getUnbundle();
|
||||
log('finish');
|
||||
|
||||
const moduleGroups = ModuleGroups(groups, lazyModules);
|
||||
const moduleGroups = createModuleGroups(groups, lazyModules);
|
||||
const startupCode = joinModules(startupModules);
|
||||
|
||||
log('Writing unbundle output to:', bundleOutput);
|
||||
@@ -45,21 +55,26 @@ function saveAsIndexedFile(bundle, options, log) {
|
||||
).then(() => log('Done writing unbundle output'));
|
||||
|
||||
const sourceMap =
|
||||
buildSourceMapWithMetaData({startupModules, lazyModules, moduleGroups});
|
||||
buildSourceMapWithMetaData({
|
||||
startupModules: startupModules.concat(),
|
||||
lazyModules: lazyModules.concat(),
|
||||
moduleGroups,
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
writeUnbundle,
|
||||
writeSourceMap(sourcemapOutput, JSON.stringify(sourceMap), log),
|
||||
sourcemapOutput && writeSourceMap(sourcemapOutput, JSON.stringify(sourceMap), log),
|
||||
]);
|
||||
}
|
||||
|
||||
/* global Buffer: true */
|
||||
|
||||
const fileHeader = Buffer(4);
|
||||
fileHeader.writeUInt32LE(MAGIC_UNBUNDLE_FILE_HEADER);
|
||||
const nullByteBuffer = Buffer(1).fill(0);
|
||||
const fileHeader = new Buffer(4);
|
||||
fileHeader.writeUInt32LE(MAGIC_UNBUNDLE_FILE_HEADER, 0);
|
||||
//$FlowIssue #14640206
|
||||
const nullByteBuffer: Buffer = new Buffer(1).fill(0);
|
||||
|
||||
function writeBuffers(stream, buffers) {
|
||||
function writeBuffers(stream, buffers: Array<Buffer>) {
|
||||
buffers.forEach(buffer => stream.write(buffer));
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on('error', reject);
|
||||
@@ -69,7 +84,7 @@ function writeBuffers(stream, buffers) {
|
||||
}
|
||||
|
||||
function nullTerminatedBuffer(contents, encoding) {
|
||||
return Buffer.concat([Buffer(contents, encoding), nullByteBuffer]);
|
||||
return Buffer.concat([new Buffer(contents, encoding), nullByteBuffer]);
|
||||
}
|
||||
|
||||
function moduleToBuffer(id, code, encoding) {
|
||||
@@ -98,7 +113,8 @@ function buildModuleTable(startupCode, buffers, moduleGroups) {
|
||||
const moduleIds = Array.from(moduleGroups.modulesById.keys());
|
||||
const maxId = moduleIds.reduce((max, id) => Math.max(max, id));
|
||||
const numEntries = maxId + 1;
|
||||
const table = new Buffer(entryOffset(numEntries)).fill(0);
|
||||
//$FlowIssue #14640206
|
||||
const table: Buffer = new Buffer(entryOffset(numEntries)).fill(0);
|
||||
|
||||
// num_entries
|
||||
table.writeUInt32LE(numEntries, 0);
|
||||
@@ -109,9 +125,8 @@ function buildModuleTable(startupCode, buffers, moduleGroups) {
|
||||
// entries
|
||||
let codeOffset = startupCode.length;
|
||||
buffers.forEach(({id, buffer}) => {
|
||||
const idsInGroup = moduleGroups.groups.has(id)
|
||||
? [id].concat(Array.from(moduleGroups.groups.get(id)))
|
||||
: [id];
|
||||
const group = moduleGroups.groups.get(id);
|
||||
const idsInGroup = group ? [id].concat(Array.from(group)) : [id];
|
||||
|
||||
idsInGroup.forEach(moduleId => {
|
||||
const offset = entryOffset(moduleId);
|
||||
@@ -132,7 +147,7 @@ function groupCode(rootCode, moduleGroup, modulesById) {
|
||||
}
|
||||
const code = [rootCode];
|
||||
for (const id of moduleGroup) {
|
||||
code.push(modulesById.get(id).code);
|
||||
code.push((modulesById.get(id) || {}).code);
|
||||
}
|
||||
|
||||
return code.join('\n');
|
||||
@@ -170,7 +185,10 @@ function buildTableAndContents(startupCode, modules, moduleGroups, encoding) {
|
||||
].concat(moduleBuffers.map(({buffer}) => buffer));
|
||||
}
|
||||
|
||||
function ModuleGroups(groups, modules) {
|
||||
function createModuleGroups(
|
||||
groups: Map<number, Set<number>>,
|
||||
modules: Array<ModuleTransport>,
|
||||
): ModuleGroups {
|
||||
return {
|
||||
groups,
|
||||
modulesById: new Map(modules.map(m => [m.id, m])),
|
||||
|
||||
@@ -5,14 +5,25 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const {combineSourceMaps, joinModules} = require('./util');
|
||||
|
||||
module.exports = ({startupModules, lazyModules, moduleGroups}) => {
|
||||
const startupModule = {
|
||||
import type {ModuleGroups, ModuleTransportLike} from '../../types.flow';
|
||||
|
||||
type Params = {
|
||||
lazyModules: Array<ModuleTransportLike>,
|
||||
moduleGroups?: ModuleGroups,
|
||||
startupModules: Array<ModuleTransportLike>,
|
||||
};
|
||||
|
||||
module.exports = ({startupModules, lazyModules, moduleGroups}: Params) => {
|
||||
const startupModule: ModuleTransportLike = {
|
||||
code: joinModules(startupModules),
|
||||
id: Number.MIN_SAFE_INTEGER,
|
||||
map: combineSourceMaps({modules: startupModules}),
|
||||
};
|
||||
return combineSourceMaps({
|
||||
|
||||
@@ -5,13 +5,19 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const asAssets = require('./as-assets');
|
||||
const asIndexedFile = require('./as-indexed-file');
|
||||
|
||||
function buildBundle(packagerClient, requestOptions) {
|
||||
import type Bundle from '../../../../packager/react-packager/src/Bundler/Bundle';
|
||||
import type Server from '../../../../packager/react-packager/src/Server';
|
||||
import type {OutputOptions, RequestOptions} from '../../types.flow';
|
||||
|
||||
function buildBundle(packagerClient: Server, requestOptions: RequestOptions) {
|
||||
return packagerClient.buildBundle({
|
||||
...requestOptions,
|
||||
unbundle: true,
|
||||
@@ -19,7 +25,11 @@ function buildBundle(packagerClient, requestOptions) {
|
||||
});
|
||||
}
|
||||
|
||||
function saveUnbundle(bundle, options, log) {
|
||||
function saveUnbundle(
|
||||
bundle: Bundle,
|
||||
options: OutputOptions,
|
||||
log: (x: string) => void,
|
||||
): Promise<mixed> {
|
||||
// we fork here depending on the platform:
|
||||
// while android is pretty good at loading individual assets, ios has a large
|
||||
// overhead when reading hundreds pf assets from disk
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -5,14 +5,19 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const newline = /\r\n?|\n|\u2028|\u2029/g;
|
||||
const countLines =
|
||||
string => (string.match(newline) || []).length + 1; // fastest implementation
|
||||
import type {ModuleGroups, ModuleTransportLike, SourceMap} from '../../types.flow';
|
||||
|
||||
function lineToLineSourceMap(source, filename) {
|
||||
const newline = /\r\n?|\n|\u2028|\u2029/g;
|
||||
// fastest implementation
|
||||
const countLines = (string: string) => (string.match(newline) || []).length + 1;
|
||||
|
||||
|
||||
function lineToLineSourceMap(source: string, filename: string = ''): SourceMap {
|
||||
// The first line mapping in our package is the base64vlq code for zeros (A).
|
||||
const firstLine = 'AAAA;';
|
||||
|
||||
@@ -21,34 +26,52 @@ function lineToLineSourceMap(source, filename) {
|
||||
const line = 'AACA;';
|
||||
|
||||
return {
|
||||
version: 3,
|
||||
sources: [filename],
|
||||
file: filename,
|
||||
mappings: firstLine + Array(countLines(source)).join(line),
|
||||
sources: [filename],
|
||||
names: [],
|
||||
version: 3,
|
||||
};
|
||||
}
|
||||
|
||||
const wrapperEnd = wrappedCode => wrappedCode.indexOf('{') + 1;
|
||||
|
||||
const Section = (line, column, map) => ({map, offset: {line, column}});
|
||||
const Section =
|
||||
(line: number, column: number, map: SourceMap) =>
|
||||
({map, offset: {line, column}});
|
||||
|
||||
function combineSourceMaps({modules, withCustomOffsets, moduleGroups}) {
|
||||
type CombineSourceMapsOptions = {
|
||||
moduleGroups?: ModuleGroups,
|
||||
modules: Array<ModuleTransportLike>,
|
||||
withCustomOffsets?: boolean,
|
||||
};
|
||||
|
||||
function combineSourceMaps({
|
||||
moduleGroups,
|
||||
modules,
|
||||
withCustomOffsets,
|
||||
}: CombineSourceMapsOptions): SourceMap {
|
||||
let offsets;
|
||||
const sections = [];
|
||||
const sourceMap = {
|
||||
version: 3,
|
||||
const sourceMap: Object = {
|
||||
file: '',
|
||||
sections,
|
||||
version: 3,
|
||||
};
|
||||
|
||||
|
||||
if (withCustomOffsets) {
|
||||
offsets = sourceMap.x_facebook_offsets = [];
|
||||
}
|
||||
|
||||
let line = 0;
|
||||
modules.forEach(({code, id, map, name}) => {
|
||||
modules.forEach(moduleTransport => {
|
||||
const {code, id, name} = moduleTransport;
|
||||
let column = 0;
|
||||
let hasOffset = false;
|
||||
let group;
|
||||
let groupLines = 0;
|
||||
let {map} = moduleTransport;
|
||||
|
||||
if (withCustomOffsets) {
|
||||
if (moduleGroups && moduleGroups.modulesInGroups.has(id)) {
|
||||
@@ -56,15 +79,19 @@ function combineSourceMaps({modules, withCustomOffsets, moduleGroups}) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (moduleGroups && moduleGroups.groups.has(id)) {
|
||||
group = moduleGroups.groups.get(id);
|
||||
const otherModules = Array.from(group).map(
|
||||
moduleId => moduleGroups.modulesById.get(moduleId));
|
||||
|
||||
group = moduleGroups && moduleGroups.groups.get(id);
|
||||
if (group && moduleGroups) {
|
||||
const {modulesById} = moduleGroups;
|
||||
const otherModules: Array<ModuleTransportLike> =
|
||||
Array.from(group || [])
|
||||
.map(moduleId => modulesById.get(moduleId))
|
||||
.filter(Boolean); // needed to appease flow
|
||||
otherModules.forEach(m => {
|
||||
groupLines += countLines(m.code);
|
||||
});
|
||||
map = combineSourceMaps({
|
||||
modules: [{code, id, map, name}].concat(otherModules),
|
||||
modules: [moduleTransport].concat(otherModules),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -85,7 +112,9 @@ function combineSourceMaps({modules, withCustomOffsets, moduleGroups}) {
|
||||
return sourceMap;
|
||||
}
|
||||
|
||||
const joinModules = modules => modules.map(m => m.code).join('\n');
|
||||
const joinModules =
|
||||
(modules: Array<*>): string =>
|
||||
modules.map(m => m.code).join('\n');
|
||||
|
||||
module.exports = {
|
||||
countLines,
|
||||
|
||||
@@ -5,12 +5,18 @@
|
||||
* 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
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const writeFile = require('../writeFile');
|
||||
|
||||
function writeSourcemap(fileName, contents, log) {
|
||||
function writeSourcemap(
|
||||
fileName: string,
|
||||
contents: string,
|
||||
log: (x: string) => void,
|
||||
): Promise<> {
|
||||
if (!fileName) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user