Express入門 〜express-generatorの使い方〜
Node.jsのWebフレームワーク Express
ベースのアプリ雛形を作成するツール express-generator
をさわってみた。
下記の記事を読んだテイで書く。
express-generator
のインストール
$ npm install -g express-generator $ ndenv rehash # ndenvを使っている人は
RailsのScaffoldのように使用できる。
サンプルアプリの作成
以下の順で記載する。
- express-generatorの使い方
- express-generatorで雛形作成
- ディレクトリ構造
- 実行と確認
- コードを見てみる
express-generatorの使い方
$ express --help Usage: express [options] [dir] Options: -h, --help output usage information --version output the version number -e, --ejs add ejs engine support --pug add pug engine support --hbs add handlebars engine support -H, --hogan add hogan.js engine support -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) -c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore -f, --force force on non-empty directory
express-generatorで雛形作成
ExpressのデフォルトのView Template Engine は Jade
だが、 Jadeは Pug
にリネームされた。
今後、ExpressのデフォルトのView Template EngineはPugに置き換えられるため、ここでは Pug
を使用する。
また、ここではCSSメタ言語としてSASSを使用する。
$ express express-generator-sample --view=pug --css=sass --git create : express-generator-sample create : express-generator-sample/package.json create : express-generator-sample/app.js create : express-generator-sample/.gitignore create : express-generator-sample/public create : express-generator-sample/routes create : express-generator-sample/routes/index.js create : express-generator-sample/routes/users.js create : express-generator-sample/views create : express-generator-sample/views/index.pug create : express-generator-sample/views/layout.pug create : express-generator-sample/views/error.pug create : express-generator-sample/bin create : express-generator-sample/bin/www create : express-generator-sample/public/javascripts create : express-generator-sample/public/images create : express-generator-sample/public/stylesheets create : express-generator-sample/public/stylesheets/style.sass install dependencies: $ cd express-generator-sample && npm install run the app: $ DEBUG=express-generator-sample:* npm start $ cd express-generator-sample/ $ npm install
express <プロジェクト名>
コマンドでExpressの雛形プロジェクトが作成される。
npmのpackage.jsonが作成されているので「npm install」でモジュールをインストールする。
npm start
コマンド(package.jsonにて定義)で node ./bin/www
が実行され、サービスが起動する。
「./bin/www」には、Express.jsでHTTPサービス(3000番ポート)が起動するJavaScriptがコーディングされており、「app.js」に記述されたサービスが実行される。
ディレクトリ構造
$ tree . ├── app.js # メインJavaScript ├── bin/ # サービス起動JavaScript(www)置き場 ├── node_modules/ # npmモジュール置き場 ├── package.json ├── public/ # 公開ディレクトリ │ ├── images/ │ ├── javascripts/ │ └── stylesheets/ │ └── style.sass ├── routes/ # ルーティング先のスクリプト置き場(MVCのCとロジックに相当) │ ├── index.js │ └── users.js └── views/ # View用のコード置き場(MVCのVに相当) ├── error.pug ├── index.pug └── layout.pug
実行と確認
# 実行 $ npm start
# 確認 $ curl localhost:3000 <!DOCTYPE html><html><head><title>Express</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>Express</h1><p>Welcome to Express</p></body></html> $ curl localhost:3000/users respond with a resource
コードを見てみる
app.js
- 各種ライブラリのロード(
var xxx = require('xxx');
) - ルーティング先コントローラ層ロジックのロード(
var xxx = require('./routes/xxx');
) - Express本体オブジェクトの作成と設定(
var app = express();
)- View Template Engine(
Pug
) の設定 - ロガー、パーサー、公開ディレクトリの設定
- ルーティン部先ロジックの設定(
app.use('/xxx', xxx);
) - エラーハンドリングの設定
- View Template Engine(
index.js
users.js
style.sass
Spring BootでJUnitテスト
Spring Bootのテストについて書く。
spring-boot-starter-testを使用するとコントローラのJUnitテストも可能になる。
テストやコードインスペクションレポートのMaven設定は以下を参照。
テスト対象アプリ
以下の記事で紹介した入門アプリをテスト対象とする。
テストの作成
以下を作成する。
- com.pepese.sample.service.HelloServiceTest
- コントローラへDIされるサービスクラスのテスト
- com.pepese.sample.controller.HelloControllerTest
- コントローラのテスト
サービスのテスト(com.pepese.sample.service.HelloServiceTest)
ポイントは以下。
@RunWith(SpringRunner.class)
アノテーション- Spring BootでJUnitテストするときはコレをつける
@SpringBootTest
アノテーション- SpringのJava/XML Based Configurationなどの設定を読み込んでくれる
Springの設定(Java/XML Based Configuration)を読み込んでいるのでDIでテスト対象のインスタンスを取得できる。
コントローラのテスト(com.pepese.sample.controller.HelloControllerTest)
ポイントは以下。
@AutoConfigureMockMvc
アノテーションをつけるとコントローラ層のモック(MockMvc
)を作成でき、これでコントローラのJUnitテストが可能になる@WebMvcTest(HelloController.class)
としてコントローラクラスを指定することもできる
@MockBean
でコントローラ内でDIされるモジュールのモック(Mockito)を作成できるwhen
メソッド等(Mockito)を使用してコントローラ内にDIされたモジュールの挙動を指定できる- HamcrestのMatchersを使用してassertする
テストの実行
基本的には mvn test
で実行可能だが、特定のクラスを指定してテストしたい場合は mvn clean test -Dtest=*.HelloControllerTest
のように指定して実行できる(正規表現の指定可能)。
また、 mvn clean test -Dtest=*.HelloControllerTest,*HelloServiceTest
のようにカンマ区切りで複数指定することもできる。
webpack + Babel 入門
webpack + Babel で ES6(ECMAScript 2015)をトランスパイルしてブラウザで動くまでをまとめる。
以降を記載する。
- サンプルが動くまで
- サンプルが動くまでの手順
- 説明
- 上記の手順の説明
サンプルが動くまで
ブラウザに「Hello World !」とポップアップが出るサンプルを作成する。
前提
$ npm -v
4.0.2
プロジェクトの作成
$ mkdir es6-sample $ cd es6-sample $ npm init -y $ npm install --save-dev \ webpack \ babel-cli \ babel-core \ babel-preset-env \ babel-preset-es2015 \ babel-polyfill \ babel-loader \ webpack-dev-server $ mkdir src; touch src/app.js $ mkdir dist; touch dist/index.html $ touch webpack.config.js $ touch .babelrc
トランスパイル後のディレクトリ構造は以下のようになる。
$ tree -a -I 'node_modules' . ├── .babelrc ├── dist │ ├── app.bundle.js │ ├── app.bundle.js.map │ └── index.html ├── package.json ├── src │ └── app.js └── webpack.config.js
以降、各ファイルの内容を記載する。
package.json
npm run build
でES6のトランスパイル、npm run start
で簡易Webサーバが起動する。
.babelrc
ここでトランスパイル対象の種類を指定する。
webpack.config.js
webpackの設定ファイル。
npm run build
でES6のトランスパイル、npm run start
で簡易Webサーバが起動するように package.json
にスクリプトを設定している。
index.html
トランスパイル後のJSコードをロードしている。
app.js
実行方法
npm run build
でトランスパイルnpm run start
で簡易Webサーバの起動http://localhost:8080/webpack-dev-server/
へブラウザでアクセス- 「Hello World !」とポップアップが出れば成功
説明
Babelのインストール
npm install --save-dev babel babel-preset-es2015
babel
はトランスパイラだが、これだけだとまだ何をトランスパイルするのか分からない。
babel-preset-es2015
を入れるとES6をトランスパイルできるようになる。
Babelは .babelrc
というファイルがあると、その設定を読み込んでくれる。
Babel6での変更?
Babel5からBabel6で babel
が babel-core
と babel-cli
に分割された模様。
CLIを使用しないのであれば、 babel-core
だけでいい。
.babelrc
トラインスパイルする内容を指定する場合、以下のように プリセット(presets) を指定する。
{ "presets": [es2015", "react"] }
babel-preset-2015
、 babel-preset-react
を使用する場合は上記のように指定する。
Polyfill
$ npm install --save-dev babel-polyfill
Babelでトランスパイルすると古いブラウザでも動作する Javascript(ES5) を出力するが、古いブラウザのブラウザオブジェクトの中には標準オブジェクト(ES6で記述できるブラウザオブジェクトの扱い方)に対応していないものがある。
babel-polyfill
を利用すると、古いブラウザでも動くように標準オブジェクトを拡張してくれる。
ちなみに、古いブラウザーに欠けている部分、新しいブラウザーでも足りない機能の穴を埋めることを、 ポリフィル (polyfill) という。
標準オブジェクトを拡張すると、既存の環境と互換性を失うことになるため、別ライブラリ babel-polyfill
に分かれている。
babel-polyfill
の他に babel-runtime
というのがある。
babel-polyfill
が標準オブジェクトを拡張するのに対して、 babel-runtime
は標準オブジェクトの対応していない機能を、その場で別のコードにトランスパイルして解決する。
babel-polyfill
を導入しているほうが多そうな肌感。
その他のBabelプラグイン
- babel-preset-env
- compat-tableを用いて、サポートされている環境に基づいて必要なBabelプラグインを自動で決定するライブラリ
- babel-loader
- webpackからbabelを使用できるようにするやつ
- babel-preset-react
- Reactをトランスパイルするプリセット
- babel-preset-stage-0
- ECMAScriptのステージを指定できる
- ステージについては後述
- bable-register
- 通常のwebpackの設定ファイルは
webpack.config.js
というファイルだが、webpack.config.babel.js
というファイル名でES6で書けるようになる
- 通常のwebpackの設定ファイルは
ステージ(stage)
BabelはECMAScript2015 (ES6), ECMAScript7をECMAScript5に変換するが、ECMAScript2015 (ES6), ECMAScript7の仕様でもまだ議論中のものもある。
そこで、ECMAScriptの中でもまだ議論しきれていない仕様に関しては、stageという概念を使って安定度を示している。
初期値は2が指定されており、Draft版のものが使用できる。
基本的には初期値で問題無いが、それ以上のものを使いたい場合はリスクを加味して使用すること。
ステージは以下がある。
stage | description |
---|---|
0 | Strawman - アイデア |
1 | Proposal - 提案 |
2 | Draft - ドラフト |
3 | Candidate- 仕様書と同じ形式 |
4 | Finished - 策定完了 |
sourceMaps
トラインスパイル前後のコードをマッピングする。
デバッグなどする際、エラー箇所がトランスパイル前のコードのどこに対応するのかがわかるようになる。
webpack
webpackは、複数のファイルの依存関係を顧慮してビルドを行うツール。
設定ファイルは webpack.config.js
。
entry
でトランスパイル対象を指定して、output
で出力先を指定する。- Loaderという仕組みがあり、これでES6やReactをコンパイルできる。
- Pluginという仕組みがあり、これでUglifyなど圧縮処理などができる。PluginはLoaderの前後で実行される。
- WebpackDevServerという確認用簡易Webサーバがある。
Sublime Text 3のインストールとパッケージの導入
インストール
公式から「portable version」を入手して展開するだけ。
(Windowsではportable versionでないとプロキシ環境下で何故か動かなかった)
MacユーザはHomebrewを使用して以下のようにインストール。
$ brew cask install sublime-text
Homebrewについては以下を参照。
起動方法
アイコンクリックでもいいがコマンドラインで起動できる。
$ subl file
プロジェクト(カレントディレクトリ)で起動したい場合は以下。
$ subl .
Package Controlのインストール
パッケージの検索・インストールを簡単にしてくれる。
「View」→「Show Console」からコンソールを起動。
下記を実行。
import urllib.request,os,hashlib; h = 'df21e130d211cfc94d9b0905775a7c0f' + '1e3d39e33b79698005270310898eea76'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
プロキシ環境の場合は下記を実行。
import urllib.request,os,hashlib; h = 'df21e130d211cfc94d9b0905775a7c0f' + '1e3d39e33b79698005270310898eea76'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler({"http": "http://[username]:[password]@[proxy_server]:[port]", "https": "https://[username]:[password]@[proxy_server]:[port]"})) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
「[username]:[password]@[proxy_server]:[port]」の箇所はプロキシ環境に合わせて書き換える。
また、最新のインストールコマンドは公式を参照。
その他、以降のオペレーションなどでプロキシ関係でうまくいかないときは、
- 「Preferences」→「Package Settings」→「Package Controll」→「Settings-User」
を選択して、 Package Control.sublime-settings
ファイルを開き、編集する。
{ "http_proxy": "プロキシサーバのアドレス:ポート番号", "https_proxy": "プロキシサーバのアドレス:ポート番号", "proxy_username": "プロキシのユーザ名", "proxy_password": "プロキスのパスワード" }
その他設定はここを参照。(※プロキシの設定とか)
日本語化
Japanize というパッケージを導入する。
- 「Preferences」→「Package Control」を選択(
Command + Shift + P
) - 「Package Control: Install Package」を選択
- 「Japanize」を選択
- 「Package Control Message」の内容に従う
Macユーザは以下の手順で。
~/Library/Application Support/Sublime Text 3/Packages/Japanize
にインストールされている*.jpファイルを、以下にコピー。~/Library/Application Support/Sublime Text 3/Packages/Default
- Defaultフォルダがない場合は自分で作成
- コピーしたファイルをオリジナルのファイル(.jpが付かないファイル)と置き換える。
~/Library/Application Support/Sublime Text 3/Packages/Japanize/Main.sublime-menu
(.jpが付かない方)を、以下にコピー。~/Library/Application Support/Sublime Text 3/Packages/User
- すると、他のプラグインで上書きされてしまっているトップメニューも日本語化される。
カスタマイズ
テーマの変更
- 「Package Control: Install Package」で使用したいテーマを検索してインストール
- 「Preferences」→「Settings」を選択して
Preferences.sublime-settingsーUser
ファイルを開く - 設定ファイルに各テーマ用のコードを記述・保存
ググって好きなテーマを探す。
筆者はMaterial Themeをインストールして以下の設定を行った。
{ "theme": "Material-Theme-Darker.sublime-theme", "color_scheme": "Packages/Material Theme/schemes/Material-Theme-Darker.tmTheme" }
インデントの変更
- 「Preferences」→「Settings - User」を選択して設定ファイルを開く
- 「"tab_size": 2」(タブサイズが2)を追記
- 「"translate_tabs_to_spaces": true」(タブをスペースに変換)を追記して保存
その他
基本には
- 「Package Control: Install Package」(
Command + Shift + P
してInstall Package) - 好きなパッケージを入力・インストール
でパッケージをインストールできる。
プログラマな人は下記のパッケージ辺りを入れておくといいかも。
- AdvancedNewFile
Option + Command + N
で新規ファイルを作成できる
- All Autocomplete
- コード補完を補強するパッケージ
- SublimeLinter
- 下記の「SublimeLinter-XX」を使うためのフレームワーク
- SublimeLinter-XX
- リアルタイムに構文チェック
- XXの部分に任意の文字が入っていろんな種類がある
- SublimeLinter-javac
- SublimeLinter-ruby
- その他「https://github.com/SublimeLinter」
- BracketHighlighter
- []、()、{}、””、”、などの開始、終了をハイライトしてくれるパッケージ
- GitGutter
- Git管理してるファイルを編集すると「+ -」で行番号のとこに表示
- SideBarEnhancements
- サイドバーのファイル/フォルダ操作を拡張
- ConvertToUTF8
- UTF-8以外の文字コードのファイルをUTF-8にしてくれる
- SublimeCodeIntel
- 補完機能を強化、Tabによるコード補完補完
- BoundKeys
- 複雑になったショートカットキーを確認できるパッケージ
便利機能
Spring MVC入門
Spring MVCで最小アプリケーションが動くまでの設定についてまとめる。
以下の2種類で同じアプリを実装する。
- Java Based Configuration
- XML Based Configuration
上記は両方HTTP GETするとHelloが返ってくる簡単たRESTアプリ。
Spring BOM 2.0.8.RELEASEで動確した。
Java Based Configuration
以下を作成する。
- pom.xml
- src/main/java/com/pepese/sample/config/AppConfig.java
- Spring設定クラス
- DIやAOPなどの設定に使用する
@Configuration
アノテーションを付与すること- 必要に応じて
@ComponentScan
を指定してコンポーネントスキャン領域を指定すること
- Spring設定クラス
- src/main/java/com/pepese/sample/config/WebMvcConfig.java
- Spring MVC設定クラス
- コンテンツネゴシエーションなどSpring MVCの
DispatcherServlet
に関する設定に使用する
- コンテンツネゴシエーションなどSpring MVCの
WebMvcConfigurerAdapter
が継承されていること@Configuration
アノテーションを付与すること@EnableWebMvc
アノテーションを付与すること
- Spring MVC設定クラス
- src/main/java/com/pepese/sample/config/WebInitializer.java
- web.xmlのJava Based Configuration
AbstractAnnotationConfigDispatcherServletInitializer
を継承することWebApplicationInitializer
の実装クラス
- src/main/java/com/pepese/sample/controller/HelloController.java
- 動作確認用のコントローラクラス
- src/main/java/com/pepese/sample/service/HelloService.java
- DIなどの動作確認用のサービスクラス
pom.xml
AppConfig.java
WebMvcConfig.java
WebInitializer.java
HelloController.java
HelloService.java
mvn clean package
してTomcatにデプロイすれば動く。
XML Based Configuration
以下を作成する。Java Based Configurationと異なるファイルだけ記載する。
以下は不要になるファイル。
- src/main/java/com/pepese/sample/config/AppConfig.java
- src/main/java/com/pepese/sample/config/WebMvcConfig.java
- src/main/java/com/pepese/sample/config/WebInitializer.java
以下は追加するファイル。
- src/main/resources/META-INF/spring/applicationContext.xml
- src/main/resources/META-INF/spring/spring-mvc.xml
- src/main/webapp/WEB-INF/web.xml
applicationContext.xml
spring-mvc.xml
web.xml
mvn clean package
してTomcatにデプロイすれば動く。
Spring Boot入門
Spring Bootで最小アプリケーションが動くまでの設定についてまとめる。
以下の2種類について記載する。
- Spring Bootで実行可能jarの作成
- Spring BootでAPサーバにデプロイ可能なwarの作成
上記は両方HTTP GETするとHelloが返ってくる簡単たRESTアプリ。
Spring Bootで実行可能jarの作成
以下を作成する。
- pom.xml
- Maven設定ファイル/POM
- POMのdependencyに
spring-boot-starter-*
が含まれること - POMのbuild -> pluginsに
spring-boot-maven-plugin
が含まれることmvn package
実行時に適切に実行可能jarを作成してくれる
- src/main/java/com/pepese/sample/Application.java
- Spring Bootアプリケーション起動クラス
@SpringBootApplication
アノテーションを付与すること@Configuration
、@EnableAutoConfiguration
、@ComponentScan
をまとめたもの
- src/main/java/com/pepese/sample/config/AppConfig.java
- Spring設定クラス
- DIやAOPなどの設定に使用する
@Configuration
アノテーションを付与すること
- Spring設定クラス
- src/main/java/com/pepese/sample/config/WebMvcConfig.java
- Spring MVC設定クラス
- コンテンツネゴシエーションなどSpring MVCの
DispatcherServlet
に関する設定に使用する
- コンテンツネゴシエーションなどSpring MVCの
WebMvcConfigurerAdapter
が継承されていること@Configuration
アノテーションを付与すること- Spring Bootの場合、
@EnableWebMvc
を付与する必要はない- Spring Bootを利用しないSpring MVCアプリケーションを作成する場合には付与する
- Spring MVC設定クラス
- src/main/java/com/pepese/sample/controller/HelloController.java
- 動作確認用のコントローラクラス
- src/main/java/com/pepese/sample/service/HelloService.java
- DIなどの動作確認用のサービスクラス
pom.xml
Application.java
AppConfig.java
WebMvcConfig.java
HelloController.java
HelloService.java
実行
以下の2通り。
mvn spring-boot:run
で実行してhttp://localhost:8080/
へアクセスmvn package
でビルドしてjava -jar target/springboot-sample-jar-0.0.1-SNAPSHOT.jar
で実行してhttp://localhost:8080/
へアクセス
Spring BootでAPサーバにデプロイ可能なwarの作成
意味あんの?なツッコミは無しで。
準備されたTomcatにデプロイしないといけないルールなプロジェクトは存在するんです。
以下を作成する。「Spring Bootで実行可能jarの作成」と異なるファイルだけ記載する。
- pom.xml (変更)
- Maven設定ファイル/POM
- POMのdependencyに
spring-boot-starter-*
が含まれること - POMのbuild -> pluginsに
spring-boot-maven-plugin
が含まれることmvn package
実行時に適切にデプロイ可能warを作成してくれる
- POMのpackagingをwarにすること
- POMのspring-boot-starter-tomcatの組み込み系APサーバのscopeをprovidedにすること
- tomcatに限らずjetty等組み込み系APサーバは全て
- src/main/java/com/pepese/sample/ServletInitializer.java (追加)
- web.xmlのSpring Boot版
SpringBootServletInitializer
が継承されていること- web.xmlのSpring MVC版である
WebApplicationInitializer
を継承している
- web.xmlのSpring MVC版である
configure
メソッドをオーバーライドし、Spring Bootアプリケーション起動クラスをロードすること
pom.xml
ServletInitializer.java
実行
以下の2通り。
mvn spring-boot:run
で実行してhttp://localhost:8080/
へアクセスmvn package
でビルドしてできたwarをTomcatにデプロイしてhttp://localhost:8080/springboot-sample-war/
へアクセス- コンテキストパスは自分で調整して
補足
SpringBootServletInitializer
はSpring Bootの起動クラスに継承して作成してもよい。下記の通り。
package com.pepese.sample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; @SpringBootApplication public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } }