My use case for this was in my Electron app. The files here are based on the Electron Quick Start.
I want to have a File object similar to what I would get after selecting a file via <input type="file" /> or via the Drop event, but I want to use the extra power of electron and it's Node direct file access without needing to request file access permissions as with the File System Access API.
Thanks to @abr's answer I have a complete solution now:
main.js
const { app, BrowserWindow, ipcMain } = require('electron')
const fs = require('fs')
const path = require('path')
const { LocalFileData } = require('get-file-object-from-local-path')
let win
const createWindow = () => {
win = new BrowserWindow({
width: 1920,
height: 1080,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
})
ipcMain.handle('get-file', async (event, filePath) => {
try {
const data = new LocalFileData(filePath)
return [data]
} catch (e) {
return [null, e]
}
})
win.loadFile(path.join(__dirname, 'index.html'))
}
app.whenReady().then(() => {
createWindow()
})
preload.js:
const { ipcRenderer, contextBridge } = require('electron')
const { constructFileFromLocalFileData } = require('get-file-object-from-local-path')
contextBridge.exposeInMainWorld('electronAPI', {
getFile: async (filePath) => {
const [data, error] = await ipcRenderer.invoke('get-file', filePath)
if (!data) {
return [data, error]
}
return [constructFileFromLocalFileData(data), error]
},
})
renderer.js:
const filePath = '/path/to/my/file.jpg'
const [file] = await window.electronAPI.getFile(filePath)
console.log(file)
You could arguably do the constructFileFromLocalFileData in renderer.js to keep any logic out of preload.js.
However it seems more sensible that the renderer.js can treat getFile as something similar to a file picker and so get a standard File object back. Since preload runs in the renderer environment but with also access to Node modules it seems like a sensible place to do it.