読者です 読者をやめる 読者になる 読者になる

コンパイラかく語りき

文系新卒プログラマーのメモ

WebStormのターミナルで、rvmのPATHが通っていなかった

すみません、ひょっとしたらWebStorm関係ないかもしれません。少なくとも、自分のWebStorm環境で発生したので便宜的に「WebStormのターミナルで、rvmのPATHが通っていなかった」となりました。

発端

いつものようにrails開発を始めようとしたところ、

$ rails s

以下のメッセージが。

Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.

おや? railsがインストールされていないとのこと。

ちなみに、WebStormの内蔵ターミナルでの出来事でした。 そんなことあるかと思い、色々調べてみたら、WebStormのターミナルだからじゃないかと。

試しに、iTerm2で同じことを。

$ rails s

安心のWEBrick起動。

=> Booting WEBrick
=> Rails 4.2.6 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server

PATHが通ってなかった

ためしに、PATHが正しいか調べる。

$ echo ${#PATH}

正常なiTermでは、結果は290。WebStormのターミナルでは、167でした。パスが足りてない…?

WebStormの方では、以下のPATHが通っていませんでした。

/Users/chuck/.rvm/gems/ruby-2.3.0/bin:
/Users/chuck/.rvm/gems/ruby-2.3.0@global/bin:
/Users/chuck/.rvm/rubies/ruby-2.3.0/bin:

たしかに、これではrailsが無さそう。

rvm系のPATHが通す

どうやら、↓の1文がrvm系のPATHを通しているっぽい。

$ source "$HOME/.rvm/scripts/rvm"

参考:RVM 経由で Ruby を入れるときにハマったこと

先の1文を zshrc に追加することで、解決。(bashをお使いの方はbashrc に。) WebStormのターミナルを再起動すると、$ rails s が成功しました。

そもそも、なぜこんなことが起こってしまったのか、次回調べてみたいと思います。

nodebrew install でsyntax errorが出たら、nodebrew install-binaryを試す

Node.js

nodebrew install したら、syntax errorが出てインストールに失敗した。

 

hasen.hatenablog.com

 

Pythonのバージョンが違うのかなと思って調べてみたら、確かに3系を使っていた。

ところがpyenvで2系に戻してみても、install時にsyntax error。結果は変わらず。

 

調べてみたところ、nodebrewのissueがヒット。

 

github.com

 

nodebrew intall-binary

 

でインストールできました。

 

We recommend you to use install-binary command to install.

そもそもREADMEに↑のように、書いてありますね。

 

ちなみに、install-binary コマンドなら、python3系のままでもNodeがインストールできました。

Qiitaの"俺たちはJavaScriptの非同期処理とどう付き合っていけば良いのだろうか"をやってみる

JavaScript

非同期周りにまだ慣れてない感じがあったので、素振りです。

 

こちらの記事をただただ写経しました。

qiita.com

 

書いたコードはこちらに。

github.com

 

Promiseにまだまだ慣れていないなと感じたので、改めて噛み砕いてQiitaに投稿しました。

qiita.com

【JSer向け】ローカルで生のRethinkDBを触る

RethinkDB

RethinkDBについて。

 

続きを読む

webpackはどのように動いているのか(3)

WebPack

webpackの仕組みについて、見ていきます。

前回↓ 

chuckwebtips.hatenablog.com

 

前回は、webpackがexportやmodule.exportsをどのように変換するかについて見てみました。

今回は、モジュールのimportやrequireがどのように処理されるかを見てみます。

 

まず、このようなファイルを作りました。(./modules/greet.js)

gist.github.com

 

ES6 import

これをindex.jsからimportして一部を実行してみます。

 

gist.github.com

 

すると、変換ファイルがこのとおり。

gist.github.com

 

モジュール定義が2つになりました!

2つ目のモジュールについては、前回見たとおりですね。1つ目のモジュールについて詳しく見ていきます。

 

gist.github.com

 

まず、関数の引数が増えていますね。第三引数として__webpack_require__が渡されています。どうやらimportを行うモジュールには、これが渡されるようですね。

 

そして、さっそく__webpack_require__(1)という記述が。

これはgreet.jsモジュールをロードしてますね。ロードした結果、module.exportsが返るので、_greet変数にはgreet.jsで定義したモジュールへの全参照が含まれます。

 

gist.github.com

 

その次はこんな感じ。

 

gist.github.com

 

_interopRequireDefaultという関数が使われていますね。引数にオブジェクトを取り、オブジェクトを返します。

オブジェクトが存在しており、__esModuleキーがtrueかどうかで、オブジェクトそのものを返すか、{ default: obj }を返すかを判定していますね。なるほど。

 

最後にimportしたモジュールの実行を行います。

 

gist.github.com

 

むむ、、見慣れない記法ですね。

_greet2.default()じゃあダメなんですかね…?謎です。変換前のJavaScriptが複雑化してきたら意味を持つんですかね。ひとまず今はスルーします。

 

CommonJS require

次はrequireを使った場合について見てみます。

 

まず、greet.jsをCommonJS式に書き換えます。

 

gist.github.com

 

次にindex.jsでの読み込みをrequireに変更。

 

gist.github.com

 

このように変換されます。

 

gist.github.com

 

なるほど!わかりやすいですね。

__webpack_require__が2度呼ばれていますね。ここでモジュールキャッシュが効いてくるんですね。(第一回を参照)

 

 

ES6 import * as hoge

再びES6式に戻って、import * as ~ 形式を試してみます。

greet.jsをES6のexportに書き戻しておきます。

 

gist.github.com

 

import側はこんな感じ。

 

gist.github.com

 

変換後のbundle.jsのうち、index.jsの部分はこんな感じ。

 

gist.github.com

 

むむ。

export defaultの時は、_interopRequireDefaultが呼ばれましたが、今回は、_interopRequireWildcardが呼ばれていますね。

 

ここはBabelの機能のようですね。importの種類によって、異なる関数を生成します。

export hoge & import hoge from 'hoge' -> __webpack_require__のみ

 

export default hoge & import hoge from 'hoge' -> __webpack_require__ + _interopRequireDefault

 

import * as hoge from 'hoge' -> __webpack_require__ + _interopRequireWildcard

 

ざっくりと。

 

_interopRequireWildcard関数を抜き出してみました。

 

gist.github.com

 

まずは、受け取ったオブジェクトのesModuleプロパティがtrueかどうか判定していますね。

 trueではない場合には、オブジェクトをそのままreturnせずに新しいオブジェクトを生成してreturnしています。

 

 

というわけで、今回はimport / requireがどのように変換されるのか挙動について見てみました。これで、webpackがimportとexportをどのように扱うかを知ることができました。

 

次回は、複数バンドルについて見ていきます。

webpackはどのように動いているのか(2)

WebPack

引き続き、webpackの仕組みについて見ていきます。

 

chuckwebtips.hatenablog.com

 

前回書いたコードはこちらでした。

 

gist.github.com

 

本当に単純な定数定義ですね。

実際の開発では、JavaScriptはモジュール単位で書くのが基本だと思います。なので、まずはモジュール化を行います。

 

ES6 export

 

gist.github.com

 

まずは、CommonJS形式ではなくES6のexport を使います。また、実行されたかどうかがわかりやすいように、処理分にconsole.logを書きました。

変換後のbundle.jsがこちら。

 

gist.github.com

 

前半部分は前回解説したものと変わっていなさそうです。

後半のモジュール部分が変わりましたね。

 

gist.github.com

 

Object.definePropertyを使用している部分と、関数定義部分に分けることができそうです。

 

まずはObject.defineProperty部分について。

 

gist.github.com

 

exportsオブジェクトに対して、__esModule__ というキー名で、true値をセットしています。

definePropertyを使うことによって、暗示的にプロパティの属性をfalseにすることができます。

プロパティの属性については、以下の記事がとてもわかりやすかったです。

十一章第四回 Objectとプロパティ — JavaScript初級者から中級者になろう — uhyohyo.net

 

つまり、exportsに__esModule__プロパティを追加したけど、それは上書き不可能だし、列挙されないし、そういった設定を変更することは不可能、ということです。

なので、console.log(exports)で表示しても、__esModule__プロパティは見えません。

 

次に、関数定義部分について。

gist.github.com

 

var helloとfunction(){...} の間にexports.helloが挟まりましたね。

exportsのプロパティとしてhello関数を定義しているんですね。

 

exportsプロパティはmoduleオブジェクトに含まれており、moduleオブジェクトはinstalledModulesというオブジェクトに含まれているので、すべてのexportはinstalledModulesから辿れることになりますね。

 

 

CommonJS export

では、これをexportではなくCommonJS形式のmodule.exportsに変えてみます。

 

gist.github.com

 

変換後のモジュール定義部分がこちら。

 

gist.github.com

 

なるほど!w

引数で受け取っているmoduleのexportsプロパティに追加を行っていますね。ただし、module.exportsはもう1つの引数であるexportsと同じものです。

そして、CommonJS式の場合は特に__esModule__: trueのような目印はつけないんですね。

 

複数モジュールの定義

なんとなく予想はつきますが、複数のモジュールを定義した場合も見てみます。

gist.github.com

 

変換後はこんな感じ。

gist.github.com

 

exportsプロパティとして複数定義される感じですね。

 

export default 

では、ES6式のexport defaultによるモジュール化はどうなるでしょう。

 

一番最後にdefault exportを追記しました。

 

gist.github.com

 

変換後はこのとおり。

 

gist.github.com

 

なるほどw

exports.defaultのプロパティとして追加されました。import時にどのように処理されるのか、楽しみです。

 

 

 

以上、JavaScriptコードのモジュール化をwebpackがどのように処理するか見てみました。

次回は定義したモジュールを外部からimport/requireしてみます。