Electronでアプリを作ると以下のような感じになります。
main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
const url = require('url');
...
function createWindow() {
win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true,
}));
...
}
app.on('ready', createWindow);
...
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hoge</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div id="root">
</div>
<script type="text/javascript" src="/app.js">
</script>
</body>
</html>
しかし、index.html
の中で/style.css
や/app.js
を絶対パスで指定すると正しく読み込めません。絶対パスで書くとファイルシステムのルートを基点としてパスが探索されます(当たり前ですね)。相対パスで書けば、同じディレクトリを起点にして探してくれるので正しく動きますが、webサイトとコードを共通化していたりすると、main.js
と同階層を/
として扱い絶対パスで書きたかったりします。
そこで、main.js
を以下のようにします。
main.js
const { app, BrowserWindow, protocol } = require('electron');
const path = require('path');
const url = require('url');
...
app.on('ready', () => {
protocol.interceptFileProtocol('file', (req, callback) => {
const requestedUrl = req.url.substr(7);
if (path.isAbsolute(requestedUrl)) {
callback(path.normalize(path.join(__dirname, requestedUrl)));
} else {
callback(requestedUrl);
}
});
});
function createWindow() {
win = new BrowserWindow({ width: 800, height: 600 });
win.loadURL(url.format({
pathname: '/index.html',
protocol: 'file:',
slashes: true,
}));
...
}
app.on('ready', createWindow);
...
electron.protocol.interceptFileProtocol()
で、URL解釈を特定のスキーマについて割り込めます。
ファイルを読み込む時はfile
というスキーマ(例:file:///hoge/fuga
)なので、その処理に割り込んで絶対パスの場合は__dirname
を足すようにします。
以上の処理を足したので、win.loadURL()
に渡すURLは__dirname
を足してフルパスにしておく必要はなく、現在のディレクトリを/
として考えた絶対パスで書くように変えます。