mirror of https://github.com/status-im/metro.git
Add utilities for bundle creation
Summary: Adds utilities needed for bundle creation: `completeModuleWrapper` appends numeric IDs for the module itself and its dependencies to a module wrapped. `createGetModuleId` returns a function that returns sequential numeric IDs for strings, and is idempotent. Reviewed By: cpojer Differential Revision: D4240334 fbshipit-source-id: c165482ebcf0e81ebb83ba6ff634de095ffb6bf0
This commit is contained in:
parent
269d1e10fa
commit
2151936b80
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2016-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.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
jest.disableAutomock();
|
||||||
|
|
||||||
|
const {match} = require('sinon');
|
||||||
|
const {fn} = require('../../test-helpers');
|
||||||
|
const {
|
||||||
|
addModuleIdsToModuleWrapper,
|
||||||
|
createIdForPathFn,
|
||||||
|
} = require('../util');
|
||||||
|
|
||||||
|
const {any} = jasmine;
|
||||||
|
|
||||||
|
describe('`addModuleIdsToModuleWrapper`:', () => {
|
||||||
|
const path = 'path/to/file';
|
||||||
|
const createModule = (dependencies = []) => ({
|
||||||
|
dependencies,
|
||||||
|
file: {code: '__d(function(){});', isModule: true, path},
|
||||||
|
});
|
||||||
|
|
||||||
|
it('completes the module wrapped with module ID, and an array of dependency IDs', () => {
|
||||||
|
const dependencies = [
|
||||||
|
{id: 'a', path: 'path/to/a.js'},
|
||||||
|
{id: 'b', path: 'location/of/b.js'},
|
||||||
|
];
|
||||||
|
const module = createModule(dependencies);
|
||||||
|
|
||||||
|
const idForPath = fn();
|
||||||
|
idForPath.stub
|
||||||
|
.withArgs(match({path})).returns(12)
|
||||||
|
.withArgs(match({path: dependencies[0].path})).returns(345)
|
||||||
|
.withArgs(match({path: dependencies[1].path})).returns(6);
|
||||||
|
|
||||||
|
expect(addModuleIdsToModuleWrapper(module, idForPath))
|
||||||
|
.toEqual('__d(function(){}, 12, [345, 6]);');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('omits the array of dependency IDs if it is empty', () => {
|
||||||
|
const module = createModule();
|
||||||
|
expect(addModuleIdsToModuleWrapper(module, () => 98))
|
||||||
|
.toEqual(`__d(function(){}, ${98});`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('`createIdForPathFn`', () => {
|
||||||
|
let idForPath;
|
||||||
|
beforeEach(() => {
|
||||||
|
idForPath = createIdForPathFn();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a number for a string', () => {
|
||||||
|
expect(idForPath({path: 'arbitrary'})).toEqual(any(Number));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns consecutive numbers', () => {
|
||||||
|
const strings = [
|
||||||
|
'arbitrary string',
|
||||||
|
'looking/like/a/path',
|
||||||
|
'/absolute/path/to/file.js',
|
||||||
|
'/more files/are here',
|
||||||
|
];
|
||||||
|
|
||||||
|
strings.forEach((string, i) => {
|
||||||
|
expect(idForPath({path: string})).toEqual(i);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the same id if the same string is passed in again', () => {
|
||||||
|
const path = 'this/is/an/arbitrary/path.js';
|
||||||
|
const id = idForPath({path});
|
||||||
|
idForPath({path: '/other/file'});
|
||||||
|
idForPath({path: 'and/another/file'});
|
||||||
|
expect(idForPath({path})).toEqual(id);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2016-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
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import type {Module} from '../types.flow';
|
||||||
|
|
||||||
|
// Transformed modules have the form
|
||||||
|
// __d(function(require, module, global, exports, dependencyMap) {
|
||||||
|
// /* code */
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// This function adds the numeric module ID, and an array with dependencies of
|
||||||
|
// the dependencies of the module before the closing parenthesis.
|
||||||
|
exports.addModuleIdsToModuleWrapper = (
|
||||||
|
module: Module,
|
||||||
|
idForPath: {path: string} => number,
|
||||||
|
): string => {
|
||||||
|
const {dependencies, file} = module;
|
||||||
|
const {code} = file;
|
||||||
|
const index = code.lastIndexOf(')');
|
||||||
|
const depencyIds =
|
||||||
|
dependencies.length ? `, [${dependencies.map(idForPath).join(', ')}]` : '';
|
||||||
|
return (
|
||||||
|
code.slice(0, index) +
|
||||||
|
`, ${idForPath(file)}` +
|
||||||
|
depencyIds +
|
||||||
|
code.slice(index)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates an idempotent function that returns numeric IDs for objects based
|
||||||
|
// on their `path` property.
|
||||||
|
exports.createIdForPathFn = (): ({path: string} => number) => {
|
||||||
|
const seen = new Map();
|
||||||
|
let next = 0;
|
||||||
|
return ({path}) => {
|
||||||
|
let id = seen.get(path);
|
||||||
|
if (id == null) {
|
||||||
|
id = next++;
|
||||||
|
seen.set(path, id);
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue