[react-packager] Implement new style asset packaging (with dimensions)

This commit is contained in:
Amjad Masad 2015-04-08 13:27:56 -07:00
parent 8a57c4e980
commit bd7b9da64a
6 changed files with 90 additions and 11 deletions

View File

@ -61,7 +61,9 @@
"underscore": "1.7.0", "underscore": "1.7.0",
"worker-farm": "1.1.0", "worker-farm": "1.1.0",
"ws": "0.4.31", "ws": "0.4.31",
"yargs": "1.3.2" "yargs": "1.3.2",
"bluebird": "^2.9.21",
"image-size": "0.3.5"
}, },
"devDependencies": { "devDependencies": {
"jest-cli": "0.2.1", "jest-cli": "0.2.1",

View File

@ -30,8 +30,13 @@ function ModuleDescriptor(fields) {
this.isPolyfill = fields.isPolyfill || false; this.isPolyfill = fields.isPolyfill || false;
this.isAsset_DEPRECATED = fields.isAsset_DEPRECATED || false;
this.isAsset = fields.isAsset || false; this.isAsset = fields.isAsset || false;
if (this.isAsset_DEPRECATED && this.isAsset) {
throw new Error('Cannot be an asset and a deprecated asset');
}
this.altId = fields.altId; this.altId = fields.altId;
this._fields = fields; this._fields = fields;

View File

@ -92,7 +92,7 @@ describe('DependencyGraph', function() {
{ id: 'image!a', { id: 'image!a',
path: '/root/imgs/a.png', path: '/root/imgs/a.png',
dependencies: [], dependencies: [],
isAsset: true isAsset_DEPRECATED: true
}, },
]); ]);
}); });
@ -183,7 +183,7 @@ describe('DependencyGraph', function() {
id: 'image!a', id: 'image!a',
path: '/root/imgs/a.png', path: '/root/imgs/a.png',
dependencies: [], dependencies: [],
isAsset: true isAsset_DEPRECATED: true
}, },
]); ]);
}); });
@ -954,7 +954,7 @@ describe('DependencyGraph', function() {
{ id: 'image!foo', { id: 'image!foo',
path: '/root/foo.png', path: '/root/foo.png',
dependencies: [], dependencies: [],
isAsset: true, isAsset_DEPRECATED: true,
}, },
]); ]);
}); });

View File

@ -596,7 +596,7 @@ DependecyGraph.prototype._processAsset_DEPRECATED = function(file) {
this._assetMap_DEPRECATED[name] = new ModuleDescriptor({ this._assetMap_DEPRECATED[name] = new ModuleDescriptor({
id: 'image!' + name, id: 'image!' + name,
path: path.resolve(file), path: path.resolve(file),
isAsset: true, isAsset_DEPRECATED: true,
dependencies: [], dependencies: [],
}); });
} }

View File

@ -43,14 +43,21 @@ describe('Packager', function() {
}; };
}); });
var packager = new Packager({projectRoots: []}); var packager = new Packager({projectRoots: ['/root']});
var modules = [ var modules = [
{id: 'foo', path: '/root/foo.js', dependencies: []}, {id: 'foo', path: '/root/foo.js', dependencies: []},
{id: 'bar', path: '/root/bar.js', dependencies: []}, {id: 'bar', path: '/root/bar.js', dependencies: []},
{ id: 'image!img', {
id: 'image!img',
path: '/root/img/img.png', path: '/root/img/img.png',
isAsset: true, isAsset_DEPRECATED: true,
dependencies: [], dependencies: [],
},
{
id: 'new_image.png',
path: '/root/img/new_image.png',
isAsset: true,
dependencies: []
} }
]; ];
@ -74,6 +81,10 @@ describe('Packager', function() {
return 'lol ' + code + ' lol'; return 'lol ' + code + ' lol';
}); });
require('image-size').mockImpl(function(path, cb) {
cb(null, { width: 50, height: 100 });
});
return packager.package('/root/foo.js', true, 'source_map_url') return packager.package('/root/foo.js', true, 'source_map_url')
.then(function(p) { .then(function(p) {
expect(p.addModule.mock.calls[0]).toEqual([ expect(p.addModule.mock.calls[0]).toEqual([
@ -96,6 +107,24 @@ describe('Packager', function() {
'/root/img/img.png' '/root/img/img.png'
]); ]);
var imgModule = {
isStatic: true,
path: '/root/img/new_image.png',
uri: 'img/new_image.png',
width: 50,
height: 100,
};
expect(p.addModule.mock.calls[3]).toEqual([
'lol module.exports = ' +
JSON.stringify(imgModule) +
'; lol',
'module.exports = ' +
JSON.stringify(imgModule) +
';',
'/root/img/new_image.png'
]);
expect(p.finalize.mock.calls[0]).toEqual([ expect(p.finalize.mock.calls[0]).toEqual([
{runMainModule: true} {runMainModule: true}
]); ]);

View File

@ -18,6 +18,7 @@ var _ = require('underscore');
var Package = require('./Package'); var Package = require('./Package');
var Activity = require('../Activity'); var Activity = require('../Activity');
var declareOpts = require('../lib/declareOpts'); var declareOpts = require('../lib/declareOpts');
var imageSize = require('image-size');
var validateOpts = declareOpts({ var validateOpts = declareOpts({
projectRoots: { projectRoots: {
@ -88,6 +89,8 @@ function Packager(options) {
transformModulePath: opts.transformModulePath, transformModulePath: opts.transformModulePath,
nonPersistent: opts.nonPersistent, nonPersistent: opts.nonPersistent,
}); });
this._projectRoots = opts.projectRoots;
} }
Packager.prototype.kill = function() { Packager.prototype.kill = function() {
@ -138,8 +141,13 @@ Packager.prototype.getDependencies = function(main, isDev) {
Packager.prototype._transformModule = function(module) { Packager.prototype._transformModule = function(module) {
var transform; var transform;
if (module.isAsset) { if (module.isAsset_DEPRECATED) {
transform = Promise.resolve(generateAssetModule(module)); transform = Promise.resolve(generateAssetModule_DEPRECATED(module));
} else if (module.isAsset) {
transform = generateAssetModule(
module,
getPathRelativeToRoot(this._projectRoots, module.path)
);
} else { } else {
transform = this._transformer.loadFileAndTransform( transform = this._transformer.loadFileAndTransform(
path.resolve(module.path) path.resolve(module.path)
@ -166,7 +174,7 @@ Packager.prototype.getGraphDebugInfo = function() {
return this._resolver.getDebugInfo(); return this._resolver.getDebugInfo();
}; };
function generateAssetModule(module) { function generateAssetModule_DEPRECATED(module) {
var code = 'module.exports = ' + JSON.stringify({ var code = 'module.exports = ' + JSON.stringify({
uri: module.id.replace(/^[^!]+!/, ''), uri: module.id.replace(/^[^!]+!/, ''),
isStatic: true, isStatic: true,
@ -179,4 +187,39 @@ function generateAssetModule(module) {
}; };
} }
var sizeOf = Promise.promisify(imageSize);
function generateAssetModule(module, relPath) {
return sizeOf(module.path).then(function(dimensions) {
var img = {
isStatic: true,
path: module.path, //TODO(amasad): this should be path inside tar file.
uri: relPath,
width: dimensions.width,
height: dimensions.height,
};
var code = 'module.exports = ' + JSON.stringify(img) + ';';
return {
code: code,
sourceCode: code,
sourcePath: module.path,
};
});
}
function getPathRelativeToRoot(roots, absPath) {
for (var i = 0; i < roots.length; i++) {
var relPath = path.relative(roots[i], absPath);
if (relPath[0] !== '.') {
return relPath;
}
}
throw new Error(
'Expected root module to be relative to one of the project roots'
);
}
module.exports = Packager; module.exports = Packager;