3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

フロントエンドリソースを、HTMLで管理する設計

Last updated at Posted at 2017-03-11

まず、リソースコンパイルについて

最近、フロントエンドのリソースを開発する上で、様々なコンパイラを使用することが増えている気がします。
具体的には、

JS・JSX
Browserifyとbabelでモジュール管理・ES6・JSX
CSS
sassやpostcssやらautoprefixerで変換
HTML
テンプレートエンジンで変換
これらをタスクにして、ファイル監視して、タスクランナー走らせて、BrowserSyncして・・・ ### これらの問題点(と私が感じるところ) - Gulp等のタスクランナーはプラグイン頼みなところがある - npm scriptsは、コマンドライン環境に影響される - タスクランナーのタスクのパスを書く部分がやだ - 監視するパスとかリソースのパスがごっちゃになる(/dev/*.js ⇒ /dev/bundle.js的な) - タスク監視起動して、Webサーバー起動しての2段階が面倒 - cdnを使った場合、そこまでBundle(一つのファイルにまとめる)できない

HTMLで管理してみる

とりあえず、図にしてみました
image

上の図で、「コンパイル処理」って書かれているものが、browserifyやbabelなどの処理で、基本的には、ストリームで読み込んで、吐き出すだけの共通処理を実装すればいいと思っています。
(コマンドラインの標準入出力でもOK)
Webサーバーには、mimeタイプなどで判定してコンパイルする処理を埋め込みます。

リリース時に流す処理は、それとは別で、htmlを読み込ませて、linkタグやscriptタグをもとに、読み込み⇒コンパイル⇒Bundleという風な処理をさせます。
HTMLは、このようになります。

変換前.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>タイトル</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://hostname//framework-1.2.3.css" rel="stylesheet">
        <link href="css/1.css" rel="stylesheet">
        <link href="css/2.css" rel="stylesheet">
        <link href="css/3.css" rel="stylesheet">
    </head>
    <body>
        <div id="app"></div>
    
        <script src="https://hostname/framework-1.2.3.js"></script>
        <script src="js/1.js"></script>
        <script src="js/2.js"></script>
        <script src="js/3.js"></script>
    </body>
</html>

変換後.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>タイトル</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="bundle.css" rel="stylesheet">
    </head>
    <body>
        <div id="app"></div>
    
        <script src="bundle.js"></script>
    </body>
</html>

deferやasyncを使う場合を除けば、HTMLは上から順に読み込んでいくだけです。
ならば、linkタグとscriptタグを上から順に読み込み、コンパイル処理をし、bundleするだけで同じ挙動になるはず。(cheerioとか使えば、簡単そう)
cdnなどのリモートファイルもそのまま読み込んで一つにまとめちゃう。

開発時は、ファイルバラバラで、コンパイル処理もさせて、開発用のWebサーバーに負担かかるけど、リリース時に解消しちゃえばいいよねって考え方。

メリット

  • 開発時のコンパイルは、Webサーバーに任せ、タスクランナーは使わなくて済む
  • リソースのパスはHTMLで管理できる
  • CDNのファイルとかもまとめられる(本番環境は、ネットにつながっていない場合がある)
  • コンパイルの処理は、タスクランナーのプラグインでない為、使いまわしやすい

デメリット

  • リリース時には、サーバーサイドのコンパイル処理をはずす必要がある
  • リリース時には、ソースマップとかは、はずす必要がある

実際にやってみるとしたら

せっかくcheerio使うなら、<part>タグなんて読み込めるようにして…
(実装簡単そう)

sample.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>タイトル</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="css/1.css" rel="stylesheet" async>
        <link href="css/1.css" rel="stylesheet" defer>
        <link href="https://hostname//framework-1.2.3.css" rel="stylesheet">
        <link href="css/2.css" rel="stylesheet">
        <link href="css/3.css" rel="stylesheet">
    </head>
    <body>
        <part src="part/header.html">
        <div id="app"></div>
        <part src="part/footer.html">
        
        <script src="https://hostname/framework-1.2.3.js"></script>
        <script src="js/1.js"></script>
        <script src="js/2.js"></script>
        <script src="js/3.js"></script>
    </body>
</html>

コンパイル処理

compile.js
const compile = require('compile-tool')

let config = {
    // Expressのstaticとかの為に
    prefix: "static/base",
    // コンパイル前のテンプレートエンジンがあれば指定
    templateEngine: function(file, cb) {
        // パスとバッファを格納
        let buffer = file.buffer
        let path = file.path

        this.push(//コンパイル後のBuffer)

        // 最後は、コールバックを呼び出し
        cb()
    },
    // 拡張子ごとのコンパイラを指定(インターフェイスは、templateEngineに渡す関数と同じ)
    compilers: {
        "js": jsCompiler,     // browserify babelify
        "jsx": jsCompiler,    // browserify babelify
        "css": cssCompiler    // postcss autoprefixer
    }
}

// HTMLのパスをglobで指定・configで初期化・outのパスは、config.prefixを指定しない場合のみ有効
compile("./dev/*.html", config).out("./out/")

こんな感じですかね~

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?