Gulpプラグインを使い開発用サーバ-の起動とライブリロードの設定をします。開発用サーバーはExpressサーバーとは独立して起動するのでフロントサイドのSPAの開発が行うことができます。リポジトリはこちら です。
パッケージの追加 package.json のdevDependenciesに今回の作業で追加するパッケージを定義します。
package.json ... "devDependencies": { ... "gulp-watch": "~4.3.5", "gulp-webserver": "~0.9.1", "del": "~2.0.2", "run-sequence": "~1.1.2" }, "scripts": { "start": "node src/server/app.js", "postinstall": "bower install", "clean": "gulp clean", "bower": "gulp bower", "build": "gulp build", "dev-server": "gulp" } }
インストール Dockerイメージのビルド課程でRUN npm install
が実行されます。
Dockerfile ... COPY package.json /app/ COPY bower.json /app/ RUN npm install
package.jsonのscriptsセクションに定義してあるpost install`セクションからBowerパッケージもDockerイメージにインストールされます。
$ docker-compose run --rm f7 npm run build
config.js Gulpのビルドタスクでディレクトリ名やファイル名はまとめてconfig.js に定義しておきます。相対パスの辺りの記述は現在ではふつうに連結して使えました。
config.js 'use strict' ;var path = require ('path' );var filter = { html: '**/*.html' , js: '**/*.js' , css: '**/*.css' , }, srcDir = './src' , relativeSrcPath = srcDir, src = { server: relativeSrcPath + '/server/' , client: relativeSrcPath + '/client/' , scripts: relativeSrcPath + '/client/js/' + filter.js, views: './views/' + filter.html }, distDir = './dist' , dist = { base: distDir, js: distDir + '/js/' , css: distDir + '/css/' }, output = { buildJs: 'bundle.js' , buildCss: 'bundle.css' , bowerJs: 'vendor.js' , bowerCss: 'vendor.css' , minJs: '.min.js' , minCss: '.min.css' }; module .exports = { src: src, dist: dist, filter: filter, output: output }
Gulpビルドタスク (del, run-sequence) 以下のサイトを参考にビルドタスクを書いていきます。
gulpfile.js 最初に作成したgulpfile.js の全文です。
gulpfile.js 'use strict' ;var gulp = require ('gulp' ), gutil = require ('gulp-util' ), concat = require ('gulp-concat' ), rename = require ('gulp-rename' ), uglify = require ('gulp-uglify' ), minifyCss = require ('gulp-minify-css' ), gulpFilter = require ('gulp-filter' ), bower = require ('main-bower-files' ), webserver = require ('gulp-webserver' ), watch = require ('gulp-watch' ), del = require ('del' ), runSequence = require ('run-sequence' ), config = require ('./config' ); gulp.task('clean' , function (cb ) { return del(config.dist.base, cb); }); gulp.task('copy' , function ( ) { return gulp.src(config.src.views) .pipe(gulp.dest(config.dist.base)); }); gulp.task('scripts' , function ( ) { return gulp.src(config.src.scripts) .pipe(concat(config.output.buildJs)) .pipe(gulp.dest(config.dist.js)) .pipe(uglify()) .pipe(rename({ extname: config.output.minJs })) .pipe(gulp.dest(config.dist.js)); }); gulp.task('bowerJs' , function ( ) { var jsFilter = gulpFilter(config.filter.js); return gulp.src(bower()) .pipe(jsFilter) .pipe(concat(config.output.bowerJs)) .pipe(gulp.dest(config.dist.js)) .pipe(uglify()) .pipe(rename({ extname: config.output.minJs })) .pipe(gulp.dest(config.dist.js)); }); gulp.task('bowerCss' , function ( ) { var cssFilter = gulpFilter(config.filter.css); return gulp.src(bower()) .pipe(cssFilter) .pipe(concat(config.output.bowerCss)) .pipe(gulp.dest(config.dist.css)) .pipe(minifyCss()) .pipe(rename({ extname: config.output.minCss })) .pipe(gulp.dest(config.dist.css)); }); gulp.task('watch' , function ( ) { watch(config.src.scripts, function ( ) { gulp.start(['scripts' ]); }); watch(config.src.views, function ( ) { gulp.start(['copy' ]); }); }); gulp.task('webserver' , function ( ) { console .log(config.dist.base); return gulp.src(config.dist.base) .pipe(webserver({ host: process.env.DEV_HOST || 'localhost' , port: process.env.DEV_PORT || 8080 , livereload: true })); }); gulp.task('bower' , ['bowerJs' , 'bowerCss' ]); gulp.task('build' , function (cb ) { runSequence('clean' , ['bower' , 'scripts' , 'copy' ], cb); }); gulp.task('default' , ['webserver' ,'watch' ]);
buildタスク buildタスクではrun-sequence パッケージを使いタスクの直列処理と並列処理を制御します。clean
タスクが終了後に配列で定義したタスクを並列で実行します。
gulpfile.js gulp.task('build' , function (cb ) { runSequence('clean' , ['bower' , 'scripts' , 'copy' ], cb); });
開発用サーバーとライブリロード (gulp-watch, gulp-webserver) 以下のサイトを参考に開発サーバーのタスクを書いていきます。
watchタスク gulp-watch を使ったwatch
タスクを用意して開発しているJavaScriptとHTMLファイルのディレクトリの更新を監視します。JavaScriptとHTMLファイルに編集があった場合にそれぞれscripts
タスクとcopy
タスクが実行されます。公開用のdist
ディレクトリに変換されたファイルがコピーされます。
gulpfile.js gulp.task('watch' , function ( ) { watch(config.src.scripts, function ( ) { gulp.start(['scripts' ]); }); watch(config.src.views, function ( ) { gulp.start(['copy' ]); }); });
webserverタスク gulp-webserver を使い開発用のWebサーバーを起動するタスクです。
gulpfile.js gulp.task('webserver' , function ( ) { console .log(config.dist.base); return gulp.src(config.dist.base) .pipe(webserver({ host: process.env.DEV_HOST || 'localhost' , port: process.env.DEV_PORT || 8080 , livereload: true })); });
開発をクラウド上で行っているので、 docker-compose.ymlにバインドするホスト名をenvironment
セクションの環境変数として0.0.0.0
にバインドします。またports
セクションにDockerホストにマップして公開するポートを定義します。
docker-compose.yml environment: - DEV_HOST=0.0.0.0 - DEV_PORT=8080 ports: - 3030 :3000 - 8090 :8080 - 35729 :35729
buildタスク run-sequence プラグインを使いタスク処理の順番を直列と並列に制御します。
gulpfile.js gulp.task('build' , function (cb ) { runSequence('clean' , ['bower' , 'scripts' , 'copy' ], cb); }); gulp.task('default' , ['webserver' ,'watch' ]);
cleanタスク del パッケージは、プロジェクトをビルドする前のclean
タスクで公開用ディレクトリをクリアする目的で使います。return
しないとタスクが途中で止まってしまうので注意が必要です。
gulpfile.js gulp.task('clean' , function (cb ) { return del(config.dist.base, cb); });
ビルドと実行 同様にbuildコマンドと、
Run arbitrary package scripts にrun-scriptの使い方が書いてあります。package.jsonのscripts
セクションに定義したdev-server
コマンドをnpm run dev-server
から実行します。
$ docker-compose run --rm f7 npm run build $ docker-compose run --rm --service-ports f7 npm run dev-server npm info it worked if it ends with ok npm info using npm@2.13.3 npm info using node@v3.2.0 npm info predev-server framework7-docker@0.0.1 npm info dev-server framework7-docker@0.0.1 > framework7-docker@0.0.1 dev-server /app > gulp [21:02:03] Using gulpfile /app/gulpfile.js [21:02:03] Starting 'webserver' ... ./dist [21:02:03] Webserver started at http://0.0.0.0:8080 [21:02:03] Starting 'watch' ... [21:02:03] Finished 'watch' after 12 ms [21:02:03] Finished 'webserver' after 62 ms [21:02:03] Starting 'default' ... [21:02:03] Finished 'default' after 11 μs
開発用サーバーはsrc/client/js/
とviews
ディレクトリを監視します。ファイルに変更があると、公開用のdist
ディレクトリにファイルの結合と圧縮を行いコピーします。