システム開発

【electron】electronでejsを使う!

シロクマくん

こんにちは、シロクマです!

今日は、electronでejsを使うためのライブラリ「ejs-electron」を使ってみたいと思います!

この記事で分かること

  • ejs-electronの使い方
  • ejs-electronを使った実装サンプル

Contents

そもそも「ejs」とは

What is the “E” for? “Embedded?” Could be. How about “Effective,” “Elegant,” or just “Easy”? EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It’s just plain JavaScript.

https://ejs.co/

以上、公式からですが英語ばかりで分かりません。。。googole翻訳に通した後の形が以下となります。

「E」とは何ですか? "埋め込み?"になり得る。 「効果的」、「エレガント」、または単に「簡単」はどうですか? EJSは、プレーンなJavaScriptを使用してHTMLマークアップを生成できる単純なテンプレート言語です。物事を整理する方法についての宗教性はありません。反復と制御フローの再発明はありません。単なるJavaScriptです。

また、公式には左記の文言もありました。「Embedded JavaScript templating.

上記公式の文言にもある通り、ejsとは「 EJSは、プレーンなJavaScriptを使用してHTMLマークアップを生成できる単純なテンプレート言語」です。

以下サンプルですが、jspを使ったことのある人には見覚えがあるのでは?と思います。(詳細は後述)

//test.ejs
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <%- include("../_share/stylesheets.ejs") %>
    <title>ejs_test</title>
  </head>
  <body>
    <%
    let val1 = "test";
    let array2 = ["Polar bear","Penguin","Orca","Sea lion"];
    %>
    <div class="container">
      <select class="param4-sel">
        <%if ( val1 ) {%>
          <% array2.forEach (( element ) => { %>
            <option value=<%= element %>><%= element %></option>
          <% }) %>
        <% } else { %>
          <option value="nothing">nothing</option>
        <% } %>
      </select>     
    </div>
  </body>
</html>

electronでejsを使う!

はい。本題です。上記サンプルの通り、ejsは「HTMLマークアップを生成できる」のです。

シロクマくん

・・・ということは、web開発リソースを使える「electron」でもejsは使えるの?

その通りではあるのですが、通常expressなどでejsを使う際は以下のように利用宣言を行いますが、electronの場合は勝手が違うため同じライブラリを使った利用は出来ないのです。

app.set("view engine", "ejs");

そこで出てくるのが「ejs-electron」です。※公式リンクは以下です。

A mega lightweight, completely flexible module that allows ejs templating in an Electron app.Makes use of the Electron protocol module to supply a custom handler for the file: protocol.This handler intercepts all file requests, compiles any requested .ejs files, and serves the result.

https://www.npmjs.com/package/ejs-electron

例によってgoogle翻訳です。

Electronアプリでテンプレートを作成できる、非常に軽量で完全に柔軟なモジュール。

Electronプロトコルモジュールを使用して、ファイルのカスタムハンドラーprotocolを提供します。このハンドラーは、すべてのファイル要求をインターセプトし、要求された.ejsファイルをコンパイルして、結果を提供します。

要するに、electronでもejsが使えるよってことですね。上記の概要については実際に実装していく際や、ejs-electronの中身を見てみるとよく分かると思います。

では、次からいよよいサンプルを使った実際の使い方です。

【サンプル】ejs-electronサンプル

サンプルの流れとしては以下となります。

  1. npm installしてモジュール入手(必須)
  2. main.jsでejs-electronの利用要求(必須)
  3. main.jsでコンパイル対象へデータ引き渡し
  4. test.ejsの実装および引き渡されたデータの利用

1.npm installしてモジュール入手

npm install --save-dev ejs-electron

2.main.jsでejs-electronの利用要求

const {app, BrowserWindow} = require('electron');
const ejse = require('ejs-electron'); // 2.main.jsでejs-electronの利用要求

let mainWindow;

let data = ["Polar bear","Penguin","Orca","Sea lion"];

app.on("ready", () => {
  ejse.data("Sea-animals",data); main.jsでコンパイル対象へデータ引き渡し
  mainWindow = new BrowserWindow({
    width : 800,
    height : 600,
  });
  mainWindow.loadURL('file://' + __dirname + '/ejs/test.ejs'); // ※fileプロトコルで読み込み

});

//クローズ処理
const del = require("del");
app.on("window-all-closed",() => {
  app.quit();

})

2行目で、ejs-electronの利用要求を行っています。また、14行目で対象ejsをfileプロトコルで読み込みます

3.main.jsでコンパイル対象へデータ引き渡し

ここが今回の一つのポイントかな?と思いますが、9行目で「コンパイル対象へデータ引き渡し」を行っています。(正確には引き渡す前の準備だと思いますが・・・)

4.test.ejsの実装および引き渡されたデータの利用

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>ejs_test</title>
  </head>
  <body>
    <%
    const seaAnimals = ejse.data("Sea-animals") || undefined;
    %>
    <div class="container">
      <select class="param4-sel">
        <%if ( seaAnimals ) {%>
          <% seaAnimals.forEach (( seaAnimal ) => { %>
            <option value=<%= seaAnimal %>><%= seaAnimal %></option>
          <% }) %>
        <% } else { %>
          <option value="nothing">nothing</option>
        <% } %>
      </select>     
    </div>
  </body>
</html>

10行目で、main.jsで引き渡ししていたデータの受け取りを行っています。もしもデータが存在しなかった場合はundefinedで。

14行目~20行目あたりが実際の利用となります。引き渡しデータにデータが格納されていた場合はループで取り出して、「selectタグのoptionとなるように」という設定です。

(おまけ)ejs-electronについて

ejs-electronがどのようにコンパイルを実現しているのか?ということについては、実際にejs-electronを覗いていただくのが早いかなと思います。

が、わたしもちょっと見てみたので何となく印象を述べてみます。※誤りがあったらごめんなさい。。。

Electronプロトコルモジュールを使用して、ファイルのカスタムハンドラーprotocolを提供します。このハンドラーは、すべてのファイル要求をインターセプトし、要求された.ejsファイルをコンパイルして、結果を提供します。

electoronは、web系開発リソースを使ってデスクトップアプリ開発ができる、というのが売り文句です。が、electron説明の記事でも書いた通り、Webサーバ機能はもってないのです。

では、どのようなプロトコルでデータのやり取りをしているのかというと・・・いろいろあるようです。

が、今回使ったejs-electronでは、「file」プロトコルをインターセプトする形で利用しているようです。

要するに、fileプロトコルでファイルが読み込まれた際にejs-electronが動作してファイルをejsとしてコンパイルする、ということです。

そのため、ejs-electronを使ってejsファイルを取り扱う場合は、fileプロトコルを使うことになります!

まとめ

はい。まとめです。

electronにとどまらず、web開発でもそうですが画面回りでどのフレームワークを使えばいいか?というのは迷いがちです。今回はelectronでejsを使う方法紹介しましたが、そもそもejsって古いのかも?とも思います。

ただ、はじめの方でも書きましたがejsはたとえばjspに慣れ親しんだ人からするととっつきやすかったりしますし、使うメリットもあるのかなと思っています。