Powered By Blogger

2015年12月17日木曜日

play + react + gulp + webpackでビルド環境

最終着地点はactivator runと同時にreactをビルドする。
そしてMinifyもできるようにしておく。
  1. 前提条件 
    • 以下がインストール済であること
      • Scalaがインストール済
      • Playがインストール済
      • Node.jsがインストール済
      • gulpがグローバルインストール済
  2. プロジェクトの作成
    • >activator new
      
      Fetching the latest list of templates...
      
      Browse the list of templates: http://typesafe.com/activator/templates
      Choose from these featured templates or enter a template name:
        1) minimal-akka-java-seed
        2) minimal-akka-scala-seed
        3) minimal-java
        4) minimal-scala
        5) play-java
        6) play-scala
      (hit tab to see a list of all templates)
      > 6
      Enter a name for your application (just press enter for 'play-scala')
      > test1
      OK, application "test1" is being created using the "play-scala" template.
      
      To run "test1" from the command line, "cd test1" then:
      C:\playSandbox\test1/activator run
      
      To run the test for "test1" from the command line, "cd test1" then:
      C:\playSandbox\test1/activator test
      
      To run the Activator UI for "test1" from the command line, "cd test1" then:
      C:\playSandbox\test1/activator ui
      
  3. Reactのチュートリアルなどを参考にファイルを編集
    • JSを以下のような感じで配置し、main.jsをエントリーポイントする
      • /test1/app/assets/app/components/CommentBox.js
      • /test1/app/assets/app/components/CommentForm.js
      • /test1/app/assets/app/components/CommentList.js
      • /test1/app/assets/app/main.js
    • CSSを以下のような感じで配置
      • /test1/app/assets/app/css/main.css
    • /test1/app/views/index.scala.htmlを編集 
      • @(message: String)
        
        @main {
            <header>
              <h1>React Tutorial ES6</h1>
            </header>
            <div id="container"></div>
        }
        
    • /test1/app/views/main.scala.htmlを編集
      • @(content: Html)
        <html>
            <head>
                <title>title</title>
                <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("css/main.css")">
                <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
            </head>
            <body>
                @content
                <script src="/assets/app/main.build.js"></script>
            </body>
        </html>
        
  4. 必要パッケージのイントール、設定
    •  プロジェクトディレクトリ直下にpackage.jsonの作成
      • {
          "name": "test1",
          "version": "0.0.1",
          "dependencies": {
            "gulp": "^3.9.0"
          },
          "private": true,
          "devDependencies": {
            "babel-core": "^6.3.17",
            "babel-loader": "^6.2.0",
            "babel-preset-es2015": "^6.3.13",
            "babel-preset-react": "^6.3.13",
            "gulp-uglify": "^1.5.1",
            "jquery": "^2.1.4",
            "react": "^0.14.3",
            "react-dom": "^0.14.3",
            "webpack": "^1.12.9",
            "webpack-stream": "^3.1.0"
          }
        }
        
    • インストール
      • npm installを実行 (しばらくかかる)
  5. Gulpの設定
    •  プロジェクトディレクトリ直下にgulpfile.jsの作成
      • (function() {
          'use strict';
        
          var gulp = require('gulp');
          var uglify = require('gulp-uglify');
          var webpack = require('webpack-stream');
          var wpConf = require('./webpack.config.js');
        
          gulp.task('default', function() {
            console.log('gulp default task.');
          });
        
          gulp.task('build', function() {
            gulp.src(wpConf.entry).pipe(webpack(wpConf)).pipe(gulp.dest(wpConf.dest));
          });
        
          gulp.task('minify', function() {
            gulp.src('./target/web/public/main/app/main.build.js').pipe(uglify()).pipe(gulp.dest('./target/web/public/main/app'));
          });
        
          function errorHandler(err) {
            console.log('Error: ' + err.message);
          }
        
        })();
        
  6. webpackの設定
    • プロジェクトディレクトリ直下にwebpack.config.jsの作成
      • (function(module) {
          var WEBPACK_CONFIG = {
            entry: './target/web/public/main/app/main.js',
            dest: './target/web/public/main/app/',
            output : {
              filename : 'main.build.js'
            },
            module: {
              loaders: [
                {
                  test: /\.jsx?$/,
                  loader: 'babel',
                  query: {
                      presets:['es2015', 'react']
                  }
                }
              ]
            },
          };
          module.exports = WEBPACK_CONFIG
        }(module));
        
  7. 動作確認
    •  ビルドタスク
      • >gulp build
        [11:59:00] Using gulpfile C:\playSandbox\test1\gulpfile.js
        [11:59:00] Starting 'build'...
        [11:59:01] Finished 'build' after 212 ms
        [11:59:15] Version: webpack 1.12.9
                Asset    Size  Chunks             Chunk Names
        main.build.js  693 kB       0  [emitted]  main 
    • Minifyタスク
      • >gulp minify
        [12:03:32] Using gulpfile C:\playSandbox\test1\gulpfile.js
        [12:03:32] Starting 'minify'...
        [12:03:32] Finished 'minify' after 8.87 ms 
  8. activator run実行時にgulpを実行する設定 
    • /test1/projectディレクトリにGulp.scalaを作成(windowsとそれ以外で処理分けてるけど、他にいい方法はないのか・・・)
      • import play.PlayRunHook
        import sbt._
        
        object Gulp {
          def apply(base: File, tasks: String): PlayRunHook = {
        
            object GulpProcess extends PlayRunHook {
        
              var process: Option[Process] = None
        
              override def beforeStarted(): Unit = {
                process = Some(runGulp())
              }
        
              private def runGulp(): Process = {
                val process: ProcessBuilder = System.getProperty("os.name").startsWith("Windows") match {
                  case true => Process("cmd" :: "/c" :: "gulp" :: "--gulpfile=gulpfile.js" :: tasks.split(" ").toList, base)
                  case _ => Process("gulp" :: "--gulpfile=gulpfile.js" :: tasks.split(" ").toList, base)
                }
                process.run()
              }
        
              override def afterStopped(): Unit = {
                process.map(p => p.destroy())
                process = None
              }
            }
        
            GulpProcess
          }
        }
        
    • build.sbtの編集
      • 以下を追記
        import play.sbt.PlayImport.PlayKeys.playRunHooks
        playRunHooks <+= baseDirectory.map(base => Gulp(base, "build"))
        
  9. activator runの実行と確認
    • 以下のような感じで表示されているか確認
      • >activator run
        [info] Loading project definition from C:\playSandbox\test1\project
        [info] Set current project to test1 (in build file:/C:/playSandbox/test1/)
        
        --- (Running the application, auto-reloading is enabled) ---
        
        [info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
        
        (Server started, use Ctrl+D to stop and go back to the console...)
        
        [12:17:43] Using gulpfile C:\playSandbox\test1\gulpfile.js
        [12:17:43] Starting 'build'...
        [12:17:44] Finished 'build' after 501 ms
        [12:17:58] Version: webpack 1.12.9
                Asset    Size  Chunks             Chunk Names
        main.build.js  693 kB       0  [emitted]  main
        
    • localhost:9000にアクセスし、画面表示を確認
以上で終了

0 件のコメント:

コメントを投稿