Gregion Gregion - 1 month ago 10
Javascript Question

getting current and previous version number on Google Chrome Extension

I would like to compare the version number while I'm updating my Chrome Extension.

The reason is that there were a few structural changes, and I don't want my users (who already have my module) to add their details again.

I know that I can get version number of the currently running module by this line:

chrome.runtime.getManifest().version


My question is, while I'm updating, how can I compare the versions, or should I look at the issue from another angle?

Xan Xan
Answer

The API that gets invoked on upgrade is chrome.runtime.onInstalled.

chrome.runtime.onInstalled.addListener(details => {
  if (details.reason === "update") {
    let newVersion = chrome.runtime.getManifest().version;
    console.log(`Updated from ${details.previousVersion} to ${newVersion}`);
  }
});

You could make your logic dependent on that, but it's fragile. Your storage schema isn't likely to change every version, and you need to account for users that don't do every single upgrade but jump versions (e.g. a machine was offline for a long time).

It's much better to store the version of your storage schema with the data itself, and trigger data migration from onInstalled.

var defaults = {
  someData: "reasonableDefault",
  /* ... */
  storageSchema: 5 // Increment this when data format changes
};

chrome.runtime.onInstalled.addListener(details => {
  if (details.reason === "update") {
    migrateData(doSomeInitialization);
  }
});

function migrateData(callback) {
  // This pulls stored values, falling back to defaults, if none
  chrome.storage.local.get(defaults, data => {
    let migrated = false;
    while (!migrated) {
      switch (data.storageSchema) {
        case 1:
          /* modify data to migrate from 1 to 2 */
          data.storageSchema = 2;
          break;
        /* ... */
        case 4:
          /* modify data to migrate from 4 to 5 */
          data.storageSchema = 5;
          break;
        case 5: // Expected; do nothing
          break;
        default:
          throw new Error(`Unrecognized storage schema ${data.storageSchema}!`);
      }
      if (data.storageSchema === defaults.storageSchema) {
        migrated = true;
      }
    }
    chrome.storage.local.set(data, callback);
  });
}