かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

TypeScriptのプロジェクトをAzure Web Appにgitデプロイする

TypeScriptのプロジェクトをgit使ってdeployしたいなぁと思います。

問題点

TypeScriptのプロジェクトではgitにJSが含まれてない。でもAzureにはJSをpushしないといけない。

とった対策

デプロイ用ブランチを作って、そこでJS追加してデプロイした。

デプロイするプロジェクト

yoコマンドでExpress TSで作られたプロジェクトにします。

blog.okazuki.jp

プロジェクトの作成

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にアクセスすると、動いてます。ちゃんとできてますね。

f:id:okazuki:20160111134031p:plain

運用どうするの?

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');
});

export default 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と出れば更新成功。

f:id:okazuki:20160111134914p:plain

まとめ

もっといいやり方募集。