LoginSignup
2
2

More than 5 years have passed since last update.

Gradleでbowerを利用したフロントエンドのビルドまでを行う方法 (3/6)

Last updated at Posted at 2016-03-31

はじめに

Java/SparkプロジェクトのGradleを利用したビルド/デプロイについて、私が試したことをまとめたものです。
(ここで言うSparkは、分散処理ライブラリのApache Sparkではなく、JavaのSinatraライクなMicroframeworkのSparkのことです)

目次

  1. Hello Worldアプリ
  2. jadeテンプレートエンジン
  3. Grunt/bowerによるWebパッケージのビルド
  4. 付録A. TravisCIによるビルド
  5. 付録B. Gradleでdocker build
  6. 付録C. TravisCIからDockerHubへ docker push

各章でのソースコードは Commits · kaakaa/gradle-frontend-boilerplate から確認できます。

環境

  • Java 1.8.0_74
  • Gradle 2.12
  • spark-core 2.3
  • spark-template-jade 2.3
  • node.js 4.4.0

gradle-frontend-boilerplate

3. Grunt/bowerによるWebパッケージのビルド

概要

Gradleのビルドフローにnpm,grunt,bowerを組み込む。

厳密には、Gradleプラグインcom.moowork.gruntを使ってnpm installとGruntタスクを実行するだけ。

bowerはGruntタスクとして操作する。


Javaプロジェクトからbootstrapなどのフロントエンド資産を利用する場合、WebJars - Web Libraries in Jarsを利用するなどの方法もあるが、今回はフロントエンドツールに慣れるために、なるべくフロントエンド部分はGradleから実行するだけにしたかったからである.

実行

git clone https://github.com/kaakaa/gradle-frontend-boilerplate.git
cd gradle-frontend-boilerplate
git checkout sec_3

./gradlew run

ビルドスクリプト

build.gradle
plugins {
    id 'java'
    id 'application'
    id 'com.moowork.grunt' version '0.11'  // (1) - npm/gruntを操作するGradleプラグインを指定する
    id 'com.moowork.node' version '0.11'
}

group 'org.kaakaa'
version '1.0-SNAPSHOT'

/** For Java build */
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

mainClassName = 'org.kaakaa.spark.Main'

sourceSets {  // (2) - フロントエンドビルドの成果物をJavaビルドのリソースに組み込む
    main {
        resources {
            srcDir 'src/main/resources'
            srcDir 'src/main/web/bower_components'
        }
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.sparkjava:spark-core:2.3'
    compile 'com.sparkjava:spark-template-jade:2.3'
}


/** For frontend build */
node {  // (3) - nodeの設定
    version = '4.4.0'
    download = true
    workDir = file("${projectDir}/src/main/web")
    nodeModulesDir = file("${projectDir}/src/main/web")
}

grunt {
    workDir = file("${projectDir}/src/main/web")
}

grunt_build.dependsOn 'installGrunt'  //  (4) - gruntの実行環境を構築する
grunt_build.dependsOn 'npmInstall'
processResources.dependsOn grunt_build

/** Other settings */
task wrapper(type: Wrapper) {
    gradleVersion = '2.12'
}

(1) npm/gruntを操作するGradleプラグインを指定する

com.moowork.gruntプラグインではGruntをインストールするinstallGruntタスクと、Gruntのタスクを実行するgrunt_<task>ルールがGradleタスクとして追加される。
今回はgrunt_buildタスクの実行によりgruntのbuildタスクを実行することを想定している。

また、com.moowork.nodeプラグインで、node.js/npmのインストールとnode/npmタスクの実行をGradleから行うことができる。

(2) フロントエンドビルドの成果物をJavaビルドのリソースに組み込む

今回、フロントエンド系の資産についてはsrc/main/web内で扱うようにしていますが、そこで生成されたjs/cssファイルをJavaビルドの成果物に含めるためにsrc/main/web/bower_componentsをresourcesフォルダとして追加しています。

(3) nodeの設定

com.moowork.nodeで使用する設定をnode節に、com.moowork.gruntで使用する設定をgrunt節にそれぞれ記述しています。
先にも述べたように、node/gruntで扱う資産はsrc/main/web内で扱うため、workDirにそのディレクトリを指定しています。

(4) gruntの実行環境を構築する

grunt_buildタスクが実行される前にinstallGrunt,npmInstallが実行されるよう設定しています。
また、grunt_buildタスクが、Javaビルドのリソースを処理するprocessResourcesタスクの実行前に実行されるよう設定しています。

ビルドスクリプト(Grunt)

Gradleのgrunt_buildタスクにより実行されるgruntファイル.
src/main/web/Gruntfile.jsに置いてある.

Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    "bower-install-simple": {  // (1) - bower installを実行する
      options: {
        directory: "bower_components/public"  // (2) - bower installの出力先を変更する
      },
      "prod": {
        options: {
          production: true
        }
      },
      "dev": {
        options: {
          production: false
        }
      }
    },
    wiredep: {
      task: {
        src: ['../resources/templates/**/*.jade'],  // (3) - jadeファイルにbowerコンポーネントへの参照をinjectする
        directory: 'bower_components/public',
        ignorePath: '../../web/bower_components/public'  // (4) - bowerコンポーネントへの参照パスから要らない部分を削除する
      }
    }
  });

  grunt.loadNpmTasks('grunt-bower-install-simple');
  grunt.loadNpmTasks('grunt-wiredep');

  grunt.registerTask('default', 'build');
  grunt.registerTask('build', ['bower-install-simple', 'wiredep']);
};

(1) bower installを実行する

bower installを実行する.
今回、bower.jsonにはbootstrapへの依存のみ宣言してある.

(2) bower installの出力先を変更する

bower installの出力先がbower_componentsままだと、bowerのコンポーネントをSparkでStaticファイルとして配信出来ない(ココらへんはGradleのprocessResourceタスクとの関係).
とりあえず今回はbower installの出力先を変更し、SparkのStaticファイルを/publicに指定することにしている.

(3) jadeファイルへbowerコンポーネントへの参照をinjectする

bower installでinstallされたコンポーネントへの参照をjadeファイルへ記述するタスク.
便利なのだが、grunt-wiredepはもうメンテされてないらしい. stephenplusplus/grunt-wiredep: Inject Bower packages into your source code with Grunt.

(4) bowerコンポーネントへの参照パスから要らない部分を削除する

(3) jadeファイルへbowerコンポーネントへの参照をinjectするでjadeファイルにinjectされるパスは、相対パスのため../../web/bower_components/public/bootstrap/dist/css/bootstrap.cssというような形式になる.
このままではWebサーバとして動作させた時に上手く動かないため、不要な部分を削る.

この削り方は(2) bower installの出力先を変更するに依存しており、ここらへんの操作のコンテキストがとても高くなりがちなのが悩みどころ.

アプリケーションコード

org.kaakaa.spark.Main
package org.kaakaa.spark;

import spark.ModelAndView;
import spark.template.jade.JadeTemplateEngine;

import java.util.Collections;

import static spark.Spark.get;
import static spark.Spark.port;
import static spark.Spark.staticFileLocation;

public class Main {
    public static void main(String[] args) {
        port(8080);
        staticFileLocation("/public");  // (1) - Staticファイルの格納場所として`/public`を指定する

        get("/hello", (rq, rs) -> new ModelAndView(Collections.EMPTY_MAP, "hello"), new JadeTemplateEngine());
    }
}

(1) Staticファイルの格納場所として/publicを指定する

ビルドスクリプト(Grunt)の(2) bower installの出力先を変更するでも触れたように、SparkのStaticファイルの格納場所として/publicを指定する.

アプリケーションコード(jade)

hello.jade
doctype html
html(lang="ja")
  head
    title gradle-frontend-boilerplate
    // bower:css  // (1) - grunt-wiredepタスクによりbowerのmainコンポーネントがinjectされる
    // endbower
    // bower:js
    // endbower
  body
    nav.navbar.navbar-inverse.navbar-fixed-top
      .container
        .navbar-header
          a.navbar-brand Gradle-frontend-boilerplate
    .container(style="margin-top: 50px;")
      h1 gradle-frontend-boilerplate
      p Hello World!

(1) grunt-wiredepタスクによりbowerのmainコンポーネントがinjectされる

gruntのgrunt-wiredepタスクが実行されると、bowerのmainコンポーネントとして指定されているjs/cssファイルへの参照がコメントの間にinjectされる。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2