react-native/local-cli/bundle/saveAssets.js
Sebastian Markbage 43f18ffd08 Add infra for Prepack build option
Summary: This adds a build option for using Prepack (an experimental packager) to
build a bundle. It doesn't actually take on the npm package dependency
because it's not published/open source (yet).

This will be used while we experiment and should be maintained as the
build system changes so that we can continue getting fresh builds.

I found that saveBundleAndMap and processBundle were over abstracted and
got in my way so I inlined it and removed the unit tests because the unit
test was testing trivial code that is likely to change interface.

I went with a separate build phase and a separate Bundle class even though
there are a lot of commonalities. I imagine that the requirements for
Prepack will continue to diverge. Especially for source maps but a larger
refactor could try to unify these a bit more. The fact that modules are
wrapped before the write phase seems to be an unfortunate architecture
that makes this difficult.
Closes https://github.com/facebook/react-native/pull/4226

Reviewed By: amasad

Differential Revision: D2673760

Pulled By: sebmarkbage

fb-gh-sync-id: 299ccc42e4be1d9dee19ade443ea3388db2e39a8
2015-11-20 20:19:25 -08:00

84 lines
2.1 KiB
JavaScript

/**
* Copyright (c) 2015-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';
const execFile = require('child_process').execFile;
const fs = require('fs');
const getAssetDestPathAndroid = require('./getAssetDestPathAndroid');
const getAssetDestPathIOS = require('./getAssetDestPathIOS');
const log = require('../util/log').out('bundle');
const path = require('path');
function saveAssets(
assets,
platform,
assetsDest
) {
if (!assetsDest) {
console.warn('Assets destination folder is not set, skipping...');
return Promise.resolve();
}
const getAssetDestPath = platform === 'android'
? getAssetDestPathAndroid
: getAssetDestPathIOS;
const filesToCopy = Object.create(null); // Map src -> dest
assets
.filter(asset => !asset.deprecated)
.forEach(asset =>
asset.scales.forEach((scale, idx) => {
const src = asset.files[idx];
const dest = path.join(assetsDest, getAssetDestPath(asset, scale));
filesToCopy[src] = dest;
})
);
return copyAll(filesToCopy);
}
function copyAll(filesToCopy) {
const queue = Object.keys(filesToCopy);
if (queue.length === 0) {
return Promise.resolve();
}
log('Copying ' + queue.length + ' asset files');
return new Promise((resolve, reject) => {
const copyNext = (error) => {
if (error) {
return reject(error);
}
if (queue.length === 0) {
log('Done copying assets');
resolve();
} else {
const src = queue.shift();
const dest = filesToCopy[src];
copy(src, dest, copyNext);
}
};
copyNext();
});
}
function copy(src, dest, callback) {
const destDir = path.dirname(dest);
execFile('mkdir', ['-p', destDir], err => {
if (err) {
return callback(err);
}
fs.createReadStream(src)
.pipe(fs.createWriteStream(dest))
.on('finish', callback);
});
}
module.exports = saveAssets;