pirosikick's diary

君のハートにunshift

jsdoc.vimでデフォルトじゃないキーにマップする

heavenshell/vim-jsdoc · GitHub

デフォルトだと<C-L>(Ctrl + l)にマップされているが、そのキーを既に<C-w><C-l>するのに使っていた。GithubのREADME.mdには書いてなかったから調べた。書いてたw

NeoBundle "heavenshell/vim-jsdoc"

~ 略 ~
" <C-P>にマップ
nmap <silent> <C-P> <Plug>(jsdoc)

ftplugin/javascript/jsdoc.vimにこんな感じで定義されている

if !exists('g:jsdoc_default_mapping')
  let g:jsdoc_default_mapping = 1
endif
nnoremap <silent> <buffer> <Plug>(jsdoc) :call jsdoc#insert()<CR>
if !hasmapto('<Plug>(jsdoc)') && g:jsdoc_default_mapping
  nmap <silent> <C-l> <Plug>(jsdoc)
endif

<Plug>ってのを初めて見たんだけど、ここに解説書いてる。 <Plug>は特殊なコードで絶対キーボードから入力できないようになっていて、とりあえず<Plug>ほげほげにマップしておき、ユーザがそこに対して任意のキーをmapできるようにしてる。(たぶん)

g:jsdoc_default_mapping使って下記のようにも書けると思う(この方法がREADME.mdに書いてる)

let g:jsdoc_default_mapping = 0
nnoremap <silent> <C-P> :JsDoc<CR>

Angular2.0のDI

Angular2.0について、Angular.jsのブログに出ていた。 ここ半年間くらいAngular.jsを使って不便に思っていたところが結構改善されるようで非常に嬉しい。

びっくりしたのが、ドキュメントがしっかりしてて、Angular2.0がどういうデザインになるかちゃんとまとまってること。 で、DIのデザインついてのドキュメントを読んでみたのでメモ。

要点抜き出してみた

configフェーズがなくなる

  • 混乱のもとだった。シンプルにする
  • 具体的にはmodule.config()module.constant()module.provider()が廃止
    • constant→value、provider→factory

Remove the global module registry

  • 今まで依存関係を定義するのに2ステップ必要だった
    1. 依存関係をモジュール名で定義する(angular.module('hoge', ['a', 'b']))
    2. 依存関係のモジュールのファイルを先にロードしておく
  • どっちかを忘れるってことが容易に想像がつく
  • angular.moduleが常に新しいインスタンスを返すようになる
  • angular.bootstrap(document.body, [moduleA, moduleB])使って手動でbootstrap、<body ng-app>はできなくなるっぽい

Hierarchical Injectors

  • SingletonじゃなくてもOKにする、遅延ロード
  • 今までは全てがSingletonで、bootstrapが実行される前に全てのコードがロードされる
  • (もともとのinjectorの動きがよくわからんから、あんまり理解できなかった。。。)

Private module

  • node-diに実装予定だが、そんなに重要な機能と思ってないから必要になるまで後回しにしてるらしい
    • 現在ある、モジュール間のトークン名(service, factory, valueの名前)の衝突を回避できない問題と、別のモジュールから自由にvalueやserviceにアクセスできてしまう問題のソリューション

Property Injection

  • こういうのができるようになるらしい
module.value('config', {
  hoge: {
    fuga: {
      'fuga'
    }
  }
});

// 今までだと'config'でinjectするところを、
// ドットで'config.hoge.fuga'と局所的に取得可能
module.factory('something', ['config.hoge.fuga', function (fuga) {

}]);

ES6 Modules Integration

Asynchronous Injection

Annotations

まとめ

  • Traceur compilerとかnode-diとかdi.jsとか使ってみよ
  • 全てがAngular.jsに乗ってないといけない状態はかなり改善されそう。
  • ブラックボックス感が強くて理解できなかったところが、シンプルになることで理解しやすくなりそう。
  • 取っ付き易くなりそう

Vue.jsに乗り換えようとしてたけど、あー早く使いたいー。

気持ちの整理メモ

※殴り書きのメモなので読んでも面白くは無いはず!

 

最近「どうなりたいか」とか「何がしたいのか」とか聞かれすぎて、自分でもよくわからなくなっていて、このままでいいんだっけ?とよく悩む。
毎回聞かれて毎回違うこと言ってる気がするので、気持ちを整理するためにとりあえず深く考えず箇条書きにしてみる
 

JavaScriptが好きか

  • JavaScriptは好きだけど、絶対これじゃないとダメということはない
  • なので「俺はJavaScript書けない仕事はしたくない!」ということはない
  • むしろそういうことを言うエンジニアはあんまり尊敬できない
  • JavaScriptを使う機会が多かったから、好きって言うよりは得意なのかな
  • PHPは糞だと思うけど、別に嫌いじゃない
  • ただ、PHPのバージョンが古いとかそういうのに縛られて新しいことができないのは嫌い
  • 今までの業務はそういう縛りが多く、新しいことに挑戦できないのが辛い時があった
  • あと、なんか新しいプロジェクト始めるときはPHP以外の言語使いたいし、好きな言語選んでいいよっていう場合には絶対PHPは選ばない
  • ということで、「仕事でJavaScriptを使う」ということにそこまで執着はない
  • が、JavaScriptが言語の中で一番得意だし、JS周りは最近動きが早く、今頑張れば自分の強みになりそうな気がする
  • なので、機会があるのならばもう少しJavaScriptで仕事したい、というのが結論な気がする。

 

コミュニケーション

  • 企画したりプレゼンしたりってことが嫌いなのではなく、「資料作り」とかその資料を作るためにチームでコンセンサスを取るためのコミュニケーションっていうのが嫌いなのだと思う
  • 正確にいうと苦手でうまくいかないからストレスたまるし、出来る限り避けたいと思ってる
  • だから、我慢して苦手を克服したら好きになるのかな
  • メール書くのも嫌いだったけど、前ほどストレスは感じなくなった(時間はかかるけど。。)
  • というかコミュニケーション全般に苦手意識がある気がする。。
  • たぶん「資料作り」も「メール」も文字によるコミュニケーションで、しかも口頭よりも時間もかかるし、仕事だと敬語とか気にしないといけないし、まぁそんな感じの理由で苦手

その他

  • 3Dプリンタとかarduinoとか、つくろうと思えば何でも作れる時代で、エンジニアになって本当によかったなと思う
  • 「なんでも作れるようになりたい」と子供の頃によく思っていて、エンジニアになったのは「とりあえずこれなら食っていけそう」っていう理由だけど、意図せず子供の頃の夢が叶って本当によかった。笑
 
本当にまとまりのない感じになってしまった。。
こういう今考えていることをつらつらと書いていく作業を蛇口をひねる如く簡単にできるといいのに。文章を書くということにもっと慣れないといけないですね。 
 
 
 
 
 
 

Angular.jsとTypeScript

Angular.jsでaltJSを使う場合、CoffeeScriptが一般的(たぶん)だが、TypeScriptはあんまり聞かない。TypeScriptの方が好きな自分としてはどうにかならんかねとずっと考えていて、こうやったらいいんじゃないかというのを思いついたのでメモ。

controller定義の基本

Angular.jsでcontrollerを定義する場合、だいたいはangular.module.controllerの第1引数にcontroller名、第2引数にcontrollerのコンストラクタ関数を渡す。

var app = angular.module('app', []);

// 'MainCtrl'という名前のcontrollerを定義
app.controller('MainCtrl', function ($scope) {

});

このままだとminiyした時にinjectがうまくいかないので、第2引数に配列を渡して明示的にinjectを定義するか、コンストラクタ関数に$injectを定義する方法がある。

// 第2引数に配列を渡すケース
app.controller('MainCtrl', ['$scope', function ($scope) {
  // do something
}]);
// $injectを定義するケース

function MainCtrl ($scope) {
  // do something
}

MainCtrl.$inject = ['$scope'];

app.controller('MainCtrl', MainCtrl);

たぶんあんまり知られていないcontrollerの定義方法

ドキュメントには多分載ってないと思うのですが、angular.module.controllerにハッシュオブジェクトを渡すことができて、keyにcontroller名、valueにcontrollerのコンストラクタ関数という感じで一気に複数のcontrollerを定義できる

// MainCtrlとSubCtrlを一気に定義する
app.controller({
  MainCtrl: function ($scope) { /* do something */ },
  SubCtrl: function ($scope) { /* do something */ }
})

これを活かして、app.controllersみたいな感じでNamespaceを作ってそこにcontrollerを定義して、Namescpaceごとangular.module.controllerに渡してしまうのが楽なのではないかと思うのです。

TypeScriptの場合、moduleを使えば簡単にNamespaceが定義できる。

// controllers.ts
// 今回は1つのファイルに2つのcontrollerを定義
// 実際は分けてもいいかと思います。

module app.controllers {

  // MainCtrl
  export class MainCtrl {
    // injectionを明示的に定義
    static $inject = ['$scope'];

    constructor ($scope) {
      // do something
    };
  }

  // SubCtrl
  export class SubCtrl {
    // injectionを明示的に定義
    static $inject = ['$scope'];

    constructor ($scope) {
      // do something
    };
  }
}
// app.js

angular.module('app', [])
  // controllerを一気に定義
  .controller(app.controllers);

controllerだけでなくdirectiveservice等もハッシュオブジェクトを渡して定義できるので、応用できるはず。

grunt-useminでライセンス表記を残す

クライアントサイドJavaScriptのライセンス管理 | GREE Engineers' Blog

これを見てgrunt-useminで難読化されたコードを見たらやっぱりライセンス表記まで削除されていた。。orz

で、grunt-license-saverを使おうかなと思ったんだけど、ソース内に@license http://hogehoge.com/license.jsonって追加するのどうしようと思っていたら、下記記事を発見。

grunt.js - UglifyJSで、できるだけライセンスコメントを残して圧縮する - Qiita

uglifyjsならば自分で関数を書いてどのコメントを残すのかの制御が可能とのこと。しかも、grunt-license-saverと同等のものが既にこの記事に書いてある!ありがたい!!

で、grunt-useminはデフォルトだと(たぶん他の使うとかはできないと思うけど)grunt-contrib-uglifyを使って難読化しているので、preserveCommentsオプションがuglifyjsのcommentsオプションと同等のものになる。

// Gruntfile.js

// ここはそのまま上記記事から持ってくる
// see http://qiita.com/shinnn/items/57327006390f2181f550
var licenseRegexp = /^\!|^@preserve|^@cc_on|\bMIT\b|\bMPL\b|\bGPL\b|\(c\)|License|Copyright|three\.js/mi;

var isLicenseComment = (function() {
  var _prevCommentLine = 0;

  return function(node, comment) {
    if (licenseRegexp.test(comment.value) ||
        comment.line === 1 ||
        comment.line === _prevCommentLine + 1) {
      _prevCommentLine = comment.line;
      return true;
    }

    _prevCommentLine = 0;
    return false;
  };
})();

module.exports = function (grunt) {
    // show elapsed time at the end
    require('time-grunt')(grunt);
    // load all grunt tasks
    require('load-grunt-tasks')(grunt);

    grunt.initConfig({

// 略

        // preserveCommentsに上で定義した関数を渡す
        uglify: {
          options: {
            preserveComments: isLicenseComment
          }
        },

// 略

    });
};

新たに発覚した問題

three.jsを使っているのだがソース内にライセンス表記がない。正確に言うと// three.js - http://github.com/mrdoob/three.jsと書いているのだが、上記の正規表現three.jsと書いてもコメントが残らず困っている。。 誰か解決方法を知っていたら教えて下さい。

grunt-useminって便利だな−

https://github.com/yeoman/grunt-usemin

grunt-useminはgruntのtaskで、

<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->

↑のようなコメントをHTML内に見つけると、勝手にconcatとuglifyしてapp.jsを生成し、HTMLを書き換えて出力してくれる。

cssも同様にコメントでconcatとcssminが可能で、sass等を使っている場合でも出力先を指定しておけば勝手にやってくれる

<!-- .tmp以下にコンパイルしたcssを出力している場合 -->
<!-- build:css(.tmp) /styles/main.css -->
<link rel="stylesheet" href="/styles/gumby.css">
<link rel="stylesheet" href="/styles/main.css">
<!-- endbuild -->

自分はyeoman大好きでgrunt-useminしか使ったこと無いのだけれど、それ以外の人って何を使っているんだろうか? これを使うと開発時のビルド手順がかなり減ってとても楽だし、その上、scriptタグを出し分けるために開発用と本番用でHTMLを分けることをしなくていい。

yeomanを使わない人でもgenerator-webappが吐くGruntfile.jsやビルド手順、ディレクトリ構成など、とても参考になるのでぜひ見てみましょうー