TypeError: fs.existsSync is not a function | import { ipcRenderer } from 'electron'
在electron的渲染进程中导包会发生TypeError: fs.existsSync is not a function node_modules/electron/index.js:6
var pathFile = path.join(__dirname, 'path.txt')
if (fs.existsSync(pathFile)) {
module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
} else {
throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
}
产生问题的原因:
1、首先在渲染进程属于浏览器端,没有集成Node的环境,所以类似 fs 这样的Node的基础包是不可以使用。
2、因为没有Node环境,所以require关键词是不可以使用的。
弄清楚这个就一起解决问题吧:
方案一:
渲染进程
const { ipcRenderer } = window.require('electron');
主进程
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
使用这种方式能够是electron为前端工程提供Node的环境,让程序能够正常运行。
但是,单独启动前端工程会出现 window.require is not a function .
方案二:
来源于StackOverflow
1、创建 preload.js 文件:
window.ipcRenderer = require('electron').ipcRenderer;
2、在main.js文件中的 webPreferen中设置预加载preload:
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
preload: __dirname + '/preload.js'
}
});
3、渲染进程
componentDidMount() {
if (isElectron()) {
console.log(window.ipcRenderer);
window.ipcRenderer.on('pong', (event, arg) => {
this.setState({ipc: true})
})
window.ipcRenderer.send('ping')
}
}
is-electron for the isElectron() function
方案三:
来源以 github
如果你使用TypeScript可以这样做:
import {IpcRenderer} from 'electron';
declare global {
interface Window {
require: (module: 'electron') => {
ipcRenderer: IpcRenderer
};
}
}
const { ipcRenderer } = window.require('electron');
方案四:
读了N个electron项目后,写成的一种解决方案:
直接上代码
externals(context, request, callback) {
const isDev = process.env.NODE_ENV === 'development';
let isExternal = false;
const load = [
'electron',
'fs',
'path',
'os',
'url',
'child_process'
];
if (load.includes(request)) {
isExternal = `require("${request}")`;
}
const appDeps = Object.keys(require('./app/package').dependencies);
if (appDeps.includes(request)) {
const orininalPath = slash(join(__dirname, './app/node_modules', request));
const requireAbsolute = `require('${orininalPath}')`;
isExternal = isDev ? requireAbsolute : `require('${request}')`;
}
callback(null, isExternal);
},
发现了吗,在前端工程配置的时候,默认设置externals参数,在使用require的时候会查看默认加载的模块中有没有,按需加载模块,如果初始加载的模块中没有该模块,会向上级目录./app/package查找模块。