Я новичок в электронике и пытаюсь использовать собственные протоколы для своего приложения и распределенных клиентских 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 будет обращаться к таким ресурсам, как файлы css или js, через мой собственный протокол resource://
. Основной файл выполняется правильно, но я не могу 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.
При проверке кода require
в инструментах разработчика (около module.js:336
, строка 337 в текущем мастере узла), когда возникает ошибка, request
равно "./test"
и paths
содержит только одну запись для основных модулей электрона, и я не смог найти способ расширить этот список путей поиска.
Я проверил другие проблемы (# 4459, # 2539), которые, похоже, связаны с той же проблемой, но они мне не помогли (например, использование сценария предварительной загрузки, управляющего путем module
или globalPaths, не работает .
Есть идеи, как заставить это работать? Или вы бы порекомендовали использовать один файл JavaScript? (Я использую TypeScript в качестве препроцессора, который может объединять все исходные файлы).
Вы можете проверить пути поиска модулей узла в module.paths
, если вашего resources/js
нет в нем, тогда require
не сможет найти test.js
.
Я думаю, это потому, что вы неправильно манипулировали путями поиска модулей, вы можете стать пчелой, чтобы получить некоторые идеи в сообществе .
Когда вы загружаете файл .js
через тег <script>
он внедряется в документ, поэтому
<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 и весь другой относительный ссылочный контент.
Вы можете установить для него любую пустую строку, если ваш индексный файл не находится внутри подпапки (в этом примере веб)
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 и весь другой относительный ссылочный контент.
Вы можете установить для него любую пустую строку, если ваш индексный файл не находится внутри подпапки (в этом примере веб)