Skip to content

Instantly share code, notes, and snippets.

@hamstu
Created June 10, 2020 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hamstu/b1f88ea486508111668df8d39e2d0ca1 to your computer and use it in GitHub Desktop.
Save hamstu/b1f88ea486508111668df8d39e2d0ca1 to your computer and use it in GitHub Desktop.
Electron file:// intercept
const path = require('path');
const { protocol } = require('electron');
/**
* This method is used to intercept file requests from the Electron
* BrowserWindow ensure we load the correct files.
*
* This allows us to intercept requests from the JavaScript that ask for
* resources with absolute paths, e.g., `/web_modules/react.js`. Without
* the intercept, Electron would attempt (and fail) to load from the
* system's root directory.
*
* The reason our JS code is making absolute requests is becuse it is bundled
* with Snowpack, which assumes we'll be serving our site from a server,
* where using absolute `/` paths would resolve normally.
*/
module.exports = function interceptFileRequests(assetDirectory) {
if (!assetDirectory) {
throw new Error('`interceptRequests` must be passed a directory argument.');
}
return protocol.interceptFileProtocol('file', (request, callback) => {
// Remove `file://` from URL/path - decode as well since it may be urlencoded
const url = decodeURIComponent(request.url.substr(7));
// Get just the relative path
const rootDir = path.resolve(__dirname, '..');
const requestedUrlRelative = url.replace(rootDir, '');
// Now insert the path to the asset directory
const newPath = path.join(rootDir, assetDirectory, requestedUrlRelative);
callback({ path: newPath });
});
};
@danprince
Copy link

Hey, cool to see someone else figuring out Snowpack + Electron too! It'd be great if there was a solid recipe to work from.

How are you working around the fact that the file:// protocol generally won't serve JS with the correct MIME type? That's usually a dealbreaker for ES modules.

I have been looking at using custom protocols to get around that: https://gist.github.com/smotaal/f1e6dbb5c0420bfd585874bd29f11c43

The rough gist is that requests to a custom protocol (e.g. app://web_modules/foo.js) are resolved to a specific dir and served with correct MIME types, but I'd love it if there was a simpler solution.

@hamstu
Copy link
Author

hamstu commented Jun 12, 2020

Thanks for the comment @danprince!

How are you working around the fact that the file:// protocol generally won't serve JS with the correct MIME type? That's usually a dealbreaker for ES modules.

Oh, interesting. 🤔 To be honest, I haven't had any issues here at all. (Since posting this I did have to add support for ignoring certain paths.) I'm wondering if this isn't an issue with the latest Chrome version? By the way, I was planning to put together a create-snowpack-app based on electron quickstart with this sort of fix in place so maybe we can collaborate on that, if you're interested. :)

@ryands17
Copy link

@hamstu Could you share how where exactly should I add this file in the Electron + Snowpack setup?

@ajoslin103
Copy link

ajoslin103 commented Mar 28, 2023

@ryands17

call this before app.on("ready"

  protocol.registerFileProtocol("file", (request, callback) => {
    const filePath = url.fileURLToPath(request.url.replace(/extras/, "static/extras"));
    callback(filePath);
  });

@aztack, thanks for the usage

https://gist.github.com/aztack/a50ab2aa574bdcaa8be98bdbc2572297?permalink_comment_id=4518984#gistcomment-4518984!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment