量産メモ帳

忘れっぽいのでメモを残しています。

Node.js初心者が躓いたこと

スポンサーリンク

初めに

唐突ですが、今度はNode.jsも学び始めてみました。
開発環境を整えて、適当なサンプルをちょっとカスタマイズして、簡単なWebサーバーを立てた程度までしかやっていませんが、初めての言語は後で振り返ると初歩的な問題に躓くことが多いです。
そして、たまにしか使わない言語だと同じ問題で悩んだりします。
一方で、言語の習得がそこそこのレベルに到達すると、こういった問題に躓いたことすら忘れてしまいます。
そういったことを踏まえ、後々の自分のためにメモを残しておきます。

問題

Node.jsのインストール

これはPythonの時も悩みましたが、、、
rms-099.hatenablog.jp
Node.jsも3パターンぐらいあるようです。

この辺の話は別で記事を書こうと思っていますが、結局、NodeBrewを使ってインストールしました。

ReferenceError: exit is not defined - Node.jsコンソールの終了方法が分からない。

Node.jsがインストール済みならば、ターミナルで node コマンドを実行すれば、Node.jsのコンソールが開始します。
しかし、コンソールを終了しようとして単純に exit と入力すると、こんなエラーが表示されます。

ReferenceError: exit is not defined

また「control + C」キーを押すと、こんなヒントが表示されます。

(To exit, press ^C again or type .exit)

つまり、以下のいずれかでコンソールを終了できます。

  • 「control + C」キーの二度押し。
  • .exit の入力。

ちなみに .exitprocess.exit() の略っぽいです。

Node.jsコンソールからWebサーバーを起動できない。

結論から言うと、わざわざNode.jsコンソールを起動する必要はありません。
node コマンドの引数にスクリプトのファイルを指定するだけで起動できます。

例えば、以下のようなコードを記したファイル(server.js)を用意して、同じディレクトリで node server.js と実行すれば、ブラウザから http://localhost:8080 にアクセスできます。

var http = require('http');
var server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
})
server.listen(8080, '127.0.0.1');

index.htmlとserver.jsの関係がよく分からない。

こちらのサンプルとかを見れば、一目瞭然なんじゃないでしょうか。

index.html

<!doctype html>
<html>
    <body>
        <p>Hello world! Node is awesome, is it not?</p>
    </body>
</html>

server.js

var http = require('http');
var fileSystem = require('fs');
var server = http.createServer(function(req, resp){
    fileSystem.readFile('./index.html', function(error, fileContent){
        if(error){
            resp.writeHead(500, {'Content-Type': 'text/plain'});
            resp.end('Error');
        } else {
            resp.writeHead(200, {'Content-Type': 'text/html'});
            resp.write(fileContent);
            resp.end();
        }
    });
});
server.listen(8080);
console.log('Listening at: localhost:8080');

require is not defined - require()関数が見つからない。

require()関数が見つからない問題です。
StackOverFlowにこう書かれていました。

Node.jsはクライアント側(ブラウザ)ではなくサーバー側の技術であり、require()のようなNode.js特有の関数はブラウザ上では動きません。(意訳)

JavaScript=ブラウザ上で動くスクリプト」という先入観があると、真っ先に嵌るポイントですね。
確かにNode.js用に書いたスクリプトは、基本的にブラウザ上で動かせないようですが、後述するBrowserifyやwebpackなどを使えば、それも可能になるみたいです。
ちなみにrequireって、他の言語におけるimportみたいだなと思ったのですが、JavaScriptの世界では区別されているようですね。

custom function is not defined - 独自定義した関数が見つからない。

今度はrequire()のようなNode.js特有の関数ではなく、自分で定義した関数が見つからない時の話です。
要は、HTMLファイル(index.html)のscriptタグに指定したJSファイル(bargraph1.js)で定義している関数(barGraph())を認識できない、という問題でして、原因はJSファイルのパス解決に失敗しているためなのですが、path.resolve()とexpress.static()を使ってパス解決できるみたいです。

app.use(express.static(path.resolve(__dirname, '/')));

ここで出てくるExpressというのはNode.jsでは欠かせないフレームワークっぽいですね。

ちなみにExpressをインストールする時はgオプションを付けない方が良さそうです。

npm install express

document is not defined - DOMのdocumentが見つからない。

いわゆるDOMのdocumentが見つからない時に出るエラーです。

StackOverflowにも書かれていますが、そもそもDOMはクライアント側の技術なので、デフォルトだとアクセスできません。

ただし、BrowserifyやwebpackといったNode.jsのモジュールをブラウザ側で使えるフレームワークを用いれば、アクセスできるようです。

また、後述するJSDomというそれっぽいパッケージもあります。

jQuery requires a window with a document - jQueryの$関数が使えない。

jQueryの$関数をNode.jsでも使おうとした時に発生し得るエラーです。
こちらもStackOverflowに解決方法が載っていました。

以下のワンライナーで$関数が使えるそうです。

var $ = require('jquery')(require("jsdom").jsdom().parentWindow);

jsdomというのは、Node.js用のDOMパッケージのようですね。

localStorage - ローカルストレージにアクセスできない。

まず、自分がどちら側のローカルストレージにアクセスしたいのかによって、解決方法が違って来るんじゃないでしょうか。
つまり、クライアント側(ブラウザ)のローカルストレージなのか、サーバー側(Node.js)のローカルストレージなのか。
クライアント側(ブラウザ)のローカルストレージは Window.localStorage ですね。

一方、サーバー側(Node.js)のローカルストレージにアクセスする時は node-localstorage というものが用意されています。

こんな感じで使えます。

var LocalStorage = require('node-localstorage').LocalStorage,
localStorage = new LocalStorage('./scratch');

package.jsonやnode_modulesがない。

こちらに答えが掲載されていました。

まず npm init を実行して、必要なパッケージは npm install でインストールしなさい、と。
npm install を実行すると、node_modulesが作成されます。

ちなみにnpmはGo言語のGlideに似ていますね。

Linux系のパッケージ管理ツールは似たり寄ったりなのかもしれませんが、以下のように一対一でイメージできます。

npm glide
package.json glide.yaml
package-lock.json glide.lock
node_modules vendor
node init glide init
node install glide install

npmで何かエラーが出た。

npmのキャッシュをクリーンすれば良いみたいです。

npm cache clean

もし上のコマンドが失敗するなら、forceオプションを付けます。

npm cache clean --force