LoginSignup
30
27

More than 5 years have passed since last update.

Node.jsで実行できるHTMLファイルを作る

Last updated at Posted at 2014-06-30

小ネタです。

Node.jsで実行可能なHTMLファイルを書くことが出来ます。

Node.jsで読んだ場合はHTML部分をコメントアウトし、
ブラウザで開いた場合は逆のことをすればいいです。
簡単ですね。

<!--
console.log("valid javascript!");
/*
-->

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    <script src="hello.html"></script>
</head>
<body>
    <h1>Valid HTML</h1>
</body>
</html>
<!--
*/
-->

明日ここに来てください。本当の1 File CMSをお見せしますよ

これを利用して、1 File CMSを作ってみます。
1ファイルに下記のものが全部入りです。

  • エディタ
  • データストア
  • ビュー

データストアは実行ファイル自身に埋め込みます。data.dbとか作りません。
Real 1 File CMSですね。

サーバサイド

下記のコマンドを実行して、サーバを立てます。

$ node index.html

下記URLを開くと、エディタが表示されます。
http://localhost:1337/

nodeside.png

クライアントサイド

index.htmlをそのままブラウザで開くと、フォームが非表示になります。
単なる静的ファイルですので、Dropboxに置いて公開しても動作します。

clientside.png

ソースコードは下記のとおりです。

<!--
http = require('http'),
    fs = require('fs'),
    qs = require('querystring');

http.createServer(function (req, res) {
    var someFile = "index.html";

    if (req.method === 'POST') {
        var body = '';
        req.on('data', function (data) {
            body += data;
        });
        req.on('end', function () {
            var poststr = JSON.stringify(qs.parse(body));
            fs.readFile(someFile, 'utf8', function (err, data) {
                if (err) return console.log(err);
                var processed = data.replace(/var data = {[^}]*};/g, 'var data = ' + poststr + ';');
                fs.writeFile(someFile, processed, 'utf8', function (err) {
                    if (err) return console.log(err);
                    res.write("{status: 'ok'}");
                    res.end();
                });
            });
        });
    } else {
        fs.readFile(someFile, 'utf8', function (err, data) {
            res.write(data);
            res.end();
        });
    }
}).listen(1337, "127.0.0.1");
console.log("http://localhost:1337/");
/*
-->

<html>
<head>
    <meta charset="UTF-8">
    <title>1File CMS</title>
    <script>var data = {"posts[]":[]};</script>
    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script>
    function reload(){
        $("#posts").html("");
        data["posts[]"].forEach(function(item){
            $("#posts").prepend("<pre>" + item + "</pre>");
        });
    }
    $(function(){
        $("#send").click(function(){
            var text = $("#contents").val();
            data["posts[]"].push(text);
            $.post("http://localhost:1337/", data, function(){
                reload();
            });
        });
        reload();
        if (document.location.hostname == "localhost"){
            $("#editor").show();
        }
    });
    </script>
    <style>
        body{
            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHUlEQVQIW2NkwAIY8Qq+fnz5v6isLlgRfpXIxgAA0iQEBsbFbSsAAAAASUVORK5CYII=);
        }
        .container{
            width: 900px;
        }
        textarea{
            margin: 20px;
            width: 96%;
        }
        button{
            font-size: 2rem;
            margin-left:20px;
        }
        #posts > pre{
            background: white;
            margin: 20px;
            padding: 20px;
            border-radius:3px;
            -webkit-border-radius:3px;
            -moz-border-radius:3px;
            box-shadow:rgba(153, 153, 153, 0.65098) 0px 1px 3px 1px;
            -webkit-box-shadow:rgba(153, 153, 153, 0.65098) 0px 1px 3px 1px;
            -moz-box-shadow:rgba(153, 153, 153, 0.65098) 0px 1px 3px 1px;
        }
        #editor{
            display: none;
        }
    </style>
</head>
<body>
<div class="container">
    <h1>1File CMS</h1>
    <div id="editor">
        <textarea id="contents" rows="20"></textarea><br>
        <button id="send">Send</button>
    </div>
    <div id="posts">
    </div>
</div>
</body>
</html>
<!--
*/
-->

30
27
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
30
27