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

小ネタです。

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

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

```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](https://qiita-image-store.s3.amazonaws.com/0/32596/74497c32-bd20-3f48-1645-9dfbfda86e97.png)

クライアントサイド
-------

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

![clientside.png](https://qiita-image-store.s3.amazonaws.com/0/32596/3166673d-7466-2d5e-54e2-904f9b7562b2.png)



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

```html
<!--
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>
<!--
*/
-->

```

https://gist.github.com/hashrock/c2e2d345c95b9a3b7abe