TypeScriptのプロジェクトをgit使ってdeployしたいなぁと思います。
問題点
TypeScriptのプロジェクトではgitにJSが含まれてない。でもAzureにはJSをpushしないといけない。
とった対策
デプロイ用ブランチを作って、そこでJS追加してデプロイした。
デプロイするプロジェクト
yoコマンドでExpress TSで作られたプロジェクトにします。
プロジェクトの作成
AzureYoっていう名前でyoコマンドでプロジェクトを作りました。作ったら、gulp, gulp-typescriptを--save-devで追加して、以下のgulpfile.jsを追加してビルドできるようにしておきます。
var gulp = require('gulp'); var ts = require('gulp-typescript'); gulp.task('build', function() {var p = ts.createProject('./tsconfig.json'); return gulp.src('./src/**/*.ts') .pipe(ts(p)) .js .pipe(gulp.dest('./app')); });
tsd installしてビルドして成功することを確認します。
F5を押して実行してみて、http://localhost:3000/にアクセスして起動することも確認しましょう。
gitの準備
リポジトリを作ります。
git init git add . git commit -m "init"
Azure WebAppの作成
適当に作ります。ここら辺はぐぐって。
Deployment credentials(英語設定でポータル使ってまるのでそれっぽい日本語のやつで)を設定して、Continuous deploymentでLocal Git Repositoryを選択しておきます。
gitの準備 その2
git clone urlをコピーして以下のコマンドでリモートを登録します。
git remote add azure コピーしたURL
deploy用ブランチを作って、そっちに移動します。
git branch deploy git checkout deploy
appフォルダに移動して強制的に(.gitignoreされててもおかまいなし)*.jsをコミットします。
cd app git add *.js -f git commit -m 'add js' cd ..
デプロイ
最後にデプロイします。
git push azure deploy:master
package.jsonから起動するjsファイルを勝手に見つけてくれたり、web.configを空気を読んで作ってくれたりします。こんな感じのログが出ます。
PS > git push azure deploy:master Password for リポジトリのURL:443': Counting objects: 30, done. Delta compression using up to 4 threads. Compressing objects: 100% (24/24), done. Writing objects: 100% (30/30), 5.42 KiB | 0 bytes/s, done. Total 30 (delta 1), reused 0 (delta 0) remote: Updating branch 'master'. remote: Updating submodules. remote: Preparing deployment for commit id '82478efd87'. remote: Generating deployment script. remote: Generating deployment script for node.js Web Site remote: Generated deployment script files remote: Running deployment command... remote: Handling node.js deployment. remote: KuduSync.NET from: 'D:\home\site\repository' to: 'D:\home\site\wwwroot' remote: Deleting file: 'hostingstart.html' remote: Copying file: '.gitignore' remote: Copying file: 'bower.json' remote: Copying file: 'gulpfile.js' remote: Copying file: 'package.json' remote: Copying file: 'tsconfig.json' remote: Copying file: 'tsd.json' remote: Copying file: '.vscode\launch.json' remote: Copying file: 'app\app.js' remote: Copying file: 'app\bin\www.js' remote: Copying file: 'app\routes\index.js' remote: Copying file: 'app\views\error.jade' remote: Copying file: 'app\views\index.jade' remote: Copying file: 'app\views\layout.jade' remote: Copying file: 'src\app.ts' remote: Copying file: 'src\tsd.d.ts' remote: Copying file: 'src\bin\www.ts' remote: Copying file: 'src\routes\index.ts' remote: Using start-up script app/bin/www.js from package.json. remote: Generated web.config. remote: The package.json file does not specify node.js engine version constraints. remote: The node.js application will run with the default node.js version 4.2.3. remote: ..................... remote: app@0.1.0 D:\home\site\wwwroot remote: +-- body-parser@1.14.2 remote: ¦ +-- bytes@2.2.0 remote: ¦ +-- content-type@1.0.1 remote: ¦ +-- depd@1.1.0 remote: ¦ +-- http-errors@1.3.1 remote: ¦ ¦ +-- inherits@2.0.1 remote: ¦ ¦ +-- statuses@1.2.1 remote: ¦ +-- iconv-lite@0.4.13 remote: ¦ +-- on-finished@2.3.0 remote: ¦ ¦ +-- ee-first@1.1.1 remote: ¦ +-- qs@5.2.0 remote: ¦ +-- raw-body@2.1.5 remote: ¦ ¦ +-- unpipe@1.0.0 remote: ¦ +-- type-is@1.6.10 remote: ¦ +-- media-typer@0.3.0 remote: ¦ +-- mime-types@2.1.9 remote: ¦ +-- mime-db@1.21.0 remote: +-- cookie-parser@1.4.0 remote: ¦ +-- cookie@0.2.2 remote: ¦ +-- cookie-signature@1.0.6 remote: +-- debug@2.2.0 remote: ¦ +-- ms@0.7.1 remote: +-- express@4.13.3 remote: ¦ +-- accepts@1.2.13 remote: ¦ ¦ +-- negotiator@0.5.3 remote: ¦ +-- array-flatten@1.1.1 remote: ¦ +-- content-disposition@0.5.0 remote: ¦ +-- cookie@0.1.3 remote: ¦ +-- depd@1.0.1 remote: ¦ +-- escape-html@1.0.2 remote: ¦ +-- etag@1.7.0 remote: ¦ +-- finalhandler@0.4.0 remote: ¦ +-- fresh@0.3.0 remote: ¦ +-- merge-descriptors@1.0.0 remote: ¦ +-- methods@1.1.1 remote: ¦ +-- parseurl@1.3.0 remote: ¦ +-- path-to-regexp@0.1.7 remote: ¦ +-- proxy-addr@1.0.10 remote: ¦ ¦ +-- forwarded@0.1.0 remote: ¦ ¦ +-- ipaddr.js@1.0.5 remote: ¦ +-- qs@4.0.0 remote: ¦ +-- range-parser@1.0.3 remote: ¦ +-- send@0.13.0 remote: ¦ ¦ +-- depd@1.0.1 remote: ¦ ¦ +-- destroy@1.0.3 remote: ¦ ¦ +-- mime@1.3.4 remote: ¦ +-- serve-static@1.10.0 remote: ¦ +-- utils-merge@1.0.0 remote: ¦ +-- vary@1.0.1 remote: +-- jade@1.11.0 remote: ¦ +-- character-parser@1.2.1 remote: ¦ +-- clean-css@3.4.9 remote: ¦ ¦ +-- commander@2.8.1 remote: ¦ ¦ ¦ +-- graceful-readlink@1.0.1 remote: ¦ ¦ +-- source-map@0.4.4 remote: ¦ ¦ +-- amdefine@1.0.0 remote: ¦ +-- commander@2.6.0 remote: ¦ +-- constantinople@3.0.2 remote: ¦ ¦ +-- acorn@2.7.0 remote: ¦ +-- jstransformer@0.0.2 remote: ¦ ¦ +-- is-promise@2.1.0 remote: ¦ ¦ +-- promise@6.1.0 remote: ¦ ¦ +-- asap@1.0.0 remote: ¦ ???-- mkdirp@0.5.1 remote: ¦ ¦ +-- minimist@0.0.8 remote: ¦ +-- transformers@2.1.0 remote: ¦ ¦ +-- css@1.0.8 remote: ¦ ¦ ¦ +-- css-parse@1.0.4 remote: ¦ ¦ ¦ +-- css-stringify@1.0.5 remote: ¦ ¦ +-- promise@2.0.0 remote: ¦ ¦ ¦ +-- is-promise@1.0.1 remote: ¦ ¦ +-- uglify-js@2.2.5 remote: ¦ ¦ +-- optimist@0.3.7 remote: ¦ ¦ ¦ +-- wordwrap@0.0.3 remote: ¦ ¦ +-- source-map@0.1.43 remote: ¦ +-- uglify-js@2.6.1 remote: ¦ ¦ +-- async@0.2.10 remote: ¦ ¦ +-- source-map@0.5.3 remote: ¦ ¦ +-- uglify-to-browserify@1.0.2 remote: ¦ ¦ +-- yargs@3.10.0 remote: ¦ ¦ +-- camelcase@1.2.1 remote: ¦ ¦ +-- cliui@2.1.0 remote: ¦ ¦ ¦ +-- center-align@0.1.2 remote: ¦ ¦ ¦ ¦ +-- align-text@0.1.3 remote: ¦ ¦ ¦ ¦ ¦ +-- kind-of@2.0.1 remote: ¦ ¦ ¦ ¦ ¦ ¦ +-- is-buffer@1.1.1 remote: ¦ ¦ ¦ ¦ ¦ +-- longest@1.0.1 remote: ¦ ¦ ¦ ¦ ¦ +-- repeat-string@1.5.2 remote: ¦ ¦ ¦ ¦ +-- lazy-cache@0.2.7 remote: ¦ ¦ ¦ ??-- right-align@0.1.3 remote: ¦ ¦ ¦ +-- wordwrap@0.0.2 remote: ¦ ¦ +-- decamelize@1.1.2 remote: ¦ ¦ ¦ +-- escape-string-regexp@1.0.4 remote: ¦ ¦ +-- window-size@0.1.0 remote: ¦ +-- void-elements@2.0.1 remote: ¦ +-- with@4.0.3 remote: ¦ +-- acorn@1.2.2 remote: ¦ +-- acorn-globals@1.0.9 remote: +-- morgan@1.6.1 remote: ¦ +-- basic-auth@1.0.3 remote: ¦ +-- depd@1.0.1 remote: ¦ +-- on-headers@1.0.1 remote: +-- serve-favicon@2.3.0 remote: remote: Finished successfully. remote: Running post deployment command(s)... remote: Deployment successful. To https://okazuki@okazukinode.scm.azurewebsites.net:443/okazukinode.git * [new branch] deploy -> master
アクセスして動作確認
URLにアクセスすると、動いてます。ちゃんとできてますね。
運用どうするの?
masterの変更をdeployにマージしてappフォルダで毎回git add *.js -fしてcommitしてpushという流れになるのかなぁ。個人的にはもっといい感じにやりたい。
実際にやってみます。
一旦masterブランチに移動します。
git checkout master
そして、src/routes/index.tsをちょっと改造します。
import * as express from 'express'; const router = express.Router(); /* GET home page. */ router.get('/',(req,res,next) => { res.render('index', {title: 'Express'}); }); // 追加 router.get('/hoge', (req, res, next) => { res.send(200, 'Hello world'); }); exportdefault router;
F5を押してローカルでhttp://localhost:3000/hogeにアクセスしてHello worldと出るか確認をします。
コミットをします。
git add . git commit -m 'change index.ts'
deployブランチにマージします。
git checkout deploy git merge deploy master
ビルドしてコミットします。
cd app git add *.js -f git commit -m 'change'
pushします。
git push azure deploy:master
/hogeにアクセスしてHello worldと出れば更新成功。
まとめ
もっといいやり方募集。