2014年11月24日月曜日

grunt-maven-pluginを使用したプロジェクトでtarget中の不要ファイルを削除する

前回のままだとGruntfile.jsやpackage.jsonなどがtargetに含まれてしまいます。。。 なのでこれを削除したいと思います。


target/classes
├── static
│   ├── Gruntfile.js
│   ├── js
│   │   ├── app.min.js
│   │   └── src
│   │       ├── Doramon.js
│   │       ├── main.js
│   │       └── namespace.js
│   ├── maven-properties.json
│   └── package.json
  


Mavenの情報を取得してtargetのパスを取得します。


今回はこれのoutputDirectoryを使います。
{
  "directory": "${project.build.directory}",
  "outputDirectory": "${project.build.outputDirectory}",
  "name": "${project.name}",
  "version": "${project.version}",
  "finalName": "${project.build.finalName}"
}
  
GitHub: src/main/resources/static/maven-properties.json


Gruntからtargetのパス情報を取得して不要ファイルの削除を行います。


ついでに"clean:before"という作業前に前回のJavaScriptを削除する処理を追加
module.exports = function (grunt) {
    grunt.initConfig({
        ・・・省略・・・
        mvnProp: grunt.file.readJSON('maven-properties.json'),
        ・・・省略・・・
        clean: {
            before: {
                options: {  force: true  },
                files: { src: [ "js/**/*.js" ] }
            },
            after: {
                options: {  force: true  },
                files: {
                    src: [
                        "<%= mvnProp.outputDirectory %>/static/Gruntfile.js",
                        "<%= mvnProp.outputDirectory %>/static/package.json",
                        "<%= mvnProp.outputDirectory %>/static/maven-properties.json",
                        "<%= mvnProp.outputDirectory %>/static/js/**/*.js"
                    ]
                }
            }
        },
        ・・・省略・・・
    grunt.registerTask('beforeClean', ['clean:before']);
    grunt.registerTask('default', ['mavenPrepare', 'concat', 'clean:after', 'mavenDist']);
};
  
GitHub: src/main/resources/static/Gruntfile.js

※ ※ 修正しました〜。goalsのgoalに create-resources がないとnpm installできませんでした。 ※

Gruntの"clean:before"をMavenのinitializeフェーズで動かす


<execution>
    <id>gruntInit</id>
    <phase>initialize</phase>
    <configuration>
        <gruntOptions>
            <gruntOption>beforeClean</gruntOption>
        </gruntOptions>
    </configuration>
    <goals>
        <goal>create-resources</goal>
        <goal>npm</goal>
        <goal>grunt</goal>
    </goals>
</execution>
  
GitHub: pom.xml


これで不要なファイルが消えました。


  target/classes
├── static
│   └── js
│       ├── app.min.js
│       └── src

サンプルを GitHub にあげています。 参考になれば幸いです〜。

2014年11月23日日曜日

MavenからGruntを起動する"grunt-maven-plugin"を使ってみました

みなさまはMavenプロジェクトでJSの結合やミニファイをどうなされていますか??

いろいろ探しているとMavenからGruntを起動するMavenプラグインを発見したので それについて調べてみたいと思います。


allegro/grunt-maven-plugin


"Grunt + Maven integration done right"
https://github.com/allegro/grunt-maven-plugin


Spring Bootのプロジェクトをサンプルで作成


Gruntを埋め込む対象としてSpring Bootのプロジェクトを作成しました。 Spring Bootの利用方法については下記ブログとかスライドをご参考ください〜


gitの管理からgrunt-mavenの作業場所を外す


.gitignoreにgrunt-mavenがJavaScript等の加工作業する場所を追加しました。
target-grunt
GitHub: .gitignore


nmp installする(Gruntで使用するパッケージ)を設定


maven-gruntで npm installするパッケージを指定します。"target-grunt"の中にnode_modulesがインストールされます。
{
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-cli": "~0.1.6",
    "grunt-contrib-concat": "^0.5.0",
    "grunt-maven": "~1.1.0",
    "grunt-contrib-clean": "~0.6.0"
  }
}
  
GitHub: src/main/resources/static/package.json


pom.xmlの情報をGruntに渡すファイルを設定


Pom/Project propertiesの値をファイルに書き込んでほしいものを指定する(た、多分。。調査不足)
{
  "version": "${project.version}"
}
  
src/main/resources/static/maven-properties.json

プロパティの種類は下記を参考にさせていただきました!ありがとうございます。
ねこだいすき:pom.xmlからプロパティ取得


Mavenから呼び出すGruntファイルの準備


例として複数のJavaScriptを結合してtarget/classesの中に結合した結果のJavaScriptファイルをコピーする
module.exports = function (grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        gruntMavenProperties: grunt.file.readJSON('grunt-maven.json'),
        mavenPrepare: {
            options: {
                resources: ['**']
            },
            dev: {}
        },
        concat: {
            files: {
                src: ['js/src/namespace.js', 'js/src/**/*.js', 'js/src/main.js'],
                dest: 'js/app.min.js'
            }
        },
        clean: {
            js: [
                "js/**/*.js",
                "!js/**/*.min.js"
            ]
        },
        mavenDist: {
            options: {
                warName: "classes",
                deliverables: ["js/**/*.min.js"]
            },
            dev: {}
        }
    });

    grunt.loadNpmTasks('grunt-maven');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-concat');

    grunt.registerTask('default', ['mavenPrepare', 'concat', 'mavenDist', 'clean']);
};
  
src/main/resources/static/Gruntfile.js


MavenからGruntを起動


Maven pluginsの中に↓追加しました。
<plugin>
            <groupId>pl.allegro</groupId>
            <artifactId>grunt-maven-plugin</artifactId>
            <version>1.4.1</version>
            <configuration>
                <sourceDirectory>${basedir}/src/main/resources</sourceDirectory>
                <gruntExecutable>node_modules/grunt-cli/bin/grunt</gruntExecutable>
                <runGruntWithNode>true</runGruntWithNode>
                <filteredResources>
                    <filteredResource>maven-properties.json</filteredResource>
                </filteredResources>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>create-resources</goal>
                        <goal>npm</goal>
                        <goal>grunt</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
     </plugins>
  
pom.xml

これで Mavenのcompile時にGruntを起動するようになりました。
サンプルをGitHubにあげています。
参考になれば幸いです〜。

2014年10月26日日曜日

Dragomeをちょっと使ってみました

なんだか面白そうなDragomeというライブラリを発見したのでちょっと試してみました。

Dragome Web SDK


Takes your Java code to the web
http://www.dragome.com/


なんでもJavaでフロントエンドもかけるらしいのです。

サーバーサイドをJavaで書いている方々から
よくJavaScript書きたくないと言われるので...(ToT)

JSF以外の選択肢として使えるものかちょっと調べてみました。

プロジェクトの雛形を生成


$ mvn archetype:generate -DarchetypeGroupId=com.dragome -DarchetypeArtifactId=simple-webapp-archetype -DarchetypeVersion=1.0 -DgroupId=com.example -DartifactId=hello 
$ cd hello
$ ls
pom.xml src

そのままをコンパイルして実行


$ mvn compile
$ mvn jetty:run
ブラウザで http://localhost:8080/hello/hello-world.html を実行
おお何かでました。

Say hello!のボタンを押下すると

POSTが発生して text/plainのメッセージが帰って来ました。

どんな感じでコーディングするのでしょうか。。

htmlみると...


<html>
<head>
<script type="text/javascript" src="dragome/dragome.js"></script>
</head>

<body>
 Message:
 <b data-template="message">...</b>
 <br>
 <button data-template="button">Say hello!</button>
</body>

</html>
おおお、スッキリしてますね。
ボタンのイベントとその結果の貼り付けはJavaの方に書いてあるんでしょうね。

Javaのソースは..


$ cd src/main/java

$ tree
.
└── com
    └── example
        ├── gui
        │   └── HelloWorldPage.java
        └── service
            ├── HelloWorldService.java
            └── serverside
                └── HelloWolrdServiceImpl.java
↑Javaのソースは3つありますね。

com.example.service



HelloWorldServiceインターフェースを

package com.example.service;

import ... 省略 ...; @ServiceImplementation(HelloWolrdServiceImpl.class)
public interface HelloWorldService {
    public abstract String getGreetingsFor(String name);
}

serverside.HelloWolrdServiceImplで実装してるみたい

package com.example.service.serverside;

import java.util.Date;
import com.example.service.HelloWorldService;

public class HelloWolrdServiceImpl implements HelloWorldService {
    public String getGreetingsFor(String name) {
        return "Hello " + name + "! (" + new Date() + ")";
    }
}

@PageAliasをつけるのがhtml(View)に対応したcontroller(?)なのかな

aliasでhtmlファイル名を指定するみたい。
package com.example.gui;

import ... 省略 ...;

@PageAlias(alias = "hello-world")
public class HelloWorldPage extends DragomeVisualActivity {
    HelloWorldService helloWorldService = serviceFactory.createSyncService(HelloWorldService.class);

    public void build() {

        // <b data-template="message">
        final VisualLabel<String> label = new VisualLabelImpl<String>("message");

        // <button data-template="button">
        final VisualButton button = new VisualButtonImpl("button", new ClickListener() {
            public void clickPerformed(
          VisualComponent aVisualComponent) {

                label.setValue(
     helloWorldService.getGreetingsFor("World"));
            }
        });

        mainPanel.addChild(label);
        mainPanel.addChild(button);
    }
}

data-templateで与えた名前を...

<b data-template="message">...</b>

下記のように紐付けるみたい

final VisualLabel<String> label
    = new VisualLabelImpl<String>("message")

ボタンのイベントリスナーでサービスからの値を取得すると


final VisualButton button = new VisualButtonImpl("button", new ClickListener() {
 public void clickPerformed(VisualComponent aVisualComponent) {
  label.setValue(helloWorldService.getGreetingsFor("World"));
  }
});

AJaxになってサーバから値を取得してくれるみたいです。


すごいなぁ。

2014年9月6日土曜日

2014/09/06 その3 AngularJS福岡勉強会(第2回) - Directiveの自作 -

01.directive - restrict: 'EAC' -



    <!-- restrict: 'E' -->
    要素名で置き換え!
    <ore-panel ></ore-panel>
    
    <!-- restrict: 'A' -->
    属性名で置き換え!
    <div ore-panel="" ></div>
      
    <!-- restrict: 'C' -->
    class名で置き換え!
    <div class="ore-panel" ></div>

02.directive - parent scope -


Directive内も外側のスコープが使えます。

03.directive - isolate scope -


Directive内でscopeを宣言し外のscopeと接続する事が出来ます。
こうする事で独自Directiveを作る人は外のscopeの事を考えずに作成する事ができます。
利用する人は属性にパラメータ値を渡す事が出来ます。

04.directive - isolate scope function -


属性に渡すのは値だけでなくfunctionも渡す事が出来ます。
scope:{ 'clicked': '&' } 
引数に値を渡す時はオブジェクトの形を使用します。




twitterのハッシュタグ

質問やこうした方がいいよ〜とかありましたら、↓につぶやいてください〜

#ng_fukuoka

2014年9月5日金曜日

2014/09/06 その2 AngularJS福岡勉強会(第2回) - DOM制御とか装飾とか -

01. ng-class


ng-classを使うとclassの切り替えが出来ます。
ng-class="{ 'panel-info': !isDanger, 'panel-danger': isDanger  }" と書くと
isDangerが trueの時に'panel-danger'class(スタイルシート)が
isDangerが falseの時に'panel-info'がDOM要素につけられます。

02. ng-style


ng-styleを使うとstyleの切り替えが出来ます。

03. ng-if


ng-ifを使うと要素の表示・非表示ができます。
☆ポイント☆
display:none;ではなくて要素が作られたり消されたりします。

04. ng-if with animation


ng-ifにAnimationを追加できます
☆ポイント☆
angular-animate.jsを読んでangular.module('app', ['ngAnimate']);とモジュール追加すること
CSSでアニメーション情報を指定してあげること
jsFIddleの.ng-enter ,.ng-leave, .ng-leave.ng-leave-active, .ng-enter.ng-enter-activeを参照

05. ng-show


ng-showも要素の表示・非表示ができます。
☆ポイント☆
display:none;で表示・非表示を切り替えてます。

06. ng-show with animation


ng-showも要素の表示・非表示ができます。
☆ポイント☆
Migrating from 1.2 to 1.3
https://docs.angularjs.org/guide/migration
書き方がかわったみたい
Migrating from 1.2 to 1.3




twitterのハッシュタグ

質問やこうした方がいいよ〜とかありましたら、↓につぶやいてください〜

#ng_fukuoka

2014/09/06 その1 AngularJS福岡勉強会(第2回) - form -

01. form.input.$invalid


必須入力のinputが空の場合にテキストボックスの枠を赤くする
☆ポイント☆
 form name="fm"   で fmというFormControllerが使えるようになります。
 input name="inputCd" でfm.inputCdにNgModelControllerが使えます。

02. form.input.$invalid と form.$invalid


form全体でエラーがあるのか項目単位でエラーがあるのか判別できます。
☆ポイント☆
 fm.inputCd.$invalid って書くと個別で不正が無いか確認
 fm.$invalid って書くとform全体で不正が無いか確認できます

03. form.input.$error


$errorで細かいエラーを判別出来ます。
☆ポイント☆
$error.required で必須チェックでエラーなのか
$error.maxlength で最大長でエラーなのか
$error.pattern で許されないパターンの入力なのか判別できます。

04. ngFormで formの入れ子


formを入れ子にして分割出来ます。
☆ポイント☆
ngFormで入れ子にできる
でも標準のHTML5のバリデーションはngFormに気づかない...
しかたないので novalidate で機能をOFF!

05. ngFormをngRepeatで繰り返す


ng-formはng-repeatの中で繰り返しつかえます。

おまけ blurの時に ng-modelを更新したいなぁ


どうやら1.3からng-model-options="{ updateOn: 'blur' }"って指定すると
blurイベント時にng-modelを更新するようにできるらしい!
1.2を使っている方は自分でカスタムディレクティブを作りましょう〜。
stackoverflow:How to let ng-model not update immediately?
http://stackoverflow.com/questions/14722577/how-to-let-ng-model-not-update-immediately




twitterのハッシュタグ

質問やこうした方がいいよ〜とかありましたら、↓につぶやいてください〜

#ng_fukuoka

2014年7月29日火曜日

altJS福岡勉強会第1回準備中〜

altJS福岡勉強会第1回準備中〜

今度の土曜日(2014/8/2土)にaltJS福岡勉強会第1回を開催する予定です!
http://www.zusaar.com/event/6467004

AngularJSを仕事で少し使っている私は
AngularJS2が Traceurを採用しているという事なんで

All code in AngularJS 2 is already being written in ES6. As ES6 doesn’t run in browsers today, we’re using the Traceur compiler to generate the nice ES5 that runs everywhere. We’re working with the Traceur team to build support for a few extensions like annotations and assertions. We call this set of extensions “ES6 +A”.
http://blog.angularjs.org/2014/03/angular-20.html

google/traceur-compiler を使った発表をしようと思ってます!
https://github.com/google/traceur-compiler
(まだちょっとしか触ってない&資料書いてないけど….)

traceur-compilerを使うといろいろES6の機能が使えるらしいですね。
https://github.com/google/traceur-compiler/wiki/LanguageFeatures#modules

Traceur+grunt+IntelliJ(WebStorm)で
ちょっとAngularJS1.2を使ってみようとおもいます〜。
https://github.com/aaronfrost/grunt-traceur

おまけ。ES6の機能が使える環境一覧表
http://kangax.github.io/compat-table/es6/