Help us understand the problem. What is going on with this article?

Javaな人向けクライアントサイドJavaScript開発入門

More than 1 year has passed since last update.

はじめに

Java界隈でご飯を食べている私ですが、最近クライアントサイドJavaScriptでの開発(というかnpm)について勉強する機会があったので手順を整理して共有します。

この記事は次のような(ちょっと前の私みたいな)人に向けたチュートリアルです。

  • 古めのJavaScriptの知識ならある人(旧石器時代に生きている人)
    • jsは公式サイトからDL・配置してhtmlファイルにscriptタグを並べて読み込むものだと思っている(それ以外に何があるのだ?)
    • jQueryならある程度は書けるんだけど
  • フロント界隈の記事を読むとサッパリ分からん な人
    • npmとかrequireとかよく見るけどよくわからん
  • Java界隈を軸に活動している人

ここに書いてあることすらもはや古臭くなりつつある感じがしますが、旧石器時代よし少しは前に進めるのではないかと思います。

また、ここに書いてあるのは開発手法の1例であって、これがスタンダードなわけじゃないよ、ということは補足しておきます。

さらに、私も勉強始めたばかりなので、間違ってたり非推奨だったりベターな方法が他にあれば指摘していただけると嬉しいです。

チュートリアル

必要なもの

  • お気に入りのテキストエディタ
  • 15分から20分程度

Node.jsインストール

最近のフロントエンド開発はNode.jsなしにはありえません。Node.jsと言うとExpressなどに代表されるサーバサイドの実行環境としての情報も混じってくるので初めは混乱しやすいですが、クライアントサイド開発におけるNode.jsはコンパイラや周辺ツールを動かす開発環境です。JavaでいえばJDKの位置づけかな?

ということでNode.jsをインストールしましょう。Windowsなら以下からインストーラをダウンロードして実行してください。

他のOSはパッケージマネージャから導入するのが良いでしょう。

プロジェクト作成

アプリのプロジェクトを作成します。便宜的にfront-devという名前で説明します。

プロジェクト用のディレクトリを作成し、ターミナルからnpm initコマンドを実行します。gradle initmvn archetype generateのnodeバージョンだと思えばよいかと。

コマンド実行
cd 好きなディレクトリ
mkdir front-dev
cd front-dev
npm init
(色々聞かれるが、Enterキー連打)

npmコマンドはNode.jsをインストールすると(特別に設定しない限り)一緒にインストールされます。

色々聞かれますがここでは適当に全部エンターを押してしまってください。

この時点でfront-devフォルダ配下にpackage.jsonが作成されます。依存パッケージなどは後々このファイルに書いていきます。Javaでいうpom.xmlのようなものですね。

front-dev/package.json
{
  "name": "front-dev",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

色々書いてありますが今回はscripts以外使わないので大胆に消してしまいましょう。

front-dev/package.json
{
  "scripts": {
   }
}

npm-scripts

package.jsonを以下のように書き換え、npm run hogeを実行してみてください。画面にHOGEHOGEと表示されるはずです。

front-dev/package.json
{
  "scripts": {
    "hoge":"echo HOGEHOGE"
   }
}
コマンド実行
> npm run hoge

> @ hoge C:\Users\tatesuke\Desktop\front-dev
> echo HOGEHOGE

HOGEHOGE

このように、package.jsonscriptsにコマンドを定義しておくとnpm run 名前でそのコマンドを実行することができます。ビルドスクリプトの起動などに使います。

ちなみに、startという名前のscriptは特別で、npm startのようにrunを省略して実行することができます。

依存モジュールのインストール

Javaでは依存モジュールのjarをダウンロードしてクラスパスに配置して・・・という作業はもはや時代遅れで、依存性管理はmavenやgradleに任せるようになりました。フロントエンドでも同様で、自分でjsファイルをダウンロードして利用するという方法はもはや時代遅れです。依存性解決はnpmに任せます1
package.jsonを以下のように変更してください。

front-dev/package.json
{
  "scripts": {
    "hoge": "echo HOGEHOGE"
  },
  "dependencies": {
    "jquery": "^3.2.1"
  }
}

このように、dependencysブロックに依存パッケージを定義することで、npmが依存性を管理してくれます。この例ではjQueryへの依存を定義しています。

依存モジュールをインストールするにはnpm installコマンドを実行します。

コマンド実行
npm install

※WARNINGが出ますがこのチュートリアルでは無視します。

front-devフォルダ配下にnode-modulesというフォルダが作成され、その中にjQueryのソースなどがダウンロードされます。

ディレクトリ構成
front-dev
│  package.json
│
└─node_modules
    └─jquery

依存モジュールの使用(scriptタグ)

インストールしたパッケージを利用する最も簡単で原始的な方法はscriptタグを利用することです。

以下のようなhtml、jsファイルを作成してブラウザで開いてください。

front-dev/index.html
<!doctype html>
<head>
    <meta charset="utf-8">
    <title>ハローフロントエンド</title>
</head>
<body>
    <div id="container"></div>

    <script src="node_modules/jquery/dist/jquery.js"></script>
    <script src="index.js"></script>
</html>
front-dev/index.js
(function($){
    $("#container").text("jQuery is work!");
})(jQuery);

jQueryが利用できていることがわかると思います。

image

依存モジュールの使用(require)

npmで管理するパッケージを利用するもっと最近っぽい方法はrequireを利用する方法です。package.jsonに定義した依存パッケージはcommon.jsのrequire関数で読み込む事ができるのです。

先程のhtml、jsを以下の通り変更してください。

front-dev/index.html
<!doctype html>
<head>
    <meta charset="utf-8">
    <title>ハローフロントエンド</title>
</head>
<body>
    <div id="container"></div>

<!--    jqueryのjsを読み込むのをやめる
    <script src="node_modules/jquery/dist/jquery.js"></script>
-->
    <script src="index.js"></script>
</html>
front-dev/index.js
var jQuery = require("jquery"); //requireでjqueryを読み込む

(function($){
    $("#container").text("require is work!");
})(jQuery);

これをブラウザで開くと無事にjQueryが利用でき・・・ません!!

image

requireの使用

実はブラウザにはrequire関数が実装されていないので動かないのは当然です。ブラウザでrequireを利用できるようにしなければなりません。それにはいくつかのメジャーな方法があります。

  • RequireJSを利用する
  • Browserifyを利用する
  • Webpackを利用する

ここではBrowserifyを使った方法を説明します。

Browserifyはrequireを使ったjsをブラウザで実行でるように変換するツールです。

Browserifyのような周辺ツールもnpmを使ってインストールできます。'package.json'を以下のように変更してください。

front-dev/package.json
{
  "scripts": {
    "hoge": "echo HOGEHOGE"
  },
  "dependencies": {
    "jquery": "^3.2.1"
  },
  "devDependencies": {
    "browserify": "^14.1.0"
  }
}

実行時には使用しないけれどプロジェクトとして利用するツール類はこのようにdevDependenciesブロックに記述します。mavenで言う「test」や「provided」スコープ、gradleでいう「testCompile」に近いものですね。

続けてmpn installを実行します。

コマンド実行
npm install

これでnode_modules配下にBrowserify(と、Browserifyが依存するモジュール)がダウンロードされました。早速使ってみましょう。次のコマンドを実施してください。

コマンド実行
./node_modules/.bin/browserify index.js > out.js

これでrequireで参照されるモジュールをひとまとめにして使えるようにしたout.jsが出力されました。index.htmlを以下のように変更してブラウザで開いてください。

front-dev/index.html
<!doctype html>
<head>
    <meta charset="utf-8">
    <title>ハローフロントエンド</title>
</head>
<body>
    <div id="container"></div>

<!--    Browserifyで生成したout.jsを読み込むようにする
    <script src="node_modules/jquery/dist/jquery.js"></script>
        <script src="index.js"></script>
-->
    <script src="out.js"></script>
</html>

無事にrequireで読み込んだjQueryが利用できたはずです。

image

蛇足ですが、私はこのようにJavaScriptからJavaScriptに変換するという感覚をつかむのに時間がかかりました。やってみたらなんだそんなことかという感じなのですが

npm-script

毎回先程のようなコマンドを打つのは面倒くさいので、npm-scriptとして記述してしまいましょう。

front-dev/package.json
{
  "scripts": {
    "build": "browserify index.js > out.js"
  },
  (略)
}

scriptsブロックではdependencysやdevDependenciesに記述されたモジュールは./node_modules/.bin/を省いて記述できます。これで、npm run buildでBrowserifyを実行できるようになります。試してみてください。

ビルドスクリプト(Gulp)

実際の開発ではLint(構文チェック)をかけてBrowserifyかけてminify(圧縮)かけて、なんならCSSもSASSやLESSからコンパイルかけて・・・などと、手順が複雑になります。これを行うのにnpm-scriptだけでは役不足です。要するにフロント開発にもビルドスクリプトが必要なのです

JavaScript界隈のビルドツール・タスクランナーはたくさんありますが2大巨塔は以下です。

  • Grant
  • Gulp

ここではGulpの利用してみましょう。もし、エディタでpackage.jsonを編集していたらそれを閉じてから、次のコマンドを実行してください

コマンド実行
npm install --save-dev gulp

いままでは依存モジュールを利用するときにpackage.jsonに依存性を記述してからnpm installを実施していましたが、このように--save-devオプションを付けるとpackage.jsondevDependenciesに追記+npm installを一括で実施してくれます。package.jsonを見ると自動的にgulpが記述されているはずです。

front-dev/package.json
{
  (略)
  "devDependencies": {
    "browserify": "^14.1.0",
    "gulp": "^3.9.1"         // ←ここが自動で追加されている
  }
}

補足ですが、--saveオプションを付ければ同様にdependenciesに追記+npm install`を一括で実施してくれます。

AngularJSをインストールする例(例なので実施しなくてよい)
npm install --save angular

話を戻してビルドスクリプトに戻します。gulpのビルドファイルgulpfile.jsを作成してください。

front-dev/gulpfile.js
var gulp = require("gulp");
var browserify = require("browserify");
var fs = require("fs");

gulp.task("build", function() {
    var out = fs.createWriteStream('./out.js');

    browserify({
        entries: ['index.js']
    })
    .bundle()
    .pipe(out);
});

buildというタスクでbrowserifyを呼び出しています。これをpackage.jsonで呼び出すようにします。

front-dev/package.json
{
  "scripts": {
    "build": "gulp build"
  },
 (略)
}

これでnpm run buildでgulpを起動してビルドできるようになりました。試してみてください。

コマンド実行
npm run build

開発用サーバ

今やJavaScriptの開発でもWebサーバーが必須になってきます。例えばAngularJSのui.routerなんかはWebサーバがないと動きません。しかし、そんなに面倒臭がる必要もありません。開発用サーバもnpmで準備できるからです。

開発用サーバも山のようにありますが、ここではsuperstaticというモジュールを利用してみます。

コマンド実行
npm install --save-dev superstatic

ビルドスクリプトの末尾にサーバー起動用のスクリプトを追記してください。

gulpfile.js
(略)
var superstatic = require('superstatic');
gulp.task("serve",  ["build"], function () {
    superstatic.server({
        port:3000
    }).listen();
});

npmから呼び出せるようにします。

front-dev/package.json
{
  "scripts": {
    "build": "gulp build",
    "serve": "gulp serve"
  },
 (略)
}

これでnpm run serveを実行するだけでソースコードをビルドしてhttpサーバ起動します。コマンドを実行したあと、以下URLにアクセスすると、index.htmlが表示できるはずです。

コマンド実行
npm run serve

http://localhost:3000/

watch

開発時には、修正→確認→修正→確認・・・というサイクルを繰り返す事になります。このとき、毎回手動でビルドコマンドを呼び出すの億劫です。そのため、大抵の場合、ソースに変更があったら自動的にビルドを実行する仕組みを導入することになるでしょう。

grup.watchを使うと指定ファイル・ディレクトリに変化があったときにタスクを自動的に実行できます。ビルドスクリプト末尾に以下を追記してください。

gulpfile.js
(略)
gulp.task("watch",  ["serve"], function () {
    gulp.watch("./index.js", ["build"]);
});

例によって、package.jsonにも追記します。

front-dev/package.json
{
  "scripts": {
    "build": "gulp build",
    "serve": "gulp serve",
    "watch": "gulp watch"
  },
  (略)
}

これで、npm run watchするとビルド→httpサーバ起動⇢index.jsに変更があると自動的に再ビルドを行ってくれます。

試しにnpm run watchした状態でindex.jsを適当にいじってみてください。ブラウザを更新すると変更が反映されているはずです。

コマンド実行
npm run watch

チュートリアルは以上で終了です。

雑多に補足

Bower

npmと同様にパッケージの依存解決を行うツールにBowerがあります。以前は流行っていたようですが、最近は失速気味?でもBowerを使ってるプロジェクトはまだまだあるので、bowerという単語を見ても慌てず「あー依存性管理のやつね」と思えばいいと思います。

トランスパイラ、コンパイラ

最近、ES6(ES1025)やらTypeScriptという単語をよく聞きます。ES6は新しい仕様のJavaScriptで、TypeScriptはJavaScriptを拡張したプログラミング言語です。「ES6+Babel+Browserifyで開発」とか「TypeScript+Webpack」とか見るとひどくややこしく感じます。が、どちらもブラウザで認識できない形式のコードで実装して、最終的にブラウザが実行できる形のjsに変換するという点を理解してしまえばそんなに難しい話ではありません。

ES6を使った開発では、ES6形式のコードをブラウザが実行できる形に変換(トランスパイル)します。

ES6で書いたコードを書く
↓
(Babel+Browserify)
↓
ブラウザで実行できるコード

TypeScriptを使った開発では、TypeScript形式のコードをブラウザが実行できる形に変換(コンパイル)します。

TypeScriptで書いたコード
↓
(TypeScriptコンパイラ)
↓
ブラウザで実行できるコード

ちなみに今回のチュートリアルで行った手順は

requireを使ったコード
↓
(Browserify)
↓
ブラウザで実行できるコード

同じことですね。

そしてトランスパイラもコンパイラもBrowserifyと同じようにもnpmで管理できるので気軽に試せます。そんなに恐れる必要もないなと思いました。

ディレクトリ構成について

プロジェクトのディレクトリ構成について、これといったものが決まったものはないみたいです。今回は全部ルート配下で作業してしまいましたが、本来はJavaと同じようにsrcフォルダとbuildフォルダに分けて、ソースとビルド成果物を明確に分けるのが良い方法でしょう。

グローバルインストール

npm install -savenpm install --save-dev のほかにもnpm install -g パッケージ名というコマンドをたたくことができます。-gはグルーバルという意味で、グローバルに機能をインストールします。npm install -g browserifyのように叩くとbrowserifyを普通にコマンドで直接叩くことができるようになります。

以下のコマンドを実行してください。

> browserify index.js > out.js
('browserify' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。)
> npm install -g browserify`
> browserify index.js > out.js

npm install -g後はbrowserifyをコマンドとして叩けるようになっているのがわかると思います。

終わりに

チュートリアルはいかがだったでしょうか。
私は用語がわけわからな過ぎて無意識にフロント界隈を避けて通ってきましたが、今回このチュートリアル程度の内容を勉強して、なんだそれだけのことだったのかと思う部分が多かったです。
最先端のモダンJavaScriptとまではいきませんが、旧跡時代のJavaScriptからは一歩抜け出せたんじゃないかな、と思います。
この内容がどなたかの参考になればうれしいです。


  1. 今更ですが、npmはNode Package Managerの略でNode.jsのパッケージ管理システムです。JavaとMavenの関係に似てます。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away