howdylikes

Google Developersってわかりづらいよね

VSCodeでtslint

VSCode

tslintの拡張機能をインストール

tslint | Visual Studio Marketplace

設定ファイルはDefault Settingsに作られている。
f:id:howdy39:20160314215849p:plain

ファイルが空文字になっているけどデフォルトはtslint.json使う模様。

tslint.json

プロジェクト直下にtslint.jsonを作る
内容は以下のページ参照

https://github.com/palantir/tslint/blob/master/tslint.json

結果

f:id:howdy39:20160314220052p:plain いろいろ怒られるようになりました。。 文字列ダブルクォートが標準なんですね。。知らんかった。

Webpack + TypeScriptのTS2304: Cannot find name 'require'エラーの解決法

Webpackでモジュール読み込むときにrequire使いますがjsからなら問題はないですがTypeScriptからだとコンパイルエラーになります。
指定方法がTypeScript上おかしいのでimport文でもだめだと思われます。

require('jade!./app.jade')();
// ERROR in ./src/ts/components/app/app.ts
// (14,25): error TS2304: Cannot find name 'require'.

その場合、declare文を記載してrequireという関数があると認識させればOKです。 requireのあるファイル全てに書くのはあれなので共通のd.ts作ってそこをreference pathで指定です。

declare function require(string): any;

参考サイト

github.com

Error: [$compile:multidir] Multiple directives

表題の通り実行時にエラーが出たので原因と解決方法のメモです。

Webpack + AngularJS + TypeScript構成です。

最終的にエラーになる理由はディレクティブを複数定義したからです。 Webpackが生成するbundle.jsが同じのを吐いているんですよね。

// 呼び出し元
import './app/app';
import './header/header';
// 変換後
    __webpack_require__(8);
    __webpack_require__(9);

/***/ },
/* 8 */
/***/ function(module, exports) {

        // 省略
    angular.module('app')
        .component('myApp', new MyAppComponent());

/***/ },
/* 9 */
/***/ function(module, exports) {

        // 省略
    angular.module('app')
        .component('myApp', new MyAppComponent());
/***/ },

Step 1

いろいろためしてみたところtsconfig.jsonをリネームして読まないようにして実行したところすんなり通る。。

ちなみにこんなんです。

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "outDir": ".",
        "out": "dummy.js",
        "rootDir": ".",
        "sourceMap": false
    },
    "files": [
        "./src/ts/app.ts"
    ]
}

Step 2

1つずつ消していったところ

"out": "dummy.js",を消した時にエラーが消えました。

いやーよくわからない(自分がわかってないだけ)ですね。

tsconfingがTypeScriptコンパイラのオプションてのはわかるんですがそこにts-loader経由でWebpackに入れるとなんでこういう動きになるのか。。。

もともとWebpackを使わずにコンパイルしてたのでoutとかが残っちゃってたのですが一旦tsconfigを消しても不都合はなさそうなのでその作戦でいきます。

webpackとts-loaderとが何をしているかちゃんとみないとあかんですね、黒魔術すぎて詰まるとさっぱりわからない。。。

Angular JS require

Angularをrequireしてやったぜと意気揚々としていたのですが
angularという変数がグローバルに作られててなんでや、、、と思ってソースを追っていたら angularが結局グローバルに書き込んでいるみたいですね。。 https://github.com/angular/angular.js/blob/0b1b9112a341f7f798db915575fad63e0e59894e/src/Angular.js#L163

angular           = window.angular || (window.angular = {}),

つまりエントリーポイントの頭でrequireしてやればその他のところでは普通にangular.XXXが使えるということ。。

var myAngular = require('angular');
// つまりrequire('angular');だけでいい

console.log(myAngular); // Object {version: Object, callbacks: Object}
console.log(angular); // Object {version: Object, callbacks: Object}

webpackメモ

全然わかっていないのですが、webpackというのがフロントエンド開発でよさげらしいので試してみたメモ。

基本的な使い方は公式のチュートリアルがわかりやすいのでそちらを参照。

SourceMap

そのまま1つのjsにまとめられたらデバッグができなくて死が見えているのでSourceMapを出力する。

webpack実行時にオプションを追加して実行

実行時に--devtool source-mapを追加するだけ。

webpack --devtool source-map source.js dest.js

Developer toolsのsourceタブにwebpack://というのができています。 ここからブレークポイントを入れることが可能です。簡単ですね。
f:id:howdy39:20160202124228p:plain

configファイルを使う

コマンド打つのもだるいのでconfigファイルを作ります。
リファレンスは以下のページ

http://webpack.github.io/docs/configuration.html

configファイルを作る

touch webpack.config.js
//webpack.config.js
module.exports = {
    entry: './source.js',
    output: {
        filename: 'dest.js'
    },
    devtool: "#source-map",
};

実行

webpack

f:id:howdy39:20160202125831p:plain

wetpack.config.jsというのがデフォルトの設定ファイル名です。
開発用とか切り替えたい場合は別ファイル名で作って--configで指定可能です。

webpack --config webpack.config-dev.js 

gulpからwebpackを呼ぶ

gulp-webpackというのを使います。

github.com

npm install -D gulp-webpack
touch gulpfile.js
//gulpfile.js
var gulp = require('gulp');
var webpack = require('gulp-webpack');
gulp.task('webpack', webpackFunc);

function webpackFunc() {
    gulp.src('source.js')
        .pipe(webpack(require('./webpack.config.js')))
        .pipe(gulp.dest('./'));
}

gulpのsrcに元ファイルを組み込んでいるのでwebpack.config.jsのentryは意味が無い扱いになっているんでしょうかね。ちょっと不透明な部分ですね。

実行

gulp webpack

f:id:howdy39:20160202125710p:plain

gulp 初期構築メモ

gulpでsassを使うまで

前提条件

nodeJSが使えること。

gulp

gulpのインストール

npm i gulp -g
# iはinstallのエイリアス

package.jsonを作る

npm init

sass

sassのファイルを作る

mkdir sass && touch sass/style.scss
/*style.scss*/
h1 {
  color: red;
  &:hover {
    font-size: large;
  }
}

sassのライブラリをインストール

npm i -D gulp-sass
# -Dは--save-devのエイリアス

gulpfile.jsを作る

srcに対象ファイルでpipeで処理を繋げていきます。

touch gulpfile.js
// gulpfile.js
'use strict';
var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', sassFunc);

function sassFunc() {
    gulp.src('sass/**/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./css'));
}

実行

sassというタスク名で登録してあるので以下のように実行

gulp sass

css/style.cssが作成されます

/* style.css */
h1 {
  color: red; }
  h1:hover {
    font-size: large; }

自動化

タスクの追加

このままだと毎回手打ちとかめんどくさいのでファイルの監視を入れます
watchに監視対象ファイル、タスク名を渡すだけですね。これは簡単。

// gulpfile.js
gulp.task('default', defaultFunc);

function defaultFunc() {
    gulp.watch(['sass/**/*.scss'],['sass']);
}

実行

defaultタスクに入れたのでそのまま実行

gulp

あとは自動検知して勝手にsassタスクをおこなってくれます。

IntellijIDEAでTypeScriptのコード補完

TypeScriptの設定

Enable TypeScript CompillerをON

f:id:howdy39:20160125212255p:plain

AngularJSのライブラリをダウンロードしてみる

f:id:howdy39:20160126084844p:plain f:id:howdy39:20160126084521p:plain

この状態でコード補完が微妙に効く

f:id:howdy39:20160126122816p:plain

several definitionってのは 複数定義されているから出せない?ってことなのですが、よくわからない。
ちなみにこのtsを自動トランスパイルしたjsの場合は以下のようにちゃんと引数まで出てきます。

f:id:howdy39:20160126123041p:plain

$scopeを解釈していないため$waではじまるものを適当に引っ張っているみたいです。
なので後述する型定義ファイルの追加$scopeの型指定をすればちゃんとコード補完されます。

この状態だとトランスパイル時にエラー

つまりこのライブラリの追加というのはコード補完時の参照であってトランスパイル時の参照ではないということですかね。

Error:(4, 1) TS2304: Cannot find name 'angular'.

f:id:howdy39:20160127082051p:plain

型定義ファイルの追加

これでトランスパイル時に参照してくれるはず!

tsdというツールを使用

github.com

tsd initで初期化

f:id:howdy39:20160126124650p:plain

tsd query angular -rosa installで定義ファイルをDL

f:id:howdy39:20160126124737p:plain

定義を追加

/// <reference path="./typings/tsd.d.ts" />

エラーが消えました!

f:id:howdy39:20160127082411p:plain

コード補完もちゃんと効きます。

f:id:howdy39:20160127084248p:plain

まとめ

  • JavaScriptのライブラリ追加はコード補完用
  • 定義ファイルの追加をすればトランスパイル時のエラーは消える
  • 定義ファイルの追加をすればJavaScriptのライブラリ追加をしなくてもコード補完される模様(同階層のjsだったり定義ファイルの追加でIDEAが自動で解釈してくれるみたい

IDEAは賢すぎて逆にわかりづらい。
TypeScriptはイイ。