ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

ファイルストア用に画像、CSS、JavaScriptファイルを一つのHTMLにまとめる

f:id:mbaasdevrel:20190318161207p:plain

手軽にアプリ内で使うファイルをアップロードできて、HTTPSで公開することもできるファイルストアですが、一つ大きな欠点があります。それは階層構造をサポートしないということです。

多くの場合、JavaScriptはjsまたはjavascriptsフォルダに、CSSはcssフォルダ、画像はimagesフォルダなどアセットごとに分類して保存しているはずです。HTMLファイルからはそれらのファイルを相対パスなどで指定しているでしょう。すべてが同じ階層に保存されてしまうファイルストアでは階層構造によるファイル管理ができず、不便です。

そこで今回は一つのHTMLファイル内にすべてのアセットを埋め込んでしまうinline-sourceを使ってこの問題に対応します。

サンプルのHTML

例えばこんなHTMLファイルになります。CSS、JavaScript、画像などが使われています。

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title></title>
    <meta charset="utf-8" />
    <meta name="description" content="" />
    <meta name="author" content="" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="css/style.css" inline />
    <link rel="shortcut icon" href="" />
  </head>
  <body>
    <h1>NCMB</h1>
    <p>
      <img src="images/logo.png" inline />
    </p>
    <script src="js/app.js" inline></script>
  <!-- Example: <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> -->
  </body>
</html>

ライブラリのインストール

そしてライブラリをインストールします。Node.jsを使っています。

$ npm init
$ npm install inline-source -S

変換スクリプトの作成

さらに変換するスクリプトを作成します。popeindustries/inline-source-cli: CLI for inline-sourceで手軽にできるようなのですが筆者環境ではエラーになってしまったのでスクリプトを書きました。

行っているのは index.html を読み込み、変換結果を compress.html として出力しています。ファイル名は index.js としています。

const { inlineSource } = require('inline-source');
const fs = require('fs');
const path = require('path');
const {promisify} = require('util');

(async () => {
  const htmlpath = path.resolve('./index.html');
  let html;
  try {
    html = await inlineSource(htmlpath, {
      compress: true,
      rootpath: path.resolve('.'),
    });
    await promisify(fs.writeFile)('./compress.html', html);
  } catch(err) {
    console.error(err);
  }  
})();

実行する

では実際に実行してみます。 node index.js を実行した結果、compress.htmlが以下のように生成されます。CSS/JavaScript/画像がきちんと展開されています。

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title></title>
    <meta charset="utf-8" />
    <meta name="description" content="" />
    <meta name="author" content="" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>body{font-size:20px}h1{color:#00f}img{width:200px}</style>
    <link rel="shortcut icon" href="" />
  </head>
  <body>
    <h1>NCMB</h1>
    <p>
      <img src="data:image/png;base64,iVBO...Jggg=="/>
    </p>
    <script>document.addEventListener("DOMContentLoaded",async()=>{document.querySelector("h1").style.color="red"});</script>
  <!-- Example: <script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> -->
  </body>
</html>

ファイルストアにアップロードする

後はこのcompress.htmlをファイルストアにアップロードするだけです。関連するファイルもすべてHTML中に埋め込まれたので、アップロードするのはこのファイルだけで済みます。

まとめ

階層構造をサポートしていないファイルストアですが、工夫次第で克服することはできます。ぜひinline-sourceを使って運用の手間を軽減してください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。