diff --git a/package.json b/package.json index 4e3811dbd..f372f7882 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,9 @@ "underscore": "1.7.0", "worker-farm": "1.1.0", "ws": "0.4.31", - "yargs": "1.3.2" + "yargs": "1.3.2", + "bluebird": "^2.9.21", + "image-size": "0.3.5" }, "devDependencies": { "jest-cli": "0.2.1", diff --git a/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js b/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js index c56593cfa..c46a57e60 100644 --- a/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js +++ b/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js @@ -30,8 +30,13 @@ function ModuleDescriptor(fields) { this.isPolyfill = fields.isPolyfill || false; + this.isAsset_DEPRECATED = fields.isAsset_DEPRECATED || 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._fields = fields; diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js index b6a978c63..f42f6f8a1 100644 --- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js +++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js @@ -92,7 +92,7 @@ describe('DependencyGraph', function() { { id: 'image!a', path: '/root/imgs/a.png', dependencies: [], - isAsset: true + isAsset_DEPRECATED: true }, ]); }); @@ -183,7 +183,7 @@ describe('DependencyGraph', function() { id: 'image!a', path: '/root/imgs/a.png', dependencies: [], - isAsset: true + isAsset_DEPRECATED: true }, ]); }); @@ -954,7 +954,7 @@ describe('DependencyGraph', function() { { id: 'image!foo', path: '/root/foo.png', dependencies: [], - isAsset: true, + isAsset_DEPRECATED: true, }, ]); }); diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js index 3348907f1..fbc7de712 100644 --- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js +++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js @@ -596,7 +596,7 @@ DependecyGraph.prototype._processAsset_DEPRECATED = function(file) { this._assetMap_DEPRECATED[name] = new ModuleDescriptor({ id: 'image!' + name, path: path.resolve(file), - isAsset: true, + isAsset_DEPRECATED: true, dependencies: [], }); } diff --git a/packager/react-packager/src/Packager/__tests__/Packager-test.js b/packager/react-packager/src/Packager/__tests__/Packager-test.js index 8f61df972..f4675c471 100644 --- a/packager/react-packager/src/Packager/__tests__/Packager-test.js +++ b/packager/react-packager/src/Packager/__tests__/Packager-test.js @@ -43,14 +43,21 @@ describe('Packager', function() { }; }); - var packager = new Packager({projectRoots: []}); + var packager = new Packager({projectRoots: ['/root']}); var modules = [ {id: 'foo', path: '/root/foo.js', dependencies: []}, {id: 'bar', path: '/root/bar.js', dependencies: []}, - { id: 'image!img', + { + id: 'image!img', path: '/root/img/img.png', - isAsset: true, + isAsset_DEPRECATED: true, 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'; }); + require('image-size').mockImpl(function(path, cb) { + cb(null, { width: 50, height: 100 }); + }); + return packager.package('/root/foo.js', true, 'source_map_url') .then(function(p) { expect(p.addModule.mock.calls[0]).toEqual([ @@ -96,6 +107,24 @@ describe('Packager', function() { '/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([ {runMainModule: true} ]); diff --git a/packager/react-packager/src/Packager/index.js b/packager/react-packager/src/Packager/index.js index bf5a635da..cfdd842db 100644 --- a/packager/react-packager/src/Packager/index.js +++ b/packager/react-packager/src/Packager/index.js @@ -18,6 +18,7 @@ var _ = require('underscore'); var Package = require('./Package'); var Activity = require('../Activity'); var declareOpts = require('../lib/declareOpts'); +var imageSize = require('image-size'); var validateOpts = declareOpts({ projectRoots: { @@ -88,6 +89,8 @@ function Packager(options) { transformModulePath: opts.transformModulePath, nonPersistent: opts.nonPersistent, }); + + this._projectRoots = opts.projectRoots; } Packager.prototype.kill = function() { @@ -138,8 +141,13 @@ Packager.prototype.getDependencies = function(main, isDev) { Packager.prototype._transformModule = function(module) { var transform; - if (module.isAsset) { - transform = Promise.resolve(generateAssetModule(module)); + if (module.isAsset_DEPRECATED) { + transform = Promise.resolve(generateAssetModule_DEPRECATED(module)); + } else if (module.isAsset) { + transform = generateAssetModule( + module, + getPathRelativeToRoot(this._projectRoots, module.path) + ); } else { transform = this._transformer.loadFileAndTransform( path.resolve(module.path) @@ -166,7 +174,7 @@ Packager.prototype.getGraphDebugInfo = function() { return this._resolver.getDebugInfo(); }; -function generateAssetModule(module) { +function generateAssetModule_DEPRECATED(module) { var code = 'module.exports = ' + JSON.stringify({ uri: module.id.replace(/^[^!]+!/, ''), 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;