mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-05-19 19:39:54 +08:00
92 lines
3.9 KiB
JavaScript
92 lines
3.9 KiB
JavaScript
/*
|
|
* This script generates a hash of all the React Native bundled assets and writes it into
|
|
* into the APK. The hash in "updateCheck" requests to prevent downloading an identical
|
|
* update to the one already present in the binary.
|
|
*
|
|
* It first creates a snapshot of the contents in the resource directory by creating
|
|
* a map with the modified time of all the files in the directory. It then compares this
|
|
* snapshot with the one saved earlier in "recordFilesBeforeBundleCommand.js" to figure
|
|
* out which files were generated by the "react-native bundle" command. It then computes
|
|
* the hash for each file to generate a manifest, and then computes a hash over the entire
|
|
* manifest to generate the final hash, which is saved to the APK's assets directory.
|
|
*/
|
|
|
|
var crypto = require("crypto");
|
|
var fs = require("fs");
|
|
var path = require("path");
|
|
|
|
var getFilesInFolder = require("./getFilesInFolder");
|
|
|
|
var CODE_PUSH_FOLDER_PREFIX = "CodePush";
|
|
var CODE_PUSH_HASH_FILE_NAME = "CodePushHash.json";
|
|
var HASH_ALGORITHM = "sha256";
|
|
var TEMP_FILE_PATH = path.join(require("os").tmpdir(), "CodePushResourcesMap.json");
|
|
|
|
var resourcesDir = process.argv[2];
|
|
var jsBundleFilePath = process.argv[3];
|
|
var assetsDir = process.argv[4];
|
|
var resourceFiles = [];
|
|
|
|
getFilesInFolder(resourcesDir, resourceFiles);
|
|
|
|
var oldFileToModifiedTimeMap = require(TEMP_FILE_PATH);
|
|
var newFileToModifiedTimeMap = {};
|
|
|
|
resourceFiles.forEach(function(resourceFile) {
|
|
newFileToModifiedTimeMap[resourceFile.path.substring(resourcesDir.length)] = resourceFile.mtime;
|
|
});
|
|
|
|
var bundleGeneratedAssetFiles = [];
|
|
|
|
for (var newFilePath in newFileToModifiedTimeMap) {
|
|
if (!oldFileToModifiedTimeMap[newFilePath] || oldFileToModifiedTimeMap[newFilePath] < newFileToModifiedTimeMap[newFilePath].getTime()) {
|
|
bundleGeneratedAssetFiles.push(newFilePath);
|
|
}
|
|
}
|
|
|
|
var manifest = [];
|
|
|
|
if (bundleGeneratedAssetFiles.length) {
|
|
bundleGeneratedAssetFiles.forEach(function(assetFile) {
|
|
// Generate hash for each asset file
|
|
var readStream = fs.createReadStream(resourcesDir + assetFile);
|
|
var hashStream = crypto.createHash(HASH_ALGORITHM);
|
|
|
|
readStream.pipe(hashStream)
|
|
.on("error", function(error) {
|
|
throw error;
|
|
})
|
|
.on("finish", function() {
|
|
hashStream.end();
|
|
var buffer = hashStream.read();
|
|
var fileHash = buffer.toString("hex");
|
|
manifest.push(CODE_PUSH_FOLDER_PREFIX + assetFile.replace(/\\/g, "/") + ":" + fileHash);
|
|
|
|
if (manifest.length === bundleGeneratedAssetFiles.length) {
|
|
// Generate hash for JS bundle
|
|
readStream = fs.createReadStream(jsBundleFilePath);
|
|
hashStream = crypto.createHash(HASH_ALGORITHM);
|
|
readStream.pipe(hashStream)
|
|
.on("error", function(error) {
|
|
throw error;
|
|
})
|
|
.on("finish", function() {
|
|
hashStream.end();
|
|
var buffer = hashStream.read();
|
|
var fileHash = buffer.toString("hex");
|
|
manifest.push(CODE_PUSH_FOLDER_PREFIX + "/" + path.basename(jsBundleFilePath) + ":" + fileHash);
|
|
manifest = manifest.sort();
|
|
|
|
var finalHash = crypto.createHash(HASH_ALGORITHM)
|
|
.update(JSON.stringify(manifest))
|
|
.digest("hex");
|
|
|
|
var savedResourcesManifestPath = assetsDir + "/" + CODE_PUSH_HASH_FILE_NAME;
|
|
fs.writeFileSync(savedResourcesManifestPath, finalHash);
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
fs.unlinkSync(TEMP_FILE_PATH); |