More than 1 year has passed since last update.

Spring Boot使ったアプリをGradleでビルドしたらtsファイルもコンパイルしてbowerで入れたライブラリとかもwebpackでまとめてjsファイル吐いてくれたら素敵だなと思ってやってみた。

ソースはここ

ディレクトリ構成はこんな感じ

src/
  └main/
    ├java/
    ├ts/ ・・・ここのtsファイルをコンパイルして
    └resources/
      └static/
      └templates/
  └test/
    ├java/
    └resources/
build/
  └classes/
    ├main/
    └test/
  └resources/
    └main/
      └static/
        └js/ ・・・ここに出力する
      └templates/
    └test/

どうやるか

gradle-gulp-pluginというのがあったのでこれを使ってgulpのタスクとしてwebpackを動かそうと思う。さらにgradle-node-pluginを使うとnodeのインストールとか面倒見てくれるようなので環境構築手順書とか書く手間省けてよさげです。

いろいろインストール

最終的にはnodeとかnpmとか入ってな環境でもgradle buildですべて完結するようになるけど、設定にファイルの生成などに必要な最低限のモジュールをグローバルにインストール。

$ npm install -g bower tsd

プロジェクトの初期化

$ npm init

プロジェクトに必要なツールをインストール

$ npm install --save-dev typescript webpack ts-loader gulp webpack-stream gulp-exec bower

bowerでvueをインストール

$ bower init
$ bower install vue --save

tsdでvueの定義ファイルを作成

TypeScriptから使うライブラリの型情報を追加します。

$ tsd init
$ tsd install vue --save

ここまでで以下のようなファイル構成になります

├bower_components/
├node_modules/
├src/
├typings/
├bower.json
├package.json
└tsd.json

スクリプトの作成

VueのViewモデルを書いてみます。
ここを参考にしました。

src/main/ts/app.ts
import Vue = require('vue');

class App extends Vue {
    constructor(){
        super(false);
        this._init({
            el: '#app',
            data: {
                message: 'Hello world'
            }
        });
    }
}
export var app = new App();

TypeScriptのコンパイル設定

filesでtypings/tsd.d.tsを指定してライブラリの型情報を使えるようにします。

tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true
  },
  "files": [
    "src/main/ts/app.ts",
    "typings/tsd.d.ts"
  ]
}

webpackの設定

ts-loaderを使ってコンパイルしたapp.tsとbowerで入れたvueをbundle.jsにまとめます。

webpack.config.js
var webpack = require('webpack');
var path = require('path');

module.exports = {
  entry: './src/main/ts/app.ts',
  output: {
    path: __dirname + '/build/resources/main/static/js',
    filename: 'bundle.js'
  },
  devtool: 'inline-source-map',
  resolve: {
    root: [path.join(__dirname, "bower_components")],
    extensions: ['', '.ts']
  },
  plugins: [
    new webpack.ResolverPlugin(
      new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
    ),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ],
  module: {
    loaders: [
      { test: /\.tsx?$/, loader: 'ts-loader' }
    ]
  }
};

gulpの設定

gulpにwebpackを実行するタスクを作成します。
buildを実行するとbower installを事前に実行してからwebpackを実行します

gulpfile.js
var gulp = require('gulp');
var webpack = require('webpack-stream');
var webpackConfig = require('./webpack.config.js');
var exec = require('gulp-exec');

gulp.task('install_bower', function(callback){
    return gulp.src('')
            .pipe(exec("./node_modules/bower/bin/bower install"));
});

gulp.task('build', ['install_bower'], function(callback){
  return gulp.src('./src/main/ts/app.ts')
    .pipe(webpack(webpackConfig))
    .pipe(gulp.dest('./build/resources/main/static/js/'));
});

gradleの設定

classesタスク実行前にnpm install gulp buildを実行するように設定します。
また、nodeをダウンロードするようにします。

build.gradle
buildscript {
  repositories {
    mavenCentral()
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE"
    classpath "com.moowork.gradle:gradle-node-plugin:0.11"
    classpath "com.moowork.gradle:gradle-gulp-plugin:0.11"
  }
}

apply plugin: "java"
apply plugin: "spring-boot"
apply plugin: "com.moowork.node"
apply plugin: "com.moowork.gulp"

node {
  version = '0.12.7'
  download = true
}

classes.dependsOn gulp_build
gulp_build.dependsOn npm_install 

repositories {
  mavenCentral()
}

dependencies {
  compile "org.springframework.boot:spring-boot-starter-web"
}

実行

$ gradle build

ちゃんと出来てます。

$ ls build/resources/main/static/js/          
bundle.js

動くか確認

$ gradle bootRun

exec.png

できました。

nodeがインストールされてない環境でビルドできるか確認

こんなDockerfileを作ります。
rootでbower installするとエラーになるので別のユーザーを作ってます。

Dockerfile
FROM java:8

RUN useradd docker
RUN mkdir /home/docker
RUN chown docker /home/docker
USER docker
WORKDIR /home/docker
RUN git clone https://github.com/jun-1/spring-boot-with-typescript.git

WORKDIR spring-boot-with-typescript
RUN ./gradlew build

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "./build/libs/spring-boot-with-typescript.jar"]

ビルド

$ docker build -t spring-boot-typescript .

起動

$ docker run -p 80:8080 spring-boot-typescript

nodeのない環境でもビルドして起動できました。1

exec2.png


  1. 192.168.99.100はdockerのホストVMのアドレスです