Edited at

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

More than 3 years have passed since last update.

小ネタです。

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

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