Skip to content

Commit eda09f8

Browse files
davidaurelioFacebook Github Bot
authored and
Facebook Github Bot
committed
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
1 parent da079f7 commit eda09f8

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Copyright (c) 2016-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
'use strict';
10+
11+
jest.disableAutomock();
12+
13+
const {match} = require('sinon');
14+
const {fn} = require('../../test-helpers');
15+
const {
16+
addModuleIdsToModuleWrapper,
17+
createIdForPathFn,
18+
} = require('../util');
19+
20+
const {any} = jasmine;
21+
22+
describe('`addModuleIdsToModuleWrapper`:', () => {
23+
const path = 'path/to/file';
24+
const createModule = (dependencies = []) => ({
25+
dependencies,
26+
file: {code: '__d(function(){});', isModule: true, path},
27+
});
28+
29+
it('completes the module wrapped with module ID, and an array of dependency IDs', () => {
30+
const dependencies = [
31+
{id: 'a', path: 'path/to/a.js'},
32+
{id: 'b', path: 'location/of/b.js'},
33+
];
34+
const module = createModule(dependencies);
35+
36+
const idForPath = fn();
37+
idForPath.stub
38+
.withArgs(match({path})).returns(12)
39+
.withArgs(match({path: dependencies[0].path})).returns(345)
40+
.withArgs(match({path: dependencies[1].path})).returns(6);
41+
42+
expect(addModuleIdsToModuleWrapper(module, idForPath))
43+
.toEqual('__d(function(){}, 12, [345, 6]);');
44+
});
45+
46+
it('omits the array of dependency IDs if it is empty', () => {
47+
const module = createModule();
48+
expect(addModuleIdsToModuleWrapper(module, () => 98))
49+
.toEqual(`__d(function(){}, ${98});`);
50+
});
51+
});
52+
53+
describe('`createIdForPathFn`', () => {
54+
let idForPath;
55+
beforeEach(() => {
56+
idForPath = createIdForPathFn();
57+
});
58+
59+
it('returns a number for a string', () => {
60+
expect(idForPath({path: 'arbitrary'})).toEqual(any(Number));
61+
});
62+
63+
it('returns consecutive numbers', () => {
64+
const strings = [
65+
'arbitrary string',
66+
'looking/like/a/path',
67+
'/absolute/path/to/file.js',
68+
'/more files/are here',
69+
];
70+
71+
strings.forEach((string, i) => {
72+
expect(idForPath({path: string})).toEqual(i);
73+
});
74+
});
75+
76+
it('returns the same id if the same string is passed in again', () => {
77+
const path = 'this/is/an/arbitrary/path.js';
78+
const id = idForPath({path});
79+
idForPath({path: '/other/file'});
80+
idForPath({path: 'and/another/file'});
81+
expect(idForPath({path})).toEqual(id);
82+
});
83+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright (c) 2016-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
* @flow
10+
*/
11+
'use strict';
12+
13+
import type {Module} from '../types.flow';
14+
15+
// Transformed modules have the form
16+
// __d(function(require, module, global, exports, dependencyMap) {
17+
// /* code */
18+
// });
19+
//
20+
// This function adds the numeric module ID, and an array with dependencies of
21+
// the dependencies of the module before the closing parenthesis.
22+
exports.addModuleIdsToModuleWrapper = (
23+
module: Module,
24+
idForPath: {path: string} => number,
25+
): string => {
26+
const {dependencies, file} = module;
27+
const {code} = file;
28+
const index = code.lastIndexOf(')');
29+
const depencyIds =
30+
dependencies.length ? `, [${dependencies.map(idForPath).join(', ')}]` : '';
31+
return (
32+
code.slice(0, index) +
33+
`, ${idForPath(file)}` +
34+
depencyIds +
35+
code.slice(index)
36+
);
37+
};
38+
39+
// Creates an idempotent function that returns numeric IDs for objects based
40+
// on their `path` property.
41+
exports.createIdForPathFn = (): ({path: string} => number) => {
42+
const seen = new Map();
43+
let next = 0;
44+
return ({path}) => {
45+
let id = seen.get(path);
46+
if (id == null) {
47+
id = next++;
48+
seen.set(path, id);
49+
}
50+
return id;
51+
};
52+
};

0 commit comments

Comments
 (0)