LoginSignup
40
41

More than 5 years have passed since last update.

TypeScript & CoffeeScript & Browserifyによるフロントエンド開発環境

Last updated at Posted at 2015-03-24

この記事の内容は古くなりました、新しい記事はこちらです。

Browserifyの記事が増えてきましたが、
自分でもフロントエンド開発環境を構築してみて、納得のいく構築が出来ましたので公開します。

GitHubへのリンク

2015/03/26追記
独自タグによるalias指定をoptionalに変更し、
require時に相対パス指定か、aliasがある時はalias指定のどちらも使えるように修正しました。

概要

このプロジェクトは、以下の機能を持っています。

  • TypeScript、Browserifyの差分ビルド
  • gulp.watch、Watchifyの変更監視による自動ビルド
  • TypeScript、CoffeeScriptのソースファイルを混在出来る
    • ファイルごとに型が欲しいか、短く書きたいか、で好きな方を選べばいい
    • CoffeeScriptで書いたクラスをTypeScriptでrequireして使う、等
    • ※当然ですが、型チェックをするならTypeScript同士じゃないとダメ

また、独自拡張として以下の対応をしています。

また、gulpのbuildやwatch中にエラーが発生するとエラー通知がされるようにしています。

Usage

  1. npm install
  2. tsd update -s
  3. gulp (watch | build | clean) [--env production]

--env productionオプションを付けると公開用として、無しだと開発用としてbundleファイルを生成します。
生成の際、開発用(オプションなし)だとソースマップ生成を、公開用(オプションあり)だとbundleファイルの圧縮を行います。

ファイル構成

root
├── src - ソース置き場
│   ├── index.html
|   └── scripts
├── gulpscripts - gulp用の自作スクリプト
│   ├── ambient-external-module.coffee - ソース内の専用タグ収集(alias、外部モジュール化の補助)
│   ├── error-log.coffee               - エラーログ
|   ├── grep-sync.coffee               - 同期版のgrep
|   ├── gulp-callback.coffee           - stream内の任意の場所でコールバックを発生させる
|   ├── merge-multi-sourcemap.coffee   - 多段ソースマップの合成
|   ├── notify-error.coffee            - エラーのデスクトップ通知
|   └── same-path.coffee               - 複数のパスから一致する部分の取得
├── gulpfile.coffee - gulpメインスクリプト
├── package.json    - nodeパッケージ
└── tsd.json        - TypeScript型定義ファイルパッケージ

ソースへのrequire用のalias、ユーザ外部モジュール化について

ソース中に独自タグである

hoge.ts
// TypeScript
/// <ambient-external-module alias="{filename}" />
foo.coffee
# CoffeeScript
###
<ambient-external-module alias="{filename}" />
###

を埋め込むことにより、
gulpscripts/ambient-external-module.coffee
がソース中のタグを収集し、Browserifyにソースを追加する際にrequireメソッドによりaliasが定義されます。

gulpfile.coffee
b.require('lib/path/to/hoge.js', expose: 'hoge')

また、TypeScriptの場合はdts-bundleにより外部モジュール化されsrc_typingsディレクトリ内にユーザ型定義ファイルが作成されるため、

foo.ts
/// <reference path="root/src_typings/tsd.d.ts" />

import Hoge = require('hoge');
Hoge.foo();

という書き方をする事が出来ます。

多段ソースマップの解決について

AltJSからBrowserifyによるbundleファイル生成までの流れは、以下のようになっています。

  • 1.AltJSのトランスパイル
    • hoge.ts -> tsc -> hoge.js & hoge.js.map
    • foo.coffee -> coffee -c -> foo.js & foo.js.map
  • 2.Browserifyによるbundle
    • (hoge.js & hoge.js.map) & (foo.js & foo.js.map) -> Browserify -> bundle.js & bundle.js.map

中間ファイルであるhoge.jsやfoo.jsのそれぞれのソースマップファイルはAltJSとの紐づけ、
生成物であるbundle.jsのソースマップファイルは中間ファイルとの紐づけがされた状態であり、
bundle.jsのソースマップファイルから、AltJSへと直接紐づける必要があります。

紐づけ方法ですが、mozilla/source-mapによりソースマップ内の対応した位置情報をプロットしてみると、
中間ファイルのソースマップファイルであるhoge.js.mapやfoo.js.mapのgeneratedの位置情報と、
生成物のソースマップファイルであるbundle.js.mapのoriginalの位置情報が対になっていると読み取れます。

multi_source_map_prot.png

この対になっている位置情報を基に、AltJSのoriginalの位置情報と、生成物のbundle.jsのgeneratedの位置情報を取り出せれば、多段ソースマップの問題が解決出来る事になります。

この問題を解決するスクリプトgulpscripts/merge-multi-sourcemap.coffeeを作成し、Browserify実行後に走らせることでこの問題を解決しています。
- ※スクリプト内では、さらに細かく紐づけをしています。
- ※browserifyでuglifyによる圧縮後のソースマップに試しましたが、列の位置が微妙にずれる結果となってしまった為、uglifyと併用した場合は上手く動かない可能性があります。

TypeScriptの定義ファイルについて

定義ファイルは、DefinitelyTypedにより公開されているモジュール用とsrcディレクトリ用の2種類があり、srcディレクトリ用の定義ファイルはgulpで自動生成され、また、TypeScriptを編集した際にも自動更新されます。
また、DefinitelyTypedと同様にルート用の定義ファイル(tsd.d.ts)を用意している為、
定義ファイルのreferenceパスはDefinitelyTyped用、srcディレクトリ用それぞれのtsd.d.tsファイルを参照するだけで良いです。

  • DefinitelyTyped用の定義ファイル

    • typings/tsd.d.ts
  • srcディレクトリ用の定義ファイル

    • src_typings/tsd.d.ts
src/scripts/hoge.ts
/// <reference path="../../typings/tsd.d.ts" />
/// <reference path="../../src_typings/tsd.d.ts" />

参考

40
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
41