我是电子的新手,并试图为我的应用程序和分布式客户端 js 文件使用自定义协议,即require
d。 但是,我无法加载模块,因为require
忽略了我的自定义方案。 这是我的环境:
lib/ - node scripts
main.js - node entry script
resources/ - client side resources
css/
html/
index.html
js/ - client side scripts
main.js
test.js
package.json
lib/main.js 基于公共主页的示例:
// lib/main.js
'use strict';
const electron = require('electron');
const app = electron.app; // Module to control application life.
const BrowserWindow = electron.BrowserWindow; // Module to create native browser window.
const path = require('path');
var mainWindow = null;
app.on('ready', function() {
const protocol = electron.protocol;
/* js, css, fonts, ... */
protocol.registerFileProtocol('resource', (request, callback) => {
var url = request.url.substr(11);
callback({path: path.join(__dirname, '../resources', url)});
});
/* html, possible rendered from other files like markdown or jade */
protocol.registerFileProtocol('view', (request, callback) => {
var url = request.url.substr(11);
callback({path: path.join(__dirname, '../resources/html', url)});
});
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600});
// and load the index.html of the app.
mainWindow.loadURL('view://index.html');
// Open the DevTools.
mainWindow.webContents.openDevTools();
// ...
});
注意view://
协议背后的过程,以后会编译其他文件成html,比如markdown或者jade( view://index.jade
会编译jade文件,返回html字符串)。
<!-- resources/html/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Electron Test</title>
</head>
<body>
<h1>Electron Test</h1>
<script src="resource://js/main.js"></script>
</body>
</html>
html 文件将通过我的自定义resource://
协议访问 css 或 js 文件等资源。 主文件正确执行,但是我不能在那里require
另一个文件:
// resources/js/main.js
const test = require('./test'); // Error: Cannot find module './test'
test.sayHello();
// resources/js/test.js
exports.sayHello = function() {
console.log('Hello!');
};
我正在使用electron .
,v0.36.7 执行它。
当错误发生时,在 devtools 中检查require
后面的代码(大约module.js:336
,节点当前主节点的第337行)时, request
是"./test"
和paths
仅包含电子核心模块的一个条目,我找不到扩展该搜索路径列表的方法。
我检查了其他问题(#4459、#2539),这些问题似乎与同一个问题有关,但它们对我没有帮助(例如,使用预加载脚本操纵module
的路径或 globalPaths 不起作用.
任何想法如何让这个工作? 或者您会建议使用单个 JavaScript 文件吗? (我使用 TypeScript 作为预处理器,它可以连接所有源文件)。
您可以在module.paths
查看 Node 模块的搜索路径,如果您的resources/js
不在其中,则require
将无法找到test.js
.
我认为是因为您没有正确操作模块搜索路径,您可能会在社区中获得一些想法。
当您通过<script>
标签加载.js
文件时,它会嵌入到文档中,因此
<body>
<h1>Electron Test</h1>
<script src="resource://js/main.js"></script>
</body>
在功能上等同于
<body>
<h1>Electron Test</h1>
<script>
const test = require('./test'); // Error: Cannot find module './test'
test.sayHello();
</script>
</body>
这意味着./test
是相对于index.html
解析的,而不是相对于js/main.js
。 要解决这个问题,你可以这样做
<body>
<h1>Electron Test</h1>
<script>
require('../js/main.js');
</script>
</body>
我为它可能涉及的任何人找到了这个解决方案:
WEB_FOLDER 包含 index.html 和所有其他相关引用内容。
如果您的索引文件不在子文件夹中(本例中为 web),您可以将其设置为任何空字符串
function createWindow() {
const WEB_FOLDER = 'web';
const PROTOCOL = 'file';
electron.protocol.interceptFileProtocol(PROTOCOL, (request, callback) => {
// // Strip protocol
let url = request.url.substr(PROTOCOL.length + 1);
// Build complete path for node require function
url = path.join(__dirname, WEB_FOLDER, url);
// Replace backslashes by forward slashes (windows)
// url = url.replace(/\\/g, '/');
url = path.normalize(url);
console.log(url);
callback({path: url});
});
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false
}
});
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: 'index.html',
protocol: PROTOCOL + ':',
slashes: true
}));
最有用的评论
我为它可能涉及的任何人找到了这个解决方案:
WEB_FOLDER 包含 index.html 和所有其他相关引用内容。
如果您的索引文件不在子文件夹中(本例中为 web),您可以将其设置为任何空字符串