概要
主にWEB開発でAjaxやjQueryが一般化する中、JavaScript開発が占める割合がとても大きくなりました。
とはいえ非WEB系のディベロッパー(業務系など)においては
JavaScriptで開発する際、どういう開発方法がスタンダードなのか、
今のやり方はおかしくないのか、と悩ましく思っている人も
多いのではないでしょうか。
今回はある程度安定して使えるJavaScript開発環境をというテーマでいってみます。
だいたいこんなことができる開発環境を構築します。
- ブラウザとテキストエディタでクライアントサイド(JavaScript)を開発する環境
- 作成したJavaScriptの結合・圧縮(よくwebサイトでありますよね。jquery.min.jsみたいな)
- 作成したCssの結合・圧縮
- JavaScriptの構文チェック
- jQueryプラグインを自動的にダウンロードして更新
- ブラウザのキャッシュでJavaScript/cssが更新されない問題の対応
今回はrequireJs・Backbone.js・AngularJS・coffee script・scssなどは使いません。
純粋にJavaScript/Cssでいきます。
ではいってみましょう。
開発に使うツールの準備
ブラウザ
JavaScriptを開発するのにはブラウザは断固Chromeです(汗。
IEでもFFでもOperaでもSafariでもなく。
というのもChromeについているChrome Developer Toolが優秀すぎる為です。
これさえあればなんとかなります。
とにかく使ったことがない人はこれを使って!
Chrome Developer Toolについてはドットインストールのサイトで使い方が学べます。
テキストエディタ
これはお好きなものを。
私はSublime Textを使っています。好きだから。
ツール
node.jsを使います。
node.jsの説明はgoogleで検索してください。
今回はnode.jsのパッケージ管理モジュールであるnpmを利用するために使います。
npmはBundlerやCPAN、brew、yum、rpmみたいなものです(雑すぎ)
例えばJavaScriptの構文チェックしてくれるモジュールのように
便利なモジュールをコマンド1つでダウンロード&インストールしてくれるものです。
node.jsのインストール手順はココからどうぞ。
Windowsな方はInstallerを使うといいですよ(PATHを通しておくと便利なので)
ソース管理
忘れちゃいけないソース管理。
gitを使います。VSS?SVN?いやgit使いましょうよ。ここは。
gitの使い方などはまたしてもドットインストールを参照。
ちなみに私はリモートリポジトリをcodebreakにおいています。
codebreakは無料でprivate設定できるので。ありがとうcodebreak。
Windowsな方はgitのインストールが必要です。
コマンドプロンプトから叩ければOKなので
ココを参考にinstall。
環境構築
gitの設定
まずgitの設定をしておきます。
コマンドラインより以下を発行します
git config --global url."https://".insteadOf git://
これはgitよりダウンロードする際、httpsを必ず利用する設定です。
(これを実施しておかないと後述するbowerでエラーが出ます)
npmの設定
まず作業フォルダを作成します。これがプロジェクトフォルダとなります。
そしてコマンドプロンプトとかターミナルとかを開いて作業フォルダに移動します。
ここでnpmを使ってプロジェクトの設定をします。
これをやっとくと、インストールしたモジュールを覚えてくれるので
例えば他のマシンに持って行く時も設定ファイルだけコピーすれば
あとは自動的にセットしてくれるようになります。
コマンドをたたきます。
npm init
するとプロジェクトの設定内容を聞かれます。
以下のような感じで入力します。
name: プロジェクト名を入力します。任意の名前を入力。 URLセーフな文字列しか使用できません。 version: プロジェクトのバージョンを入力します。 何もいれずにEnterでもOK description: プロジェクトの簡単な説明文を入力します。 何もいれずにEnterでもOK entry point: 迷わず、Gruntfile.jsと入力します。 test command: 何もいれずにEnterでもOK git repository: Gitレポジトリがあれば入力します。 何もいれずにEnterでもOK keywords: キーワードがあれば、カンマ区切りで入力します。 何もいれずにEnterでもOK author: 製作者名を入力します。 何もいれずにEnterでもOK license: ライセンスを入力します。 何もいれずにEnterでもOK
全部終わるとプロジェクトフォルダにpackage.jsonというファイルができます。
これがnpmの設定ファイルとなります。
さっそく、npmで必要なモジュールをインストールしましょう。
npm install -g bower npm install -g grunt-cli npm install grunt --save-dev npm install jshint --save-dev npm install grunt-bower-task --save-dev npm install grunt-contrib-jshint --save-dev npm install grunt-contrib-watch --save-dev npm install grunt-contrib-cssmin --save-dev npm install grunt-contrib-copy --save-dev npm install grunt-contrib-compress --save-dev npm install grunt-contrib-concat --save-dev npm install grunt-contrib-uglify --save-dev npm install grunt-cache-breaker --save-dev
いっぱい入れました。
後でくわしく解説しますが、入れたモジュールの概要だけ記載します。
bower
jQueryやjQueryプラグインなどをダウンロードしてくれる
grunt-cli
grunt
今回の目玉のgruntです。自動実行を制御するタスクマネージャ的なモジュールです。
これを使ってJavaScriptが変更されたら自動で圧縮とかを実現します。
jshint
JavaScriptの構文チェックをしてくれます。
セミコロンの要不要などからはじまりいろいろ構文チェックしてくれます。
すべてのJavaScriptはjshint等のチェッカーを通すべき。
とにかく使いましょうね。
grunt-bower-task
gruntでbowerを実行するためのプラグインです。
grunt-contrib-jshint
gruntでjshintを実行するためのプラグインです。
grunt-contrib-watch
gruntでファイルの変更を監視してジョブを実行するプラグインです。
JavaScriptを修正したら自動的に圧縮とかさせるために使います。
grunt-contrib-cssmin
grunt-contrib-copy
grunt-contrib-compress
grunt-contrib-concat
grunt-contrib-uglify
JavaScriptとCSSを結合・圧縮するプラグイン達です。
grunt-cache-breaker
html上に記載されたscriptタグを見つけて、URLの後ろに日時などを自動的に
セットするプラグインです。
ブラウザキャッシュで変更が反映されないのを防ぎます。
なおnpmのオプションですが-gをつけるとマシン全体に反映となります。
逆に-gをつけないとそのプロジェクトにだけ反映となります。
–save をつけるとpackage.jsonにインストールしたものを記録します。
他マシンにはpackage.jsonだけコピーしてnpm installとすると
package.jsonに記録されているモジュールを全部インストールしてくれるので
基本的に–saveはつけましょう。
–save-devは開発環境だけに反映するオプションです。
インストールしたモジュールはプロジェクトフォルダの
node_modulesというフォルダに格納されています。
このフォルダはpackage.jsonがあれば作成可能なので
ソース管理は不要です。
Bowerの設定
bowerはjQueryのプラグイン等をダウンロードして
プロジェクトに入れてくれるモジュールです。
jQuery本体やBootstrapもbowerから取得することができます。
いちいちページを見に行ってダウンロード→解凍→コピーしなくてすみます。
またバージョンアップも簡単なのでぜひ使いましょう。
(ただbower対応できていないpluginもたくさんあります)
bowerを使うにはまずインストールが必要です。
じつは上記npmのところでbowerをインストール済みです。
なのでいきなりコマンドラインからbowerを打てます。
bowerの初期設定をします。
bower init
設定内容を聞かれるので以下のように。
name: [bower_test] →自分のライブラリの名前。 何も入力しないでEnterでOK version: [0.0.0] →バージョン。 何も入力しないでEnterでOK main file: [] →自分のライブラリのエンドポイント 深く考えずapp.jsとでも打っておきましょう。 add commonly ignored files to ignore list? (y/n): [y] →公開時に不要と思われるファイルを不要リストに追加するかどうか 何も入力しないでEnterでOK
入力が終わるとプロジェクトフォルダにbower.jsonが作成されます。
さっそく、bowerを使ってjQueryとbootstrapを取得しましょう。
bower install jquery --save bower install bootstrap --save
–saveをつけてinstallを実行するとbower.jsonにモジュール名とバージョンが記録されます。
これでbower.jsonファイルがあれば同じことを他のマシンでもできますね。
bower installするとプロジェクトフォルダにbower_componentsというフォルダが作成されます。
この中に各モジュールが入っています。
このフォルダはbower.jsonがあれば作成可能なので
ソース管理は不要です。
Grunt(自動実行)の設定
ここまででインストールが終わりました。
つぎに肝心の自動実行の設定をします。
まずはbowerでjQueryをダウンロードして
プロジェクトフォルダに反映する、という作業を自動化しましょう。
プロジェクトフォルダは以下のような構成とします。
project_hoge
– bower_components
– bower installでインストールしたモジュール
– node_modules
– npm installでインストールしたモジュール
– public ここをWEBで公開する。
– css
– 自分で作ったcss
– dist
– 圧縮後のJavaScript/CSSを配置する予定。
– img
– 画像ファイルとか
– lib
– jQueryとか
– js
– 自分で作ったJavaScript
– index.html
今はjQueryはbower_componentsフォルダに入っています。
これをpublic/lib配下に持っていくようにgruntに設定をします。
プロジェクトフォルダの直下にGruntfile.jsというテキストファイルを
作成してください。
そして以下の記述をします。
'use strict'; module.exports = function(grunt) { grunt.initConfig({ bower: { install: { options: { targetDir: 'public/lib', layout: 'byType', install: true, verbose: false, cleanTargetDir: false, cleanBowerDir: false } } }, }); grunt.loadNpmTasks('grunt-bower-task'); grunt.registerTask('compile', [ 'bower:install' ]); };
grunt.initConfigの中にbowerを記述しています。
こんな感じでgruntで自動実行するジョブを登録していきます。
optionsにいろいろ設定していますが
targetDirの部分が出力先フォルダになります。
optionsの指定はいろいろできますので調べてみてください。
grunt.loadNpmTasks(‘grunt-bower-task’);
の部分はgruntでbowerを使うためのプラグイン、grunt-bower-taskを定義しています。
grunt.registerTask(‘compile’, [
‘bower:install’
]);
の部分はgruntのコマンド自体を定義しています。
この場合はコマンドラインで grunt compileと実行するとbower:installを実行するようになります。
registerTaskは何個も登録できるのでcompile_dev とか作ってみてもいいです。
作成できたら実行してみましょう。
grunt compile
public/lib配下にjQueryが保存されたと思います。
bower.jsonの中に記録されているモジュール、バージョンをもとに実行しているので
bower.jsonを変えることで例えばjQueryのバージョンを上げるということも簡単になります。
Gruntを使ってJavaScriptの構文をチェック
まずはGruntfile.jsを編集します。
'use strict'; module.exports = function(grunt) { grunt.initConfig({ bower: { install: { options: { targetDir: 'public/lib', layout: 'byType', install: true, verbose: false, cleanTargetDir: false, cleanBowerDir: false } } }, jshint: { files: ['public/js/**/*.js'], options: { globals: { jQuery: true, console: true, module: true, document: true, }, debug: true, expr : true, } }, }); grunt.loadNpmTasks('grunt-bower-task'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.registerTask('compile', [ 'bower:install', 'jshint', ]); };
jshintの部分がいろいろ増えていますね。
public/js配下の「.js」がつくファイルすべてを対象にチェックするようにしています。
optionsの部分は構文チェックの内容になります。
jshintのサイトを見ながら調整してください。
実行は前回と同じです。
grunt compile
js配下になにかscriptを置いて試してみましょう。
構文で気に食わないものがあると構文エラーとエラーの理由が出ると思います。
Gruntを使ってJavaScriptを結合・圧縮
JavaScriptファイルが増えてくるとHTML上にscriptタグを書くだけで大変ですし
たくさんのscriptを読み込むのはレスポンス低下にもつながります。
また、JavaScriptソースそのままだと利用者からソースをのぞかれてしまうという
問題もあります。
こういった問題を解決するため、JavaScriptファイルを全部くっつけて
1ファイルにし、空白や改行を取り除いて難読化して配布するということがあります。
これをやってみましょう。
Gruntfile.jsの編集です。
'use strict'; module.exports = function(grunt) { grunt.initConfig({ // js concat concat: { multiple_file: { files: { 'public/dist/plugin.js': ['public/lib/jquery/jquery.js', 'public/lib/**/*.js'], 'public/dist/page.js': ['public/js/**/*.js'], } } }, // js compress uglify: { options: { banner: '/*! hoge project <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, dist: { files: { 'public/dist/plugin.min.js': 'public/dist/plugin.js', 'public/dist/page.min.js': 'public/dist/page.js', } }, (省略...) }); (省略...) grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('compile', [ 'bower:install', 'jshint', 'concat', 'uglify', ]); };
concatはその名のとおり、複数ファイルを1ファイルにまとめます。
uglifyは空白や改行を取り除く圧縮を行います。
まずconcatでjQueryやjQueryプラグイン等をpublic/dist/plugin.jsというファイルにまとめます。
この時、多くのjQueryプラグインはjQueryが先にないとエラーになるので
まずjQuery.jsをまとめて、そのあと全部、という指定をしています。
この辺りの依存関係はrequireJS等を使うといいかもしれません。
まだ未対応なpluginも多く私は現時点ではあまりおすすめしませんが。
uglifyの方は見たままですね。plugin.jsをplugin.min.jsという名前で圧縮してます。
実行はいつも通り、grunt compileですね。
public/distにjsができていればOKです。
これをhtmlから読み込ませれば少ないファイル読み込みですみますね。
Gruntを使ってCSSを結合・圧縮
続いてCSSです。
'use strict'; module.exports = function(grunt) { grunt.initConfig({ cssmin : { compress : { src : ['public/css/*.css'], dest : 'public/dist/style.min.css' } }, (省略...) }); (省略...) grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.registerTask('compile', [ 'bower:install', 'jshint', 'concat', 'uglify', 'cssmin:compress', ]); };
今度は簡単ですね。
cssminを利用すればこれだけでOKです。
実行してpublic/dist/style.min.cssができていることを確認しましょう。
Gruntを使ってブラウザキャッシュを防ぐ
JavaScriptやCSSを更新したのに
ブラウザキャッシュのせいで反映されない!
というよくあるやつですね。
よくscriptタグのURL部分の後ろに?version=1.1のようにつけて
キャッシュを回避する方法がありますがあれの自動化になります。
Gruntfile.jsを編集します。
'use strict'; module.exports = function(grunt) { grunt.initConfig({ cachebreaker: { dev: { options: { match: ['dist/*.js', 'dist/*.css'], }, files: { src: ['public/*.html'] } } }, (省略...) }); (省略...) grunt.loadNpmTasks('grunt-cache-breaker'); grunt.registerTask('compile', [ 'bower:install', 'jshint', 'concat', 'uglify', 'cssmin:compress', 'cachebreaker:dev', ]); };
matchの部分に記載した文字列が
files:srcの部分に記載したhtmlファイル上に現れた時、
htmlを自動的に編集してscriptタグやstyleタグのURL部分に「?日付」などを追加します。
URL部分につける文字は日付だけでなくバージョンなどにもできます。
くわしいoptionはcachebreakerのサイトで確認してください。
Gruntでソースを修正したら自動コンパイルさせる
ソース直しながらcompileを発行するのは面倒!
ですかね…そうでもないと思いますけど。。。
横着な方への自動実行方法です。
'use strict'; module.exports = function(grunt) { grunt.initConfig({ watch: { tasks: ['jshint', 'cssmin:compress', 'concat', 'uglify', 'cachebreaker'], files: ['public/lib/**/*.js', 'public/js/**/*.js', 'war/css/*.css'] }, (省略...) }); (省略...) grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('compile', [ 'bower:install', 'jshint', 'concat', 'uglify', 'cssmin:compress', 'cachebreaker:dev', 'watch' ]); };
パッと見でわかるかと思います。
watchのタスクはgruntのタスク名を設定します。
filesのところに監視対象ファイルを指定します。
例えばpublic/js配下のjsファイルを修正すると
自動的にjshint/cssmin/concat/uglify/cachebreaker
が実行されるようになります。
コマンドラインからgrunt compileすると
変更待ち状態になります。
jsを編集してみると自動実行されるのがわかると思います。
テスト用WEBサーバを立てる
node.jsを利用すればWEBサーバも簡単に立てられます。
npmでインストールしましょう。
npm install connect --save-dev npm install serve-static --save-dev
次にプロジェクトフォルダの直下に「server.js」というファイルを作成し
以下の内容を記述します
var connect = require('connect'); var serveStatic = require('serve-static'); var app = connect(); app.use(serveStatic('public')); app.listen(3000);
サーバの起動はコマンドラインより
node server.js
これでブラウザからlocalhost:3000と打つと
webページを開くことができます。
たった5行でwebサーバが立つんですねぇ…
ソース管理の設定
あとはgitですね。
プロジェクトフォルダで以下のコマンドを実行します。
git init
次にプロジェクトフォルダ直下に「.gitignore」 という名前でファイルを作成し
中に以下を記述します。
bower_components/**/* node_modules/**/*
これはgit管理するフォルダより
bower_components
node_modules
配下を除外する指定になります。
いずれもbower.json/package.jsonがあれば作成可能なので
ソース管理の必要がない、ということです。
あとはgitの操作でコミットしてプッシュしておきましょう。
git add . git commit -m "first commit" git push リモートリポジトリのURL master
他のPCに展開
作成した環境を他のPCに展開します。
node.jsはインストールしておいてください。
あとはnpmの-g指定した以下を実行してインストールします。
npm install -g bower npm install -g grunt-cli
次に、ソースファイル一式をgitから取得しましょう。
git clone リモートリポジトリのURL
カレントディレクトリを取得したプロジェクトの位置に移動して以下を実行します。
npm install bower install
これでgruntを実行できるようになっているはずです。
これだけでOK!簡単ですね。
あとがき
ちょっと長くなってしまいましたが、JavaScriptの開発環境の構築方法でした、
例ではhtml/css/javascriptだけの構成でしたが、当然サーバサイドのソースとの
共存も可能です。
私はstruts系やgaeなどでもクライアントサイドをこの構成にしています。
またgruntに組み込むことでcoffee scriptやscssといったプリコンパイルの実行も
簡単になります。
開発効率の向上には欠かせませんのでぜひ試してみてください。