Electron: Пользовательский протокол и требование для локальных файлов

Созданный на 17 февр. 2016  ·  3Комментарии  ·  Источник: electron/electron

Я новичок в электронике и пытаюсь использовать собственные протоколы для своего приложения и распределенных клиентских 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 в качестве препроцессора, который может объединять все исходные файлы).

Самый полезный комментарий

Я нашел это решение для всех, кого это может касаться:
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
  }));

Все 3 Комментарий

Вы можете проверить пути поиска модулей узла в 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
  }));
Была ли эта страница полезной?
0 / 5 - 0 рейтинги