カテゴリー
AngularJS JavaScript

フレームワーク習得メモ (1) AngularJS

オライリーの「AngularJSアプリケーション開発ガイド」 の1〜2章を写経した。

soohei/AngularTest_001

(プレビューURL)
http://soohei.net/sample/AngularTest_001/test.html
http://soohei.net/sample/AngularTest_001/index.html

Controllerが超頑張って、ViewとModelを常に同期している。という感じ。

カテゴリー
Bower

環境構築メモ (4) Bower

Bowerは、パッケージマネージャーと呼ばれていて、
開発者がコマンドを叩くことで、configファイルに定義された、
必要なコンポーネント(外部ライブラリ) を全てオンラインから集めてきてくれる。
(node.jsのnpm installのように、bower installというコマンドを叩く)

例えば、modernizerを使いたかったら、bower install modernizer。

これを、今までの soohei/grunt-requirejs-seed に組み込んだものが、

soohei/grunt-bower-requirejs-seed

.bowerrc というファイルで、bowerのコンポーネントを配置する場所を定義できるので、
今回は、 “directory”: “www/assets/bower_components/”  を指定。

また、Grunt内の bower というタスクで、RequireJSのベースとなるファイルのパスを指定でき、
target: { rjsConfig: ‘www/assets/js/app.js’ }
というようにしておくと、タスク実行時に、各コンポーネントへのパスをapp.jsに書き込んでくれる。

その他のタスクの連携は今までと同じ。

これで開発時の、コンポーネント (外部ライブラリ) のダウンロードと、ソースコードのビルドの自動化、
Webサイトロード時の、コンポーネントの依存関係やロード順序の交通整理の自動化、
が実現できました。

こういった目的を持ったワークフローのタスク定義や、フレームワーク (AngularJS, Ionic…) の導入を行って、
さらにプロジェクトのひな型生成をやってくれるのが、Yeomanのようです。(Yo + Bower + Grunt)

ここまで手動で積み重ねたものが、Yeomanによってどんな風になるか、明日勉強します。
勉強結果を書く予定の場所はここ

カテゴリー
JavaScript RequireJS

環境構築メモ (3) RequireJS

RequireJSは、JSファイルの依存関係・実行順を、設定ファイル内に予め定義しておくことで、
html上のsourceタグでは先頭のJSファイル1つだけを読み込んで、
残りのJSファイルの非同期ロード・処理順をRequireJSに一任できるライブラリ。

これをワークフローに組み込んだものが、 soohei/grunt-requirejs-seed

今までからの変更点として、開発用のディレクトリをwwwとして、
デプロイ用のディレクトリはwww-buildを別に作るようにした。(www-buildはgitignoreしてある)
またjQueryはCDNからロードしたり、自分が書くコードはRequireJS関係も含め、
全てsource/coffee内でCoffeeScriptで書けるようにした。

この www-build の書き出しは、デプロイ時の処理の中に新たに導入した、RequireJS Optimizer が行う。
(toolsディレクトリの中、Gruntのタスク名は、 exec:build )

また、Optimizerの設定に、”removeCombined”: true を追記することで、
結合に使ったファイルをビルド先にコピーしないようにしたり、
(参考: Do not copy source file when optimizing using requirejs – Stack Overflow)
前回紹介した、Gruntでのugilify時のオプション preserveComments: ‘some’ も採用してます。

それとRequireJSの書き方の話で、requireとdefineの違いについては、
「javascript – RequireJs – Define vs Require – Stack Overflow」 に書かれているベストアンサーが的確。

そもそものRequireJSの理解は、bouzeの 「Require.jsを試してみた | blog.bouze.me」 に超救われた。

最後に、gruntのコマンドなどを整理すると、
人間が作業するのはwww/source以下。Gulpが頑張るのがwww/assets以下。
デプロイに使うのは、www-buildに残ったファイル一式
普段は、grunt
デプロイ前に、grunt -dist
www-buildをルートにしてサーバーを立てて、動作チェックをするとは、 grunt prod-serve

次回は、JSのライブラリの管理をする「パッケージマネージャー」、Bowerです。

カテゴリー
Grunt

環境構築メモ (2) Grunt

前エントリーのgulp編 でGulpに鞍替えしたけど、色々あってGruntに戻ります。

最初のGrunt〜Gulpのノウハウを込めて、Gruntの作業環境もアップデート。

こちらです。 soohei/grunt-seed

Gulpと同じことをしているけど、だいぶ設定ファイルが短くなった。

Gulpの時と同様、assets/libs/js の中身を機械的にconcatして、
source/js/libs.js としているので、ライブラリの依存関係や読み込み順によっては地雷になります。
そこでこの後導入されるのが、もっと歴史が古いけど、手付かずだった、RequireJSです。

それと、JS, CSSのライセンス表記を残すために、distタスク内で、
ugilify後にライセンスをconcat (concat:libs_js, concat:libs_css) しているけど、

uglifyのオプションで、 preserveComments: ‘some’ というのがあることを後日知りました。
CSSはだいたい同じ作者のJSとセットなので、JSにライセンス残せばOKな気が。

gulp編の繰り返しになるけど、
人間が作業するのはsource以下。Gulpが頑張るのがassets以下。
デプロイ時はsource不要で、assetsフォルダのみでOK。
普段は、grunt
デプロイ前に、grunt -dist

次回へ続く。

カテゴリー
Gulp

環境構築メモ (1) Gulp

Gruntを覚えたばかりだったけれど、Gulpへ乗り換えた仲間がいたので実践。

Gruntだろうが、Gulpだろうが、やりたいことは同じ。

基本ワークフロー

・Compass(Sass)の変更をwatchして、コンパイル、適宜結合
・CoffeeScriptの変更をwatchして、コンパイル、適宜結合
・Slicy連携、自作スプライトイメージ処理用Rubyスクリプトを自動実行 → これをCompassが良い感じに処理
・これらの処理に応じてブラウザを自動的に再読み込み

デプロイ用ワークフロー

・CSSを最適化 (ベンダープレフィックスやmedia-query周り、プロパティのソートなど)
・CSSをminify
・pngをminify
・JavaScriptをUglify
・JSライブラリのライセンスも良い感じに残す

こうして出来たのが、
soohei/gulp-seed
です。

人間が作業するのはsource以下。Gulpが頑張るのがassets以下。
デプロイ時はsource不要で、assetsフォルダのみでOK。
普段は、gulp
デプロイ前に、gulp -dist

次回へ続く。

カテゴリー
Sublime Text Tools

Sublime Text 3

Sublime Textを2から3にアップデートしたので設定、プラグインを再確認。

今使っているプラグインを一覧する
(~/Library/Application Support/Sublime Text 3/Packages/User/Package Control.sublime-settings)

▽ ユーティリティ系

・All Autocomplete
今開いている全タブの中からワードを補完する

・AutoFileName
ファイル名補完が賢くなる

・Autoprefixer
ベンダープレフィックス補完
(Cmd + Shift + Pから使う)

・DocBlockr
コメントを書きやすく
(CoffeeScriptでは、###* とタイプ)

・Emmet
旧ZenCoding

・LineEndings
改行コード

・Markdown Preview
マークダウンをプレビュー
(Cmd + Shift + Pから使う)

・SublimeCodeIntel
コード補完を賢く

・Tag
タグの扱いを賢く

・Terminal
Cmd + Shift + T でターミナルでファイルのある場所を開く
Cmd + Shift + Opt + T だとプロジェクトのある場所を開く

・SideBarEnhancements
サイドバーを賢く

・TrailingSpaces
末尾の空白をハイライト

▽ 言語系

・AngularJS
・AngularJS (CoffeeScript)
・Better CoffeeScript
・Compass
・Haml
・jQuery
・Sass
・SCSS

▽ アプリの設定ファイル

{
	"auto_indent": true,
	"color_scheme": "Packages/User/Cobalt (SL).tmTheme",
	"disable_formatted_linebreak": true,
	"disable_tab_abbreviations": true,
	"font_face": "Menlo",
	"font_size": 15.0,
	"highlight_line": true,
	"line_padding_top": 2,
	"smart_indent": true,
	"tab_completion": false,
	"tab_size": 4,
	"translate_tabs_to_spaces": true,
	"trim_trailing_white_space_on_save": true,
	"word_wrap": true
}

▽ *.js, *.coffee, &.css, *.scss には個別の設定

{
  "tab_size": 2,
  "translate_tabs_to_spaces": true
}
カテゴリー
CoffeeScript Compass Grunt JavaScript Tools

コーディング環境 (2014.08)

日々進化している最近のコーディング (フロントエンド開発) 環境について、
ここ1年くらいのノウハウを詰めて、
極端には新しいもの好きではない視点で整理します。

目次:
1. psdからのスライス
2. Compass
3. スプライトイメージの自動化
4. CoffeeScript
5. Gruntによる自動化
6. ローカルサーバー
7. その他

1. psdからのスライス

slicy

Slicyというアプリを使い始めてからは、ずっとこれです。
Photoshopのレイヤーやグループ名に画像のファイル名(+拡張子)を付けることで、
ワンクリックで画像を書き出せます。

ファイル名に@2xと付けることで、Retina用画像(@2x)と、
等倍画像を同時に書き出すこともできます。

その他に@boundsというレイヤーをつくって矩形領域を指定したり、
@slicesというフォルダをつくって、その中にファイル名と
領域指定用のレイヤーをつくることも出来ます。

公式サイトのヘルプを読んだり、
サンプルをダウンロードすると理解が早いです。

 

2. Compass

CSSにネスト構造をつくって記述できるフレームワーク。
インストールの方法などは公式ドキュメント参照。
このエントリーでは、”gem install compass –pre” でインストール出来る、
Compass 1.0.0.rc.1を使って、SCSSの文法で書いています。

必要なコマンドは
compass watch

 

3. スプライトイメージの自動化

Compassのmixinを使えば、関数や変数を使ってCSSを記述できます。
一番の恩恵として、スプライトイメージの生成の自動化について、
色々試行錯誤した結果、現時点で使っているmixinを紹介します。
参考: Using Compass Generated Sprite Sheets in Responsive Sass, by Jayson Jacobs.

・サーバーにアップするファイルはassetsフォルダにまとめる
・サーバーにアップしないファイルはsourceフォルダにまとめる
・Source Mapを有効にするとChromeでscssファイルのデバッグができる
参考: Working with CSS Preprocessors – Google Chrome
・ロゴ用の画像として、
/resource/images/sprite/logo.png
/resource/images/sprite_2x/logo_2x.png (2倍サイズ)
の2枚が用意されているとする。

config.rb

css_dir = "assets/css"
sass_dir = "source/sass"
images_dir = "source/images"
generated_images_dir = "assets/images"
javascripts_dir = "assets/js"
fonts_dir = "assets/fonts"
output_style = :nested
relative_assets = true
line_comments = true
preferred_syntax = :scss
sass_options = { :sourcemap => true }

HTML

<div class="logo">
<div class="sprite">Logo</div>
</div>

→ .sprite部分に、background-imageが適用される

scssファイル

// スプライト画像
.sprite {
display: block;
overflow: hidden;
background-repeat: no-repeat;
text-align: left;
text-indent: -10000px;
font-size: 1px;
line-height: 1px;
}

@mixin sprite-background($sprites, $sprites-img, $name, $scale, $skip-base-params:false) {
background-image: $sprites-img;
@include background-size(image-width(sprite-path($sprites)) / $scale auto);

//retina時に重複するパラメータをスキップするための分岐
@if not($skip-base-params){
height: image-height(sprite-file($sprites, $name)) / $scale;
width: image-width(sprite-file($sprites, $name)) / $scale;
$ypos: nth(sprite-position($sprites, $name), 2) / $scale;
background-position: 0 $ypos;
}
}

$sprites: sprite-map("sprite/*.png", $spacing: 2px);
$sprites-img: sprite-url($sprites);
$sprites_2x: sprite-map("sprite_2x/*.png", $spacing: 4px);
$sprites-img_2x: sprite-url($sprites_2x);

@mixin sprite-image ($name) {
.sprite {
@include sprite-background($sprites, $sprites-img, $name, 1);
}
.backgroundsize.retina_2x & {
.sprite {
@include sprite-background($sprites_2x, $sprites-img_2x, $name, 2, true);
}
}
}

→ /assets/images/ フォルダ内にスプライトイメージが書き出される。

 

また、Slicyからの作業の効率化を考えて、一つ、自作のRubyのスクリプトを使っています。
ruby mv_sprite.rb
で実行すると、実行したディレクトリ以下の@2xという名前がついた画像を、
_2xにリネームして、さらに_2x付きのディレクトリを作ってその中へ移動します。
@がついたファイル名が、Compassではコンパイルエラーを起こすことへの対処です。
(Compass 0.13.alpha.12時点)
上記mixinも、Slicy書き出し→このRubyの処理、が前提になっています。

例:
assets/images/sprite/logo.png
assets/images/sprite/logo@2x.png

assets/images/sprite/logo.png
assets/images/sprite_2x/logo_2x.png

mv_sprite.rb

# ディレクトリを再帰的に抽出する
require 'pp'
require 'FileUtils'

root = File.expand_path(File.dirname(__FILE__))
root = ARGV[0] if ARGV[0]

# フォルダの一覧を取得
dir_entries = Dir.glob(root + "/" + "**/*")
# pp dir_entries

for filePath in dir_entries do
# pp file
ext = File::extname(filePath) # 拡張子取得

# 画像のみに処理
if( ext == '.jpg' || ext == '.png' || ext == '.gif' )
dir = File::dirname(filePath) # ディレクトリ
base = File::basename(filePath,ext) # 拡張子除去
twox_index = base.index('@2x')

# @2xを含む
if( twox_index && twox_index >= 0 )
p "#{dir}/#{base}#{ext}"
parent_dir = File::dirname(dir) # e.g. path_to_htdocs/common/img
my_dir = File::basename(dir) # e.g. sprite
twox_my_dir = "#{my_dir}_2x" # e.g. sprite_2x
twox_dir = "#{parent_dir}/#{twox_my_dir}" # e.g. path_to_htdocs/common/img/sprite_2x
twox_base_ext = "#{base.sub('@2x', '_2x')}#{ext}" # e.g. hoge_2x.png

# ディレクトリがなければ作る
FileUtils.mkdir_p(twox_dir) unless FileTest.exist?(twox_dir)

# ファイルを移動する
File.rename filePath, "#{twox_dir}/#{twox_base_ext}"

p "#{twox_dir}/#{twox_base_ext}"
p '--'
end
end
end

 

4. CoffeeScript

JavaScripterの間ではすっかり浸透したCoffeeScript を使います。
コードの行数、文字数が減らせるので、その分コメントを充実させられます。

必要なコマンドは
coffee -o assets/js -cw assets/coffee

 

ここまでの内容をまとめたものは、
https://github.com/soohei/compass-coffee-template
にあります。

 

5. Gruntによる自動化

注) 最新の状況はこちら

Gruntはこれまでに書いた、CompassやCoffeeScriptのコンパイル処理、
ソースの結合やMinify、ファイルの監視、簡易サーバーの起動などを
全て一つのコマンドで実行してしまう脅威の仕組みです。
他にGulpというのがあるようなのですが、まだ試していないです..
セットアップ方法は省略します。普段使っている基本的な設定・プラグインの構成は以下。

package.json (使用しているパッケージの一覧)

{
"name": "sample",
"version": "0.0.0",
"author": "Sohei Kitada",
"devDependencies": {
"grunt": "~0.4.5",
// ベンダープレフィックス補完
"grunt-autoprefixer": "~1.0.0",
// メディアクエリーをまとめる
"grunt-combine-media-queries": "~1.0.19",
// CoffeeScript
"grunt-contrib-coffee": "~0.11.0",
// Compass
"grunt-contrib-compass": "~0.9.1",
// ファイルの結合
"grunt-contrib-concat": "~0.5.0",
// 簡易サーバー
"grunt-contrib-connect": "~0.8.0",
// Minify JS
"grunt-contrib-uglify": "~0.5.1",
// ファイルの更新検知
"grunt-contrib-watch": "~0.6.1",
// CSSのプロパティをソートする
"grunt-csscomb": "~3.0.0",
// Minify CSS
"grunt-csso": "~0.6.3",
// シェルコマンドの実行
"grunt-exec": "~0.4.6"
}
}

 

Gruntfile.coffee (タスク)

module.exports = (grunt) ->
# load package.json
grunt.initConfig
pkg: grunt.file.readJSON 'package.json'

compass:
dist:
options:
config: 'config.rb'
outputStyle: 'compressed'
environment: 'production'
dev:
options:
config: 'config.rb'

coffee:
compile:
options:
join: true
files:
'source/js/script.js': ['source/coffee/**/*.coffee']

exec:
mv_sprite:
cmd: 'ruby mv_sprite.rb'

autoprefixer:
options:
browsers: ['last 2 version', 'ie 8', 'ie 9']
default:
src: 'assets/css/style.css'
dest: 'assets/css/style.css'

csso:
default:
src: 'assets/css/style.css'
dest: 'assets/css/style.css'

cmq:
default:
src: 'assets/css/style.css'
dest: 'assets/css/style.css'

csscomb:
default:
src: 'assets/css/style.css'
dest: 'assets/css/style.css'

concat:
jsdefault:
src: [
'source/jslib/**/*.js'
'source/js/**/*.js'
]
dest: 'assets/js/script.js'

license: {
src: [
'source/jslib/_license.js'
'assets/js/script.js'
]
dest: 'assets/js/script.js'
}

uglify:
default:
src: 'assets/js/script.js'
dest: 'assets/js/script.js'

connect:
uses_defaults: {}

watch:
options: # enable livereload
livereload: true
compass: # watch scss files
files: 'source/sass/**/*.scss'
tasks: ['compass:dev']
coffee: # watch scss files
files: 'source/coffee/**/*.coffee'
tasks: ['coffee:compile']
js: # watch js files
files: ['source/js/**/*.js', 'source/jslib/**/*.js']
tasks: ['concat:jsdefault']
image: # watch image files
files: 'source/images/**'
tasks: ['exec:mv_sprite']
html: # watch html files
files: '**/*.html'

# load Grunt Plugins
grunt.loadNpmTasks('grunt-autoprefixer')
grunt.loadNpmTasks('grunt-combine-media-queries')
grunt.loadNpmTasks('grunt-contrib-coffee')
grunt.loadNpmTasks('grunt-contrib-compass')
grunt.loadNpmTasks('grunt-contrib-concat')
grunt.loadNpmTasks('grunt-contrib-connect')
grunt.loadNpmTasks('grunt-contrib-uglify')
grunt.loadNpmTasks('grunt-contrib-watch')
grunt.loadNpmTasks('grunt-csscomb')
grunt.loadNpmTasks('grunt-csso')
grunt.loadNpmTasks('grunt-exec')

# tasks

# defalt
grunt.registerTask('default', ['connect', 'watch']);

# development
grunt.registerTask('dev', ['exec:mv_sprite', 'compass:dev', 'coffee:compile', 'concat:jsdefault']);

# distribution
grunt.registerTask('dist', ['exec:mv_sprite', 'compass:dist', 'autoprefixer', 'cmq', 'csscomb', 'csso', 'coffee:compile', 'concat:jsdefault', 'uglify', 'concat:license']);

return

 

「grunt」の処理内容
・connect
簡易Webサーバーの立ち上げ (プロジェクトによっては使わない)

・ファイルの更新の監視
1) images内が更新されたら…「3. スプライトイメージの自動化」で紹介したRubyコマンドを実行
2) scssが更新されたら…Compassを再コンパイル
3) coffeeが更新されたら…CoffeeScriptを再コンパイル → jsファイルが書き出される
4) jsが更新されたら…JSファイルを一つのファイルに結合

「grunt development」の処理内容
・上記 1),2),3),4)を順番に実行

「grunt distribution」の処理内容
・1)を実行
・2)をdist用の設定 (outputStyle: ‘compressed’) で実行
・ベンダープレフィックスを追加
・メディアクエリーをまとめる
・CSSのプロパティをソート
・CSSをMinify
・3)を実行
・4)を実行
・JSをMinify
・上部にライブラリ関係のライセンスを追加

ここまでの内容をまとめたものは、
https://github.com/soohei/grunt-template
にあります。

 

6. ローカルサーバー

本気で開発する場合は、MAMPでローカルサーバーを立てています。
詳しくは、
MAMP 2 → MAMP 3
MAMPでバーチャルホストの設定 (2種類)
あたりに書かれています。

 

7. その他

最後に、ここまでのワークフローで生まれた、
本番環境にアップ不要のファイルはサーバーに転送しないように、
Transmitを設定しています。

transmit

 

カテゴリー
Tools

MAMP 2 → MAMP 3

MAMPのphpMyAdminの動作があやしかったので、これを機にローカルのWebサーバーをMAMP2からMAMP3にアップデート。以下手順です。

1)
MAMPのHP(http://www.mamp.info/en/downloads/)から
から最新版をダウンロード。

2)
既存の/Applications/MAMPをリネームして退避。(例: MAMP_old)
ダウンロードしたインストーラーを使って、MAMP 3をインストール。

/Applications フォルダには、新しくできたMAMPフォルダと、これまで使っていたMAMP_oldフォルダが並ぶ。

4)
MAMP_old/db
MAMP_old/conf/apache/httpd.conf

をそれぞれMAMPフォルダの同一階層に上書きコピー。

5)
終了!(MAMP_oldは削除してOK)

MAMPのバーチャルホスト設定については、以前書いた記事「MAMPでバーチャルホストの設定 (2種類)」をどうぞ。

カテゴリー
Diary

ニューヨークから帰国 (3度目)

1月末から移動を始め、7月後半に再び戻って来ました。
忘れないように記録。

5月
・Bedfordの南の方で再びサブレット暮らし。
・間借りしているPARTY NYが引っ越し。DumboのSTINK DIGITALの中へ。
・Bostonへ1泊、小旅行。

6月
・Bedfordの西の方でサブレット暮らし。
・一人暮らしのアパート探し開始。
・下旬についに新居へ引っ越し。

7月
・ビザの書類が完成。移民局へ申請!
・帰国

一番苦労したのは、新居のインターネットの開通。SSNを持っていないので、電話で説明して、国際免許証をFAXして、電話して工事日の予約して、途中たまたま当たった優しいコールセンターのおばさんがいなければ無理だった。

食生活はとても改善して、炊飯器でご飯を炊いて、冷凍餃子と納豆ばっかり食べてました。
Midoriyaさんありがとう。

そろそろ色々な仕事が落ち着いてきたので、無事にビザが手に入って、あちらへ行ったら色々詰め込む予定。

会社のWebの更新が止まってますが、仕事してます。
順調です。

カテゴリー
Diary

ニューヨーク 約2ヶ月

再び帰ってきました。

今回は日本の締め切りに重なって、あまりアクティブな出来事がなかったので、
今までに住んだところの記録を書きます。

5週間の滞在で日本に帰省する友人宅を中心に計3部屋に住みました。
家賃の出費がだいぶ改善。みんなありがとう。
東京の家も解約したので、固定費がだいぶ減った。

まずは前回の滞在から

・1月下旬 Bushwick (Morgan Ave)

Airbnbで借りたアパート。
マンハッタンから地下鉄(L)で15分くらい。
駅前のSwallow CafeがGood.
Whole Foods Marketの惣菜ばっかり食べてた。

・2月上旬 East Village (1st Av)

Airbnbで借りたアパート。
同じくLラインのマンハッタンの東端。14st沿いは便利。
ピザばっかり食べてた。日本食も色々あるエリア。
2Avにある味噌屋のラーメンにチャーシューと野菜トッピングがうまい。

・2月中旬 Times Square (42st)

アパートが見つからなくてホテル。
超有名な観光エリア。あまり住む場所ではない。
スープとサンドイッチばっかり食べてた。

・2月下旬 Williamsburg (Bedford Av)

Airbnbで借りたアパート。
Lラインで、Brooklynに入って1駅目。人気エリアで週末はかなり賑わっている。
ベーグルばっかり食べてた。Baglesmithはかなりおすすめ。

ここからが今回の滞在

・3月上旬〜中旬 Lower Eastside (Delancey St / Essex St)

帰省中の友人アパート。
KATZ’Sという有名サンドイッチ屋の近く。
他にもWhynotというカフェや、Mikey’s Burgerというハンバーガー屋が良い。
ベーグルとハンバーガーばっかり食べてた。SOHOが徒歩圏内。住みやすい。

・3月下旬 Midtown East (Grand Central)

帰省中の友人アパート2。
初ミッドタウン。日本食デリがあったり、ここは日本人エリアだと思った。
ビジネス街なので、昼は人が多くて、夜は少なめ。高いビルが多い。
住みやすいけどランドリーとか値段が高い。

・4月上旬 Williamsburg (Bedford Av)

前に住んだ時と1ブロック違い。
PARTYのトムの部屋をサブレット。初ルームシェア。Thanks Tom!
色々なところに住んで、Williamsburgに戻って来たら、やはり良いエリアだった。
ビザが取れたら、Williamsburgでアパート探すことになりそう。

少し締め切りが落ち着いて、ニューヨーク中心に動きそうな仕事もいくつか始まって、
楽しくなったところで、2週間の一時帰国。ビザ申請の準備を進めたり、
ここでしゃべります。

それと、そのビザ申請にあたってポートフォリオの印刷が必要だったので、
弊社Webをアップデートしました。
http://td-inc.jp/category/portfolio を印刷すると、ポートフォリオが完成。
(いくつかオンラインでは紹介してないプロジェクトもあるけれど)