きっと何者にもなれないSEの記録帳

日々で得たIT技術を記録していきます。

AngularFireでRealtime DatabaseからCloud Firestoreに変更した

AngularFIreを使用してアプリを作っていたのですが、最近のAngularFireのアップデートでRealtime DatabaseからCloud Firestore推しな雰囲気を感じたので、Cloud Firestoreに変更してみました。
AngularFireを使用する上でのRealtime DatabaseとFirestoreとの違いについて書きます。

データ構造

Choose a Database: Cloud Firestore or Realtime Database  |  Firebase

Cloud Firestore Data Model  |  Firebase

Firebaseのページに比較とFirestoreのデータモデルについての情報があります。
開発の際の注意点としては、データ構造を変更しないといけない可能性があります。
Realtime DatabaseではJSONに乗っ取っていれば、データを保存できました。
Firestoreになるとコレクション、ドキュメントという構造に合わせてデータを保存する必要があります。

例えば、以下のような例です。

FireStore

db.collection('objects').doc('object').set(data);

コレクション、ドキュメントという構造に準拠しないといけないです。

Realtime Database

db.object('object').update(data);

Realtime Databaseだと、JSONであればそのまま保存可能でした。

クエリ

angularfire2/querying-collections.md at master · angular/angularfire2 · GitHub

FIrestoreでは、クエリ表現が変わっています。
ページングのためにorderByを使用していたのですが、影響がありました。
Realtime DatabaseではorderByKeyというメソッドでkey順で並べ替えることができました。
Firestoreだと、それに相当するメソッドはなく、orderByというメソッドに並べ替えの機能は集約されています。
orderByメソッドでkey順(Firestoreだとid順)に並べるには特殊な指定が必要でした。

以下の通りです。

Firestoreでkey順に並べ替えるやり方

import { firestore } from 'firebase';
// 中略
db.collection('items', ref => ref.orderBy(firestore.FieldPath.documentId()));

firebaseのnpmモジュールにあるFieldPathクラスを利用をする必要があります。

ただし、keyの命名方法が変わっているので、どのように並び替えたいかによってはそもそもやり方を変える必要がありそうです。
Realtime Databaseの場合、データの作成順に順番に命名されるような形でした。
なので、key順で並べ替えれば、結果として、データを作成した順番に並べ替えができました。
Firestoreの場合、keyの命名は順番に関係なくランダムなようなので、データを作成した順番に並べ替えが必要であれば、データ内に作成日時を付与して、そのフィールドで並べ替えるといった工夫が必要と思われます。

まとめ

上記につまづいたくらいで、そのほかはメソッド名を変更するくらいで比較的簡単にRealtime DatabaseからCloud Firestoreに変更できました。
Firebaseのドキュメントを見てみると、今後はCloud Firestoreがスタンダードになりそうな雰囲気なので、今後はこちらを使っていくようにしたいと思います。

MCP70-532:「Microsoft Azure ソリューションの開発」の試験に合格しました

試験 70-532: Microsoft Azure ソリューションの開発に833点で合格しました。備忘録的に合格までの過程を残したいと思います。
問題や解答は持ち帰れないので、記憶にあるうちにです。

試験の内容

試験時間:150分
問題数:30問
合格点:700点以上
試験問題の形式:

※問題数はうろ覚えなので、若干異なる可能性があります

ケーススタディ形式は、ある企業のシステム開発の状況が問題の条件として与えられていて、各問題に答える形式です。C#のコードの穴埋めを択一問題形式で答える問題が多かったです。

二者択一形式は、前提条件は共通で、各問題でYESかNOかで答える形式です。

C#のコードの問題がケーススタディ形式でほぼ出題されて、そのほかはAzureのサービスに関しての知識を答える問題というような感じでした。workerロールとか、Service Busとかマイナーなイメージがある問題が結構出たりして、試験内容が古いのかなと思いました。

全体的に、択一問題形式でも二択になっているものもあり、まぐれで当たる可能性が大いにある試験だと思いました。
試験時間は150分ありますが、問題数が30問しかないので時間はかなり余ると思います。
私の場合、100分くらいで試験を終えました。

試験勉強の方法

以下のコンテンツを活用しました。

Udemyのコンテンツは試験の範囲を網羅しているので、初学には向いていると思います。英語なのが難点ですが、動画なので、Azureを実際に使いながら見てみると分かりやすいかと思います。
注意点として、この講座自体は最新の試験を反映していて、日本版の試験は遅れています。なので、古い内容で勉強しておく必要があります。具体的にはネットワーク関連の問題は最新だと省かれているようですが、日本版の試験だと出題されていました。

MeasureUpの練習テストは公式の練習テストということですが、本番では練習テストにはない二者択一形式の問題が出題されたり、本番よりも難易度が高いと思われる問題があるなど、ちょっと微妙かもしれません。
練習テストの問題が分かるレベルが必要と思ってしまうと、実はそんなことなかったというのが実際のところです。
練習テストが難しいと思っても、案外なんとかなるような気がします。
PowerShellのコードの穴埋め問題が結構あったのですが、本番では、ほぼ出題されませんでした。

最終的にはAzureの公式ドキュメントのチュートリアルを実践しながら学習しました。実際にAzureを触りながら学習すると理解が深まると思います。

Raspberry Pi3で赤外線リモコンを作る

よく耳にするけどラズパイを使ったことがなく、ふとラズパイで何か作ってみようと思い立ち。
そこそこ実用的であろう赤外線リモコンに挑戦してみました。
電子工作とは無縁な初心者向けの内容になります。

f:id:hi1280:20171015094557j:plain:w300

用意したもの

全てamazonで購入しました。

よく分からなかったので、初心者向けの電子工作キットを購入していますが、最終的に以下があれば良かったです。

  • ラズパイ3
  • ラズパイ用電源
  • microSDカード
  • ブレッドボード
  • ジャンパワイヤ
  • 赤外線受信モジュール
  • 赤外線LED
  • 200 Ω 抵抗

赤外線受信をする

配線

工作キットの提供サイトの情報をそのまま利用します。
Raspberry Piで赤外線レシーバーを作動する « osoyoo.com

LIRCのインストール

LIRCとはLinuxで赤外線を操作可能にするパッケージです。

sudo apt-get install lirc
ラズパイでLIRCを利用するための設定

/boot/config.txtを以下のように修正します。
ラズパイが赤外線のデバイスを認識する為に必要なようです。

修正前

# dtoverlay=lirc-rpi

修正後

dtoverlay=lirc-rpi,gpio_in_pin=18,gpio_out_pin=17

GPIO18が赤外線受信PINになり、GPIO17が赤外線送信PINになります。

ラズパイを再起動します。

sudo reboot
LIRCの起動

/etc/lirc/lirc_options.confを以下のように修正します。

[lircd]
nodaemon = False
driver   = default
device   = /dev/lirc0

lircdを再起動します。
lircdは赤外線の送受信を行うプログラムです。

sudo systemctl restart lircd.service
赤外線受信のテスト

以下のコマンドを実行することで、赤外線を受信できているかを確認できます。
受信モジュールに向かって赤外線を送信するとコンソール上にコードが出力されます。

mode2 -d /dev/lirc0 --driver default

f:id:hi1280:20171015151854p:plain

赤外線受信内容の記録

以下のコマンドを実行することで赤外線受信の内容を記録することができます。

irrecord -f -d /dev/lirc0 --driver default  ~/lircd.conf

プログラムの案内に従い、赤外線の内容を記録します。
何の操作なのか分かる名前を設定して、赤外線を受信させるということを繰り返します。
lircdの設定ファイルが作成されます。

設定ファイルをLIRCの設定に追加します。

sudo cp ~/lircd.conf /etc/lirc/lircd.conf

赤外線送信をする

配線

工作キットの提供サイトのLED点灯の配線を参考にして、赤外線LEDの配線をします。
Raspberry Pi GPIOピンからLEDへ制御信号を出力する « osoyoo.com

GPIO17が赤外線送信のピンなので、そこだけ変更します。

赤外線送信をする

赤外線送信の設定を以下のコマンドで確認します。

$ irsend LIST "" ""

TV
$ irsend LIST TV ""

0000000000000001 KEY_PLAY

赤外線の送信を以下のコマンドで行います。

irsend SEND_ONCE TV KEY_PLAY

感想

一連の流れを書くと何のことはない感じですが、systemdとか知らずにコマンド実行レベルで悪戦苦闘してました。
そこらへんが事前に分かっていれば、すんなり行ったはずです。
これでTVのON/OFFがリモートでできるようになりました。

参考情報

Raspberry Piで赤外線レシーバーを作動する « osoyoo.com

Raspberry Pi GPIOピンからLEDへ制御信号を出力する « osoyoo.com

LIRC - Linux Infrared Remote Control

RaspberryPi3でlircを使ってリモコン化する時の注意事項まとめ - Qiita

XP祭り2017に参加しました

XP祭り2017に初参加しました。

登壇者の方々、エクストリームでした。
2002年から開催されているイベントということで、XPの精神が根付いているんだなぁと感じました。

【基調対談】ワークスタイル改革を実践者する二人が、働き方の本質を語る (青野 慶久さん、倉貫 義人さん)

お二人ともパーカースタイルというラフな感じが印象的でした。

働いている人たちに本当に良いと思ったことをやっていたら、社員が活き活きと働く会社になっていたという話で、青野さんが言っていた社員が出ていくような会社は魅力がないので、会社をやめるということが印象的でした。

副業をしたり、コミュニティに参加したりして、自分の見聞を広げることが今の活動に繋がっているというのも印象的でした。外の世界には活き活きと仕事をしている人たちがいることを知れたことが良い経験になったということで、そういう人たちから学ぶことができると良い方向に向かっていくのだなぁと感じました。

また、IT活用が進んでいく中で、旧来の仕事のスタイルからの変革が起こっているという話も印象的で、例えば、事務をやっていた人がkintoneを使って自分たちの業務が楽になるシステムを作ってしまったという話がありました。
ITの世界だと今までできなかったことがアイデア次第ではできるようになってきているので、今までの仕事の価値がいつの間にかなくなることもあるんだろうなと感じました。

DevOps時代のプロジェクトマネジメントを考えよう (森實 繁樹さん)

プロジェクトマネージャーのあり方は今後変わっていくのだろうと確信する発表内容でした。
今までの決められたことを作るだけのプロジェクトから売れるものを作らないといけないプロジェクトになりつつあるというのがその背景で。
従来のプロジェクトマネージャーはプロダクトをマネージメントすることに注力する必要があるということでした。これは大きな変革だと思いました。求められるスキルも全然違うので。

その分、チームメンバーはお互いにセルフマネージメントが必要になるので、自分のような開発者の立場からするとマネージメントのスキルを身につけていく必要があるなぁと感じました。

全ては Fearless Change から学んだ,開発組織の変革を支えた実践的アプローチ (吉田 慶章さん)

軽快なトークで聞いていて面白いなぁと感じる発表でした。
組織変革には興味があるので、実践的な内容で非常に参考になりました。
「達人を味方に」のパターンは、あまり周りに達人っぽい人がいない環境なので、勇気が入るなと個人的には思いましたが、やれたらすごい効果的なんだろうなとも思いました。機会を作ってやってみたいと思いました。
前セッションの開発者の立場でもマネージメントが必要という中で、参考になる内容でした。

xUTPから学ぶ、記述性の高いユニットテスト (高橋 陽太郎さん)

日本語のメソッド名にしてテストケース名を分かりやすくするというテクニックは使ってましたが、データ初期化メソッドも日本語名にするというのは思いつきませんでした。テストコードの可読性を高めるには色々やり方があるなーと感じました。
JUnit5も出たので、これを機にテストコードを再考してみたいと思いました。

シンプルデザインについて (渋川 よしきさん)

最近、ソフトウェアパターンを学んでいるので、渋川さんのパターンに対する見解は興味深かったです。
パターンはそれ単体というより、組み合わせてランゲージにすることによって、より他者との共通理解を生むものなので、それを意識してパターン化できればと思いました。 フォースはその時の状況に左右されるので、一般化するには弊害があるという意見が斬新でした。そのパターンがどの文脈で使われるかを意識してパターン化できると良いのだなぁと思いました。

濃い質疑応答のススメ ~質問には質問で返してみよう~ (和田 憲明さん)

f:id:hi1280:20170916164225j:plain ワークショップ形式で体験しました。
質問を質問で返すことによって、質問者の気づきを促すことができるというのが本質だと思いました。
命令型のリーダーではなく、サーバントリーダーのような支援型のリーダーに有効なテクニックだなと思いました。
何かを伝える時にその人の納得感が得られる形で伝えられる良い方法だと思いました。

LT祭り&クロージング

LT祭りは面白かったに尽きます。これは現場にいないと分からないと思います。
XP祭りの名物コーナーということで、何か完成された盛り上がりがありました。
本当にエクストリームでした。

初参加枠ということで、XP祭りへの寄贈本をいただきました。
ありがとうございます。

Auth0 + Angularでの認証機能実装

Auth0を利用して、Angularで作成したアプリに認証機能を実装してみました。

auth0.com

Auth0のドキュメントにAngular向けのQuickStartがあるので、そのまま実装すればAuth0を利用できます。

Auth0 Angular 2+ SDK Quickstarts: Login

今回はAuth0で用意されているログイン画面の利用と認証後に扱うことが可能なユーザ情報の表示をやってみました。

ログイン

Auth0 Angular 2+ SDK Quickstarts: Login

つまずくポイントとしては、Auth0のログイン画面から戻ってきた場合にルートコンポーネントのコンストラクタが呼ばれることです。
ngOnInitメソッドは呼ばれないようです。
下記のようにルートコンポーネントで認証後の処理を行なっています。

import { Component } from '@angular/core';
import { AuthService } from './auth/auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  constructor(public auth: AuthService) {
    auth.handleAuthentication();
  }

}

ユーザ情報の利用

Auth0 Angular 2+ SDK Quickstarts: User Profile

QuickStartのコードの場合、認証後に別コンポーネント上でユーザの情報を表示するという作りになっています。
実用的なパターンとしては、認証済みであれば、ヘッダー部にユーザ情報を表示するというケースがあるかなと思いますので、それを実現するように作り変えてみました。

GitHub - hi1280/auth0-angular-samples

app.component.tsで認証及びユーザ情報の表示を行なっています。

app.component.ts

import { Component, OnInit } from '@angular/core';
import { AuthService } from './auth/auth.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
  profile: any;

  constructor(public auth: AuthService) {
    auth.handleAuthentication(() => {
      this.initProfile();
    });
  }

  ngOnInit() {
    this.initProfile();
  }

  logout() {
    this.profile = undefined;
    this.auth.logout();
  }

  initProfile() {
    if (this.auth.userProfile) {
      this.profile = this.auth.userProfile;
    } else {
      if (this.auth.isAuthenticated()) {
        this.auth.getProfile((err: any, profile: any) => {
          this.profile = profile;
        });
      }
    }
  }

}

auth.service.ts

import { Injectable } from '@angular/core';
import { AUTH_CONFIG } from './auth0-variables';
import { Router } from '@angular/router';
import 'rxjs/add/operator/filter';
import * as auth0 from 'auth0-js';

@Injectable()
export class AuthService {

  auth0 = new auth0.WebAuth({
    clientID: AUTH_CONFIG.clientID,
    domain: AUTH_CONFIG.domain,
    responseType: 'token id_token',
    audience: `https://${AUTH_CONFIG.domain}/userinfo`,
    redirectUri: AUTH_CONFIG.callbackURL,
    scope: 'openid profile'
  });

  userProfile: any;

  constructor(public router: Router) {}

  public login(): void {
    this.auth0.authorize();
  }

  public handleAuthentication(cb: any): void {
    this.auth0.parseHash((err, authResult) => {
      if (authResult && authResult.accessToken && authResult.idToken) {
        window.location.hash = '';
        this.setSession(authResult);
        cb();
        this.router.navigate(['/home']);
      } else if (err) {
        this.router.navigate(['/home']);
        console.log(err);
        alert(`Error: ${err.error}. Check the console for further details.`);
      }
    });
  }

  public getProfile(cb): void {
    const accessToken = localStorage.getItem('access_token');
    if (!accessToken) {
      throw new Error('Access token must exist to fetch profile');
    }

    const self = this;
    this.auth0.client.userInfo(accessToken, (err, profile) => {
      if (profile) {
        self.userProfile = profile;
      }
      cb(err, profile);
    });
  }

  private setSession(authResult): void {
    // Set the time that the access token will expire at
    const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
    localStorage.setItem('access_token', authResult.accessToken);
    localStorage.setItem('id_token', authResult.idToken);
    localStorage.setItem('expires_at', expiresAt);
  }

  public logout(): void {
    this.userProfile = undefined;
    // Remove tokens and expiry time from localStorage
    localStorage.removeItem('access_token');
    localStorage.removeItem('id_token');
    localStorage.removeItem('expires_at');
    // Go back to the home route
    this.router.navigate(['/']);
  }

  public isAuthenticated(): boolean {
    // Check whether the current time is past the
    // access token's expiry time
    const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
    return new Date().getTime() < expiresAt;
  }

}

handleAuthenticationメソッドにコールバック関数を渡して、認証後にユーザ情報の取得を行なっているのが修正のポイントです。

まとめ

Auth0を利用すれば、GoogleFacebookTwitterといったソーシャルな認証プロバイダーを利用して、ユーザ情報を取得できるため、面倒な認証処理の実装がショートカットできます。
APIの保護などもできるようなので、認証にまつわる面倒ごとを色々省くことができるようです。

Angularアプリケーションプログラミング

Angularアプリケーションプログラミング

MEAN and Cosmos DBをVisual Studio Team ServicesでAzure App Serviceにデプロイする

サンプルアプリの準備

MEAN構成のサンプルアプリとして以下を使用する
https://github.com/hi1280/angular-cosmosdb

前提条件

Azure CLI 2.0をインストールしている
https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli

Angular CLIをインストールしている

npm install -g @angular/cli

VSTSのプロジェクトが作られている
https://www.visualstudio.com/en-us/docs/setup-admin/team-services/sign-up-for-visual-studio-team-services

Cosmos DBの作成

以下のコマンドを実行する

# コマンドのオプションは環境に応じて適宜変更する  
az login
az group create -n my-heroes-db-group -l "Japan East"

# Cosmos DBをMongoDBのAPIで作成する
# Cosmos DBの名前が競合して作成できない場合、-nオプションの値を適宜変更する  
az cosmosdb create -n my-cosmos-heroes-example -g my-heroes-db-group --kind MongoDB

サンプルアプリとCosmos DBの連携

Cosmos DBの接続文字列を確認する

az cosmosdb list-connection-strings -n my-cosmos-heroes-example -g my-heroes-db-group --query "connectionStrings[0].connectionString"

example-environment.jsを接続文字列の内容に沿って修正する
このパラメータはサンプルアプリからCosmos DB(MongoDB)に接続する際の接続文字列に使われる
f:id:hi1280:20170730143854p:plain

example-environment.jsのファイル名をenvironment.jsに変更する

ローカルでアプリを起動する
# Angular CLIのビルド実行
npm run build

# Node.jsの実行
npm start

http://localhost:3000をブラウザで開く

Azure App Serviceの作成

az group create --location "Japan East" --name myResourceGroup 

# FREEプランで作成
az appservice plan create --name my-app-heroes-plan --resource-group myResourceGroup --sku FREE
az webapp create --name my-app-heroes-example --resource-group myResourceGroup --plan my-app-heroes-plan

# node.jsのバージョン指定
az webapp config appsettings set -g myResourceGroup -n my-app-heroes-example --settings WEBSITE_NODE_DEFAULT_VERSION=6.11.1

Visual Studio Team Services(VSTS)との連携とデプロイ

プロジェクトをVSTSにPushする

プロジェクトルートで以下のコマンドを実行する

# 既存のgitリポジトリを削除
rm -fR .git

# gitのローカルリポジトリに対する操作
git init
git add .
git commit -m "initial commit"

# gitのリモートリポジトリに対する操作
# xxxxxは任意
git remote add origin https://xxxxx.visualstudio.com/_git/my-app-heroes-example
git push -u origin --all
VSTS上でプロジェクトのビルド定義をする

ビルドタスクは以下の通りに定義する

Get Sources

  • This Projectを選択する
  • 該当のリポジトリとブランチを選択する

npmパッケージをインストー

  • Add Taskをクリックし、npmを追加する
  • installコマンドを選択する

Angular CLIのビルド実行

  • Add Taskをクリックし、npmを追加する
  • customコマンドを選択する
  • Command and argumentsrun buildと入力する

サーバのnpmパッケージをインストー

  • Add Taskをクリックし、npmを追加する
  • installコマンドを選択する
  • Working folder with package.jsondistと入力する

成果物を公開する

  • Add Taskをクリックし、Publish Build Artifactsを追加する
  • Path to Publishdistと入力する
  • Artifact Namedistと入力する
  • Artifact TypeServerを選択する

f:id:hi1280:20170730230357g:plain

VSTS上でプロジェクトのリリース定義をする

リリースタスクは以下の通りに定義する

Artifact

  • ビルドのArtifactの最新を選択する

Azure App Serviceにデプロイする

  • Run on agentの+マークをクリックし、Azure App Service Deployを追加する
  • Azure subscription及びApp Service nameを適宜選択する
  • Package or folder$(System.DefaultWorkingDirectory)/my-app-heroes-example-build/distと入力する
  • Generate Web.configにチェックをつける
  • Web.config parameters-Handler iisnode -NodeStartFile index.js -appType nodeと入力する
  • Publish using Web Deployにチェックをつける

f:id:hi1280:20170730230455g:plain


VSTS上からビルド及びリリースを実行した後に、Azure App ServiceのURLを開くとアプリが実行できる

Visual Studio CodeでTypeScriptを書くときのオススメ設定

TypeScriptにある便利機能をVisual Studio Code(以下、VSCode)がいい感じに可視化してくれるので、この二つの組み合わせは非常に良いです。
その中でも個人的に良いと思った機能と設定方法を紹介します。

なお、動作確認は以下のバージョンで行なっています。

Node.js: 6.11.1
TypeScript: 2.4.2
VSCode: 1.14.2
tslint: 5.5.0

誤りを教えてくれる

Compiler Optionsの--strictを有効にする

https://www.typescriptlang.org/docs/handbook/compiler-options.html

--strictを有効にすることで、Compiler Optionsの以下を全て有効にしたことと同様になります。

  • --noImplicitAny
  • --noImplicitThis
  • --alwaysStrict
  • --strictNullChecks

この中でも、--strictNullChecksはコード中のnullやundefinedを極力なくすことができるので良いです。

let strA: string = "str";
// error TS2322: Type 'null' is not assignable to type 'string'.
strA = null;

let strB: string | null = "str";

strB = null;

let objA: {x: string,y?: number} = {x: "str"};

// error TS2532: Object is possibly 'undefined'.
objA.y.toString();

if(objA.y) {
  objA.y.toString();
}

nullを代入するには、nullを許容する型にする必要あり。
オブジェクトでオプショナルなパラメータを定義した場合など、undefinedが許容される可能性がある場合に そのままパラメータにアクセスしようとすると、エラーになる。
if文で存在チェックをすると、エラーが解消される。

便利だし、安全です。

VSCode上でもいい感じに可視化してくれます。
f:id:hi1280:20170723234156p:plain

設定方法

下記コマンドでtsconfig.jsonを新規作成すると楽です。

tsc --init

strictが有効な設定でtsconfig.jsonが作られます。

tslintとvscode-tslintを使う

tslintはTypeScript用の静的解析ツールです。
vscode-tslintはtslintのVSCode拡張機能です。tslintの結果をVSCode上にいい感じに出力してくれます。
f:id:hi1280:20170723214438p:plain

設定方法

tslintのインストール方法

npm install -g tslint

vscode-tslintのインストール先
https://marketplace.visualstudio.com/items?itemName=eg2.tslint

tslintの設定

下記コマンドでtslint.jsonを新規作成すると楽です。

tslint --init

デフォルトのLintの設定が下記になるので、必要に応じて、ルールを個別に設定すれば良いと思います。
https://github.com/palantir/tslint/blob/master/src/configs/recommended.ts

tslintのルール一覧
https://palantir.github.io/tslint/rules/

正しく直してくれる

VSCodeのフォーマット機能を使う

VSCodeではTypeScriptを標準でサポートしていて、コードのフォーマット機能があります。 f:id:hi1280:20170723222825g:plain

設定方法

フォーマットの設定はVSCodeの設定から変更することができます。
f:id:hi1280:20170723224436g:plain

誤りの追跡がしやすい

Debugger for Chromeを使う

Debugger for ChromeVSCode拡張機能です。Chrome上での実行に対して、VSCodeデバッグ機能が使えるようになります。
f:id:hi1280:20170723231934g:plain

設定方法

Debugger for Chromeのインストール先
https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome

launch.jsonの設定

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome",
      "url": "http://localhost:8080",
      "webRoot": "${workspaceRoot}"
    },
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome to local file",
      "file": "${workspaceRoot}/index.html"
    }
  ]
}

localにあるファイルを開く場合とurlにアクセスする場合の設定があります。


最後はTypeScript関係ないですが(汗
とりあえずVSCodeは機能が充実していて良いって話です。

速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ! 速習シリーズ

速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ! 速習シリーズ