React 入門以前 (Windows で環境構築)
犬さんにいろいろ教えてもらった。
@Linda_pp さんて今 TypeScript + React で NyaoVim とか書いてる感じですか?今 ES6 と TypeScript どっちがいいかなぁと思ってるのですが…
— tyru (@_tyru_) June 24, 2016
@_tyru_ はい,型チェックがほしい+豊富な型定義の資産が使いたいので TypeScript で書いてます (NyaoVim は React でなく Polymer ですが).どっちが良いかは一概には言えないと思います.最近だと Flow 使っている人もちらほらいますし.
— 3歳 (@Linda_pp) June 24, 2016
@_tyru_ これから React さわってみるかという感じですか?それなら書き慣れている JS のほうが絶対良いです.TypeScript と JavaScript は差分小さいので後から導入とかもできますし.
— 3歳 (@Linda_pp) June 24, 2016
というわけで
- ES6 (ES2015)
- React
で入門する。
進捗した結果 (リポジトリ)
環境構築メインで中身のコードほぼ書いてないので進捗ダメです。
調べたこと
React
- Reactを使うとなぜjQueryが要らなくなるのか - Qiita
- 今からはじめるReact.js〜React ver0.14〜 - Qiita
- React 触った - 大学生からの Web 開発
- 一人React.js Advent Calendar 2014 - Qiita
旧石器時代のJavaScriptを書いてる各位に告ぐ、現代的なJavaScript超入門
- Section1 ~すぐにでも現代っぽく出来るワンポイントまとめ~ - Qiita
- Section2 ~CommonJSモジュールと仲良くなろう~ - Qiita
- Section3 ~Browserifyをマスターしよう~ - Qiita
- Section4 ~Gulpで処理を自動化しよう~ - Qiita
- Section5 ~ES2015文法を覚えよう(前編)~ - Qiita
npm
npm run-scripts からは gulp のタスクを実行するだけ。
目に付いたメリットは
- Windows でも動く
- タスクが gulpfile.js に集約する
Nodist
複数バージョンの Node の運用には *nix 環境なら n とか nvm とか nave とか nodebrew とか色々あるみたいだけど、 不自由な Windows なので nodist というのを使う。
- Windowsでnode.jsをバージョン管理する - Qiita
- Windowsでのnpm環境の作り方 – Pokosho!
- GitHub - marcelklehr/nodist: Natural node.js and io.js version manager for windows.
ちなみになぜ複数バージョン動かす必要が出たかというと、gulp のタスクを動かした時に以下のエラーが出たため。
(node:61377) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version.
その解決方法が以下の通り。まだ Node v6 をサポートしていないパッケージが沢山あるので古い Node v5 を使えとの有り難いアドバイス。
node v6 is still not supported in many packages. Consider going back to v5.
ちなみに Nodist 調べたので一応ここに書いたけど、結局複数バージョン入れるのもだるかったので、 おとなしく公式サイトから現時点の LTS (v4.4.6) をダウンロードして入れました (既存の v6 はアンインストールした)。
gulpfile.js
Browserifyの運用 〜 bundleを分ける - Qiita
全部をbundleすると太る
なるほど~
最初これにしようかと思ったが、browserify().bundle() すると1つのJSファイルになってしまう。
Gulp+Browserifyでsrc/**/*.jsをdist/**/*.jsにする | 高橋文樹.com
この記事では1つのJSファイルになってしまう問題を解決するgulpの設定が書かれている。
…と思ったけど今実行したら下記の記事のエラーが出る。
TypeError: dest.write is not a function
Browserify + gulpではまったのでメモ - Qiita
結局上記記事に書かれてる through2 というパッケージを使う方法で解決…と思ったらまたエラー。
Error: File.contents can only be a Buffer, a Stream, or null.
該当箇所の変数を console.log()
で出力したりしてみると、そもそも react パッケージとか babelify も入ってなくて Unexpected token 吐かれてた。
(JSX が有効になってない。結論から言うと .babelrc
というものが必要)
$ npm run build > hello-react@1.0.0 build C:\msys64\home\tyru\git\hello-react > gulp build [02:51:46] Using gulpfile C:\msys64\home\tyru\git\hello-react\gulpfile.js [02:51:46] Starting 'build'... [02:51:46] Finished 'build' after 15 ms Error : C:/msys64/home/tyru/git/hello-react/src/app.jsx: Unexpected token (6:6) while parsing file: C:\msys64\home\tyru\git\hello-react\src\app.jsx SyntaxError: C:/msys64/home/tyru/git/hello-react/src/app.jsx: Unexpected token (6:6) 4 | render: function() { 5 | return ( > 6 | <div className="container">Hello {this.props.name}</div> | ^ 7 | ); 8 | } 9 | }) at Parser.pp.raise (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\location.js:22:13) at Parser.pp.unexpected (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\util.js:89:8) at Parser.pp.parseExprAtom (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:522:12) at Parser.pp.parseExprSubscripts (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:277:19) at Parser.pp.parseMaybeUnary (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:257:19) at Parser.pp.parseExprOps (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:188:19) at Parser.pp.parseMaybeConditional (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:165:19) at Parser.pp.parseMaybeAssign (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:128:19) at Parser.pp.parseParenAndDistinguishExpression (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:596:26) at Parser.pp.parseExprAtom (C:\msys64\home\tyru\git\hello-react\node_modules\babelify\node_modules\babel-core\node_modules\babylon\lib\parser\expression.js:481:19)
ちなみにこうしたら上のような詳細なエラーを吐いてくれるようになった。
.on("error", function (err) { console.log("Error : " + err.message); console.log(err.stack); })
Unexpected token while parsing file - kubotti’s memo
によると次のパッケージを入れるといいらしい (勘)。
- babel-preset-es2015
- babel-preset-react
- react
- react-dom
今からはじめるReact.js〜React ver0.14〜 - Qiita
最新だと React の API が変わってるらしい。
0.14でReactDOMがReactから分離されました。 そのため、render()やfindDOMNode()はReactDOMのメソッドを使用しなければなりません。
//React.renderをReactDOM.renderに変更。 ReactDOM.render( <Index />, document.getElementById('content') );
.babelrc
{ "presets": ["es2015", "react"] }
package.json
{ "name": "hello-react", "version": "1.0.0", "description": "", "main": "dist/app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "gulp build" }, "author": "tyru <tyru.exe@gmail.com>", "license": "ISC", "devDependencies": { "babel-preset-es2015": "^6.9.0", "babel-preset-react": "^6.5.0", "babelify": "^7.3.0", "browserify": "^13.0.1", "gulp": "^3.9.1", "react": "^15.1.0", "react-dom": "^15.1.0", "vinyl-source-stream": "^1.1.0" } }
gulpfile.js
これだと結局
全部をbundleすると太る
問題が解決してないのですが力尽きました。 gulp 職人の方誰か助けてください。
var gulp = require('gulp'); var browserify = require('browserify'); var babelify = require('babelify'); var source = require('vinyl-source-stream'); gulp.task('build', function() { browserify('./src/app.jsx', { debug: true }) .transform(babelify) .bundle() .on("error", function (err) { console.log("Error : " + err.message); console.log(err.stack); }) .pipe(source('bundle.js')) .pipe(gulp.dest('./dist')) });
今度は bundle.js を読み込むタイミングが早すぎてエラーが出た。 Angular でもある例のやつ。jQuery だったら $.ready() で処理すべきなやつ。
うっかり <head>
タグに <script>
タグで bundle.js を読み込んでしまったんだけど、その際 React では以下のようなエラーが出る。
Uncaught Invariant Violation: _registerComponent(...): Target container is not a DOM element.
とうとう上記のエラーも解消して、肝心の HTML と JS は以下の通り。
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React</title> </head> <body> <div id='app'></div> </body> <script type="text/javascript" src='dist/bundle.js'></script> </html>
src/app.jsx
const React = require('react'); const ReactDOM = require('react-dom'); const Hello = React.createClass({ render: function() { return ( <div className="container">Hello {this.props.name}</div> ); } }) ReactDOM.render(<Hello name="React" />, document.getElementById("app"));
フロントエンド周りって慣れないと環境構築にほんと時間かかるな…
gulpプラグインの作り方 | js | Horic Design
through2というパッケージは、gulpのstreamまわりをサポートしてくれるプラグインです。
vinyl-source-stream やら through2 やら本来やりたいことと関係ないプラグインがいっぱい出てくるので初心者にはつらい… と思ってたらそこら辺の事情が以下の記事にまとまっていた (ブクマしとるやんけ)。
gulp と browserify と vinyl の話 - <body>
gulp で利用するプラグインをひとつひとつ読み込むと大量の require が並ぶことになる。gulp-load-plugins を利用すると package.json から自動で読み込み利用できるようになり、require する必要がなくなる。
Flowtype
犬さんに教えてもらったのですが力尽きました。
追記:Windows じゃ動きませんでした。つらい。