Remove old wrapping logic

Reviewed By: davidaurelio

Differential Revision: D6439155

fbshipit-source-id: 3332b9c7952c90411d0c595f184f92aeffd4ddd2
This commit is contained in:
Rafael Oleza 2017-12-04 16:36:49 -08:00 committed by Facebook Github Bot
parent 8c43848a1e
commit 5c06a80fd7
7 changed files with 31 additions and 519 deletions

View File

@ -105,63 +105,4 @@ describe('Bundler', function() {
});
expect(b._opts.platforms).toEqual(['android', 'vr']);
});
it('.generateAssetObjAndCode', async () => {
const mockAsset = {
__packager_asset: true,
fileSystemLocation: '/root/img',
scales: [1, 2, 3],
files: [
'/root/img/img.png',
'/root/img/img@2x.png',
'/root/img/img@3x.png',
],
hash: 'i am a hash',
height: 100,
httpServerLocation: '/assets/img',
name: 'img',
type: 'png',
width: 50,
};
assetServer.getAssetData.mockImplementation(() =>
Promise.resolve(mockAsset),
);
jest.mock(
'mockPlugin1',
() => {
return asset => {
asset.extraReverseHash = asset.hash
.split('')
.reverse()
.join('');
return asset;
};
},
{virtual: true},
);
jest.mock(
'asyncMockPlugin2',
() => {
return asset => {
expect(asset.extraReverseHash).toBeDefined();
return new Promise(resolve => {
asset.extraPixelCount = asset.width * asset.height;
resolve(asset);
});
};
},
{virtual: true},
);
expect(
await bundler.generateAssetObjAndCode(
{},
['mockPlugin1', 'asyncMockPlugin2'],
'ios',
),
).toMatchSnapshot();
});
});

View File

@ -1,38 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Bundler .generateAssetObjAndCode 1`] = `
Object {
"asset": Object {
"__packager_asset": true,
"extraPixelCount": 5000,
"extraReverseHash": "hsah a ma i",
"fileSystemLocation": "/root/img",
"files": Array [
"/root/img/img.png",
"/root/img/img@2x.png",
"/root/img/img@3x.png",
],
"hash": "i am a hash",
"height": 100,
"httpServerLocation": "/assets/img",
"name": "img",
"scales": Array [
1,
2,
3,
],
"type": "png",
"width": 50,
},
"code": "module.exports=require(\\"/AssetRegistry.js\\").registerAsset({\\"__packager_asset\\":true,\\"scales\\":[1,2,3],\\"hash\\":\\"i am a hash\\",\\"height\\":100,\\"httpServerLocation\\":\\"/assets/img\\",\\"name\\":\\"img\\",\\"type\\":\\"png\\",\\"width\\":50,\\"extraReverseHash\\":\\"hsah a ma i\\",\\"extraPixelCount\\":5000});",
"meta": Object {
"dependencies": Array [
"/AssetRegistry.js",
],
"dependencyOffsets": Array [
23,
],
"preloaded": null,
},
}
`;

View File

@ -22,8 +22,6 @@ const path = require('path');
const defaults = require('../defaults');
const createModuleIdFactory = require('../lib/createModuleIdFactory');
const {generateAssetTransformResult} = require('./util');
const {sep: pathSeparator} = require('path');
const VERSION = require('../../package.json').version;
@ -242,51 +240,6 @@ class Bundler {
);
}
async generateAssetObjAndCode(
path: string,
assetPlugins: Array<string>,
platform: ?string = null,
) {
const assetData = await this._assetServer.getAssetData(path, platform);
const asset = await this._applyAssetPlugins(assetPlugins, assetData);
const {
code,
dependencies,
dependencyOffsets,
} = generateAssetTransformResult(this._opts.assetRegistryPath, asset);
return {
asset,
code,
meta: {dependencies, dependencyOffsets, preloaded: null},
};
}
_applyAssetPlugins(
assetPlugins: Array<string>,
asset: ExtendedAssetDescriptor,
) {
if (!assetPlugins.length) {
return asset;
}
const [currentAssetPlugin, ...remainingAssetPlugins] = assetPlugins;
/* $FlowFixMe: dynamic requires prevent static typing :'( */
const assetPluginFunction = require(currentAssetPlugin);
const result = assetPluginFunction(asset);
// If the plugin was an async function, wait for it to fulfill before
// applying the remaining plugins
if (typeof result.then === 'function') {
return result.then(resultAsset =>
this._applyAssetPlugins(remainingAssetPlugins, resultAsset),
);
} else {
return this._applyAssetPlugins(remainingAssetPlugins, result);
}
}
/**
* Returns the transform options related to a specific entry file, by calling
* the config parameter getTransformOptions().

View File

@ -160,23 +160,6 @@ function generateRemoteAssetCodeFileAst(
);
}
function generateAssetTransformResult(
assetRegistryPath: string,
assetDescriptor: ExtendedAssetDescriptor,
): {|
code: string,
dependencies: Array<string>,
dependencyOffsets: Array<number>,
|} {
const {code} = babelGenerate(
generateAssetCodeFileAst(assetRegistryPath, assetDescriptor),
{comments: false, compact: true},
);
const dependencies = [assetRegistryPath];
const dependencyOffsets = [code.indexOf(assetRegistryPath) - 1];
return {code, dependencies, dependencyOffsets};
}
// Test extension against all types supported by image-size module.
// If it's not one of these, we won't treat it as an image.
function isAssetTypeAnImage(type: string): boolean {
@ -272,7 +255,6 @@ class ArrayMap<K, V> extends Map<K, Array<V>> {
module.exports = {
createRamBundleGroups,
generateAssetCodeFileAst,
generateAssetTransformResult,
generateRemoteAssetCodeFileAst,
isAssetTypeAnImage,
};

View File

@ -505,38 +505,6 @@ class DeltaTransformer extends EventEmitter {
return addParamsToDefineCall(code, ...params);
}
/**
* Temporary function to wrap an asset. This logic will go away once we
* generate the needed JS code for assets in the transformer.
*/
async _wrapAsset({
code,
dependencyPairs,
name,
path,
}: {
code: string,
dependencyPairs: Map<string, string>,
name: string,
path: string,
}): Promise<string> {
const asset = await this._bundler.generateAssetObjAndCode(
path,
this._bundleOptions.assetPlugins,
this._bundleOptions.platform,
);
return await this._resolver.wrapModule({
path,
getModuleId: this._getModuleId,
dependencyPairs,
dependencyOffsets: asset.meta.dependencyOffsets,
name,
code: asset.code,
dev: this._bundleOptions.dev,
});
}
_getModuleType(module: Module): DeltaEntryType {
if (module.isAsset()) {
return 'asset';

View File

@ -19,7 +19,6 @@ jest.mock('path');
const DependencyGraph = jest.fn();
jest.setMock('../../node-haste/DependencyGraph', DependencyGraph);
let Module;
let Polyfill;
describe('Resolver', function() {
let Resolver, path;
@ -28,21 +27,16 @@ describe('Resolver', function() {
Resolver = require('../');
path = require('path');
DependencyGraph.mockClear();
Module = jest.fn(function() {
this.getName = jest.fn();
this.getDependencies = jest.fn();
this.isPolyfill = jest.fn().mockReturnValue(false);
this.isJSON = jest.fn().mockReturnValue(false);
});
Polyfill = jest.fn(function() {
var polyfill = new Module();
polyfill.isPolyfill.mockReturnValue(true);
return polyfill;
});
DependencyGraph.load = jest
.fn()
.mockImplementation(opts => Promise.resolve(new DependencyGraph(opts)));
DependencyGraph.prototype.createPolyfill = jest.fn();
DependencyGraph.prototype.getDependencies = jest.fn();
@ -52,237 +46,53 @@ describe('Resolver', function() {
DependencyGraph.prototype.load = jest.fn(() => Promise.resolve());
});
class ResolutionResponseMock {
constructor({dependencies, mainModuleId}) {
this.dependencies = dependencies;
this.mainModuleId = mainModuleId;
this.getModuleId = createGetModuleId();
}
prependDependency(dependency) {
this.dependencies.unshift(dependency);
}
finalize() {
return Promise.resolve(this);
}
getResolvedDependencyPairs() {
return [];
}
}
function createModule(id, dependencies) {
var module = new Module({});
module.path = id;
module.getName.mockImplementation(() => Promise.resolve(id));
module.getDependencies.mockImplementation(() =>
Promise.resolve(dependencies),
);
return module;
}
function createJsonModule(id) {
const module = createModule(id, []);
module.isJSON.mockReturnValue(true);
return module;
}
describe('minification:', () => {
const code = 'arbitrary(code)';
const id = 'arbitrary.js';
let depResolver, minifyCode, module, sourceMap;
function createPolyfill(id, dependencies) {
var polyfill = new Polyfill({});
polyfill.getName = jest.fn(() => Promise.resolve(id));
polyfill.getDependencies = jest.fn(() => Promise.resolve(dependencies));
return polyfill;
}
describe('wrapModule', function() {
let depResolver;
beforeEach(() => {
minifyCode = jest.fn((filename, code, map) =>
Promise.resolve({code, map}),
);
module = createModule(id);
module.path = '/arbitrary/path.js';
sourceMap = [];
return Resolver.load({
projectRoot: '/root',
minifyCode,
postMinifyProcess: e => e,
}).then(r => {
depResolver = r;
});
});
it('should resolve modules', function() {
expect.assertions(1);
var code = [
// require
'require("x")',
'require("y");require(\'abc\');',
"require( 'z' )",
'require( "a")',
'require("b" )',
].join('\n');
/*eslint-disable */
function* findDependencyOffsets() {
const re = /(['"']).*?\1/g;
let match;
while ((match = re.exec(code))) {
yield match.index;
}
}
const dependencyOffsets = Array.from(findDependencyOffsets());
const module = createModule('test module', ['x', 'y']);
const resolutionResponse = new ResolutionResponseMock({
dependencies: [module],
mainModuleId: 'test module',
});
resolutionResponse.getResolvedDependencyPairs = module => {
return [
['x', createModule('changed')],
['y', createModule('Y')],
['abc', createModule('abc')],
];
it('should use minified code', () => {
expect.assertions(2);
const minifiedCode = 'minified(code)';
const minifiedMap = {
version: 3,
file: ['minified'],
sources: [],
mappings: '',
};
const moduleIds = new Map(
resolutionResponse
.getResolvedDependencyPairs()
.map(([importId, module]) => [
importId,
padRight(
resolutionResponse.getModuleId(module.path),
importId.length + 2,
),
]),
minifyCode.mockReturnValue(
Promise.resolve({code: minifiedCode, map: minifiedMap}),
);
const dependencyPairs = new Map();
for (const [
relativePath,
dependencyModule,
] of resolutionResponse.getResolvedDependencyPairs(module)) {
dependencyPairs.set(relativePath, dependencyModule.path);
}
const processedCode = depResolver.wrapModule({
path: module.path,
getModuleId: resolutionResponse.getModuleId,
dependencyPairs,
name: 'test module',
code,
dependencyOffsets,
dev: false,
});
expect(processedCode).toEqual(
[
'__d(/* test module */function(global, require, module, exports) {' +
// require
`require(${moduleIds.get('x')}) // ${moduleIds
.get('x')
.trim()} = x`,
`require(${moduleIds.get('y')});require(${moduleIds.get(
'abc',
)}); // ${moduleIds.get('abc').trim()} = abc // ${moduleIds
.get('y')
.trim()} = y`,
"require( 'z' )",
'require( "a")',
'require("b" )',
`}, ${resolutionResponse.getModuleId(module.path)});`,
].join('\n'),
);
});
it('should add module transport names as fourth argument to `__d`', () => {
expect.assertions(1);
const module = createModule('test module');
const code = 'arbitrary(code)';
const resolutionResponse = new ResolutionResponseMock({
dependencies: [module],
mainModuleId: 'test module',
});
const processedCode = depResolver.wrapModule({
getModuleId: resolutionResponse.getModuleId,
dependencyPairs: resolutionResponse.getResolvedDependencyPairs(module),
code,
path: module.path,
name: 'test module',
dev: true,
});
expect(processedCode).toEqual(
[
'__d(/* test module */function(global, require, module, exports) {' +
code,
`}, ${resolutionResponse.getModuleId(
module.path,
)}, null, "test module");`,
].join('\n'),
);
});
describe('minification:', () => {
const code = 'arbitrary(code)';
const id = 'arbitrary.js';
let depResolver, minifyCode, module, resolutionResponse, sourceMap;
beforeEach(() => {
minifyCode = jest.fn((filename, code, map) =>
Promise.resolve({code, map}),
);
module = createModule(id);
module.path = '/arbitrary/path.js';
resolutionResponse = new ResolutionResponseMock({
dependencies: [module],
mainModuleId: id,
return depResolver
.minifyModule(module.path, code, sourceMap)
.then(({code, map}) => {
expect(code).toEqual(minifiedCode);
expect(map).toEqual([]);
});
sourceMap = [];
return Resolver.load({
projectRoot: '/root',
minifyCode,
postMinifyProcess: e => e,
}).then(r => {
depResolver = r;
});
});
it('should use minified code', () => {
expect.assertions(2);
const minifiedCode = 'minified(code)';
const minifiedMap = {
version: 3,
file: ['minified'],
sources: [],
mappings: '',
};
minifyCode.mockReturnValue(
Promise.resolve({code: minifiedCode, map: minifiedMap}),
);
return depResolver
.minifyModule(module.path, code, sourceMap)
.then(({code, map}) => {
expect(code).toEqual(minifiedCode);
expect(map).toEqual([]);
});
});
});
});
function createGetModuleId() {
let nextId = 1;
const knownIds = new Map();
function createId(path) {
const id = nextId;
nextId += 1;
knownIds.set(path, id);
return id;
}
return path => knownIds.get(path) || createId(path);
}
function padRight(value, width) {
const s = String(value);
const diff = width - s.length;
return diff > 0 ? s + Array(diff + 1).join(' ') : s;
}
});

View File

@ -116,66 +116,6 @@ class Resolver {
);
}
resolveRequires(
getModuleId: (path: string) => number,
code: string,
dependencyPairs: Map<string, string>,
dependencyOffsets: Array<number> = [],
): string {
const resolvedDeps = Object.create(null);
// here, we build a map of all require strings (relative and absolute)
// to the canonical ID of the module they reference
for (const [name, path] of dependencyPairs) {
resolvedDeps[name] = getModuleId(path);
}
// if we have a canonical ID for the module imported here,
// we use it, so that require() is always called with the same
// id for every module.
// Example:
// -- in a/b.js:
// require('./c') => require(3);
// -- in b/index.js:
// require('../a/c') => require(3);
return dependencyOffsets
.reduceRight(
([unhandled, handled], offset) => [
unhandled.slice(0, offset),
replaceDependencyID(unhandled.slice(offset) + handled, resolvedDeps),
],
[code, ''],
)
.join('');
}
wrapModule({
path,
getModuleId,
dependencyPairs,
dependencyOffsets,
name,
code,
dev = true,
}: {
path: string,
getModuleId: (path: string) => number,
dependencyPairs: Map<string, string>,
dependencyOffsets: Array<number>,
name: string,
code: string,
dev?: boolean,
}): string {
code = this.resolveRequires(
getModuleId,
code,
dependencyPairs,
dependencyOffsets,
);
return defineModuleCode(getModuleId(path), code, name, dev);
}
async minifyModule(
path: string,
code: string,
@ -200,48 +140,4 @@ class Resolver {
}
}
function defineModuleCode(moduleName, code, verboseName = '', dev = true) {
return [
`__d(/* ${verboseName} */`,
'function(global, require, module, exports) {', // module factory
code,
'\n}, ',
`${JSON.stringify(moduleName)}`, // module id, null = id map. used in ModuleGraph
dev ? `, null, ${JSON.stringify(verboseName)}` : '',
');',
].join('');
}
function definePolyfillCode(code) {
return [
'(function(global) {',
code,
`\n})(typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this);`,
].join('');
}
const reDepencencyString = /^(['"])([^'"']*)\1/;
function replaceDependencyID(stringWithDependencyIDAtStart, resolvedDeps) {
const match = reDepencencyString.exec(stringWithDependencyIDAtStart);
const dependencyName = match && match[2];
if (match != null && dependencyName in resolvedDeps) {
const {length} = match[0];
const id = String(resolvedDeps[dependencyName]);
return (
padRight(id, length) +
stringWithDependencyIDAtStart
.slice(length)
.replace(/$/m, ` // ${id} = ${dependencyName}`)
);
} else {
return stringWithDependencyIDAtStart;
}
}
function padRight(string, length) {
return string.length < length
? string + Array(length - string.length + 1).join(' ')
: string;
}
module.exports = Resolver;