Gulpプラグインを使い開発用サーバ-の起動とライブリロードの設定をします。開発用サーバーはExpressサーバーとは独立して起動するのでフロントサイドのSPAの開発が行うことができます。リポジトリはこちらです。
パッケージの追加
package.jsonのdevDependenciesに今回の作業で追加するパッケージを定義します。
...
"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
が実行されます。
...
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に定義しておきます。相対パスの辺りの記述は現在ではふつうに連結して使えました。
'use strict';
var path = require('path');
var filter = {
html: '**/*.html',
js: '**/*.js',
css: '**/*.css',
},
srcDir = './src',
/*relativeSrcPath = path.relative('.', srcDir),*/
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の全文です。
'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
タスクが終了後に配列で定義したタスクを並列で実行します。
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
ディレクトリに変換されたファイルがコピーされます。
gulp.task('watch', function () {
watch(config.src.scripts, function () {
gulp.start(['scripts']);
});
watch(config.src.views, function () {
gulp.start(['copy']);
});
});
webserverタスク
gulp-webserverを使い開発用のWebサーバーを起動するタスクです。
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ホストにマップして公開するポートを定義します。
environment:
- DEV_HOST=0.0.0.0
- DEV_PORT=8080
ports:
- 3030:3000
- 8090:8080
- 35729:35729
buildタスク
run-sequenceプラグインを使いタスク処理の順番を直列と並列に制御します。
gulp.task('build', function(cb) {
runSequence('clean', ['bower', 'scripts', 'copy'], cb);
});
gulp.task('default', ['webserver','watch']);
cleanタスク
delパッケージは、プロジェクトをビルドする前のclean
タスクで公開用ディレクトリをクリアする目的で使います。return
しないとタスクが途中で止まってしまうので注意が必要です。
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
ディレクトリにファイルの結合と圧縮を行いコピーします。