next-offline icon indicating copy to clipboard operation
next-offline copied to clipboard

Pre-cache static HTML files

Open ScreamZ opened this issue 6 years ago • 3 comments

Hello,

I'm using next as static export.

Edit: I figured out that this might not needed because manifest start_url property will only open one URL ?

The problem

The problem is that workbox webpack is running during next build phase which will cache all the JS assets that are used by the app. During this phase, html files are not generated yet, so the plugin can't detect them.

The thing is that the JS assets are not enough and we also need each static HTML page to make the app work if someone is coming on any URLs.

I found no solution to handle this, so I made my own, maybe we could discuss about how this could be added ?

My solution

Manifest extension function

const crypto = require("crypto");
const fs = require("fs");
const _ = require("lodash");
const path = require("path");

function readDirR(dir) {
  return fs.statSync(dir).isDirectory() ? Array.prototype.concat(...fs.readdirSync(dir).map(f => readDirR(path.join(dir, f)))) : [dir];
}


module.exports.buildManifestForPages = function(pagesDirectoryPath) {
  return readDirR(pagesDirectoryPath)
    .map(url => url.replace(pagesDirectoryPath, ""))
    .filter(page => !page.startsWith("/_")) // Remove specific pages
    .map(pageName => {
      // Remove extension
      let url = pageName.replace(/(\/index)?.(tsx|jsx)/, "");

      // For index page
      if (url === "") {
        url = "/";
      }

      return {
        revision: crypto
          .createHash("md5")
          .update(String(Date.now()), "utf8")
          .digest("hex"),
        url
      };
    });
};

next.config.js

I'm using const withPlugins = require("next-compose-plugins"); but this remain the same

const { buildManifestForPages } = require("./modules/build/helpers");

// …
[
      withOffline,
      {
        transformManifest: manifest => {
          // Pre-cache HTML assets
          const pagesRoot = path.join(__dirname, "pages");
          const customManifest = buildManifestForPages(pagesRoot);

          return customManifest.concat(manifest);
        },
        workboxOpts: {
          offlineGoogleAnalytics: true,
        }
      }
    ]
  ],

What do you think about this ?

Regards

ScreamZ avatar Jul 24 '19 13:07 ScreamZ

@ScreamZ Do you know at which point the HTML files are generated?

It's also important to know a lot is changing in workbox v5, specifically they're doubling down on the webpack asset pipeline. You can read more about it here: https://github.com/GoogleChrome/workbox/releases

hanford avatar Jul 24 '19 18:07 hanford

Looks like they are created when running next export. I'll take a look closer, thanks

ScreamZ avatar Jul 25 '19 12:07 ScreamZ

@hanford Is there an update regarding this issue? The static HTML files are generated after the creation of the webpack manifest. Actually, webpack is not involved at all in the static export.

As a "ugly" workaround I'm post-processing the output of next export and appending the missing HTML file and all resources in the public directory to the precacheAndRoute array.

Maher4Ever avatar Mar 17 '20 20:03 Maher4Ever