react.jsを0.13.3から0.14.0にあげてみた

react.jsの0.14.0がでたので、0.13.3から上げてみました

変更内容はこちら
npm install –save react react-dom

手順にしたがって上げてみます

react.js + gulp + browserify + browserify-shim、コードはjsx
の構成で使ってました

node_modulesをいったん消して入れなおしました

$ rm -rf node_modules

package.jsonからreactのライブラリ、react-datepickerを消しておきました
で入れる

$ npm install -D react-datepicker

他のもいれる

$ npm install

reactはbrowserify-shimをつかって、cdnから読み込むようにしてたので

  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>

とバージョン変えたのと、react-domも追加

あとは既存のコードの変換ですがfacebookからツールがでてます
react-codemod/README.md at master · reactjs/react-codemod

ここの手順通り

$ npm install -g jscodeshift

好きな場所へ git clone
今回はホームディレクトリに入れていみました

$ cd ~
$ git clone https://github.com/facebook/react.git

で、コードを置換していきます
jsx使ってたので

$ jscodeshift -t ~/react/packages/react-codemod/transforms/class.js *.jsx
$ jscodeshift -t ~/react/packages/react-codemod/transforms/findDOMNode.js *.jsx
$ jscodeshift -t ~/react/packages/react-codemod/transforms/pure-render-mixin.js *.jsx
$ jscodeshift -t ~/react/packages/react-codemod/transforms/react-to-react-dom.js *.jsx

変更される内容は
npm install –save react react-dom
で確認

$ git diff

とかで差分をチェックしといて変化を覚えておく(今後のため)
動作確認してOKでした

react.js + browserifyの出力ファイルを小さくしてみた

react.js + browserifyを使っていて一つのjsファイルが巨大化したので小さくするため
ライブラリ郡を外に出してみました

package.jsonを見ると

{
  "devDependencies": {
    "jquery": "^2.1.4",
    "react": "^0.13.3",
    "react-datepicker": "^0.12.0",
    "babelify": "^6.3.0",
    "browserify": "^11.1.0",
    "gulp": "^3.9.0",
    "vinyl-source-stream": "^1.1.0"
  }
}

な感じのものをつかっていて gulpfile.js がこんな感じ

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');

var option = { debug: false };
gulp.task('debug', function() {
  option = { debug: true };
});

gulp.task('watch', function() {
  gulp.watch('./*.jsx', ['debug', 'browserify'])
});

gulp.task('browserify', function() {
  browserify('./index.jsx', option)
    .transform(babelify)
    .bundle()
    .on("error", function (err) { console.log("Error : " + err.message); })
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./'))
});

gulp.task('build', ['browserify']);
gulp.task('default', ['debug', 'browserify', 'watch']);

この gulp build で bundle.js が出力されますが、 1.6 MB で大きかったので
react.jsとjqueryを bundle.js にまとめず直リンクするようにしました

直リンクは

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

とかCDNから読み込むようにして
thlorenz/browserify-shim
を使って、動作するようにします

$ npm install -D browserify-shim

$ vim package.json

{
  "devDependencies": {
    "babelify": "^6.3.0",
    "browserify": "^11.1.0",
    "browserify-shim": "^3.8.10",
    "gulp": "^3.9.0",
    "jquery": "^2.1.4",
    "react": "^0.13.3",
    "react-datepicker": "^0.12.0",
    "vinyl-source-stream": "^1.1.0"
  },
  "browserify-shim": {
    "react": "global:React",
    "jquery": "global:$"
  }
}

と記載してあげて

$ vim gulpfile

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');

var option = { debug: false };
gulp.task('debug', function() {
  option = { debug: true };
});

gulp.task('watch', function() {
  gulp.watch('./*.jsx', ['debug', 'browserify'])
});

gulp.task('browserify', function() {
  browserify('./index.jsx', option)
    .transform(babelify)
    .transform('browserify-shim', { global: true })
    .bundle()
    .on("error", function (err) { console.log("Error : " + err.message); })
    .pipe(source('bundle.js'))
    .pipe(gulp.dest('./'))
});

gulp.task('build', ['browserify']);
gulp.task('default', ['debug', 'browserify', 'watch']);

で transform(‘browserify-shim’, { global: true }) で、package.jsonで指定したライブラリを
bundle.jsでも使えるようになりました

これで

$ gulp build

で 1.6MB -> 0.38MB になりました

React.jsのテストをJestでやってみる

Jest | Painless JavaScript Unit Testing
のチュートリアルをやってみました

書かれてる通りjsファイルを用意してpackage.jsonも用意

$ npm install

でインストールした後

$ npm test

/home/user/react-sample/node_modules/jest-cli/src/TestRunner.js:433
        const cacheA = testPerformanceCache && testPerformanceCache[a[0]];
        ^^^^^
SyntaxError: Use of const in strict mode.
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/home/user/react-sample/node_modules/jest-cli/src/jest.js:13:18)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
npm ERR! Test failed.  See above for more details.

といった感じでエラーが..
調べて見るとnode.jsのバージョンが古いようで

$ node -v
v0.11.13

でした

nvmでインストールしていたので

$ nvm install v0.12.7

としましたが同じエラー

$ nvm install v4.1.2

とするとうまくいきました

$ npm test

Using Jest CLI v0.5.9
 PASS  __tests__/CheckboxWithLabel-test.js (0.597s)
1 test passed (1 total)
Run time: 0.894s

reactjsでUncaught Error: Invariant Violation: processUpdates();エラー

ReactjsでTodoリストのようなものを作って削除処理でsetStateするとエラーが発生

Uncaught Error: Invariant Violation: processUpdates(): Unable to find child 8 of element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID `.0.3.0.1`

エラー通り、tableタグにtheadとtbodyをつけてなかったのが原因でした

var jobBox = React.createClass({
  onJobDelete(id) {
    this.props.onJobDelete(id);
  },
  render() {
    var jobLines = this.props.jobs.map((job, i) => {
      return <JobLine key={i} onDelete={this.onJobDelete} job={job} />;
    });

    return (
      <div>
        <table>
        <thead>
          <tr>
            <th>注文No.</th>
            <th>部品名</th>
          </tr>
        </thead>
        <tbody>
          {jobLines}
        </tbody>
        </table>
      </div>
    );
  }
});

一部ですがこんな感じです
theadとtbodyがないとDOM操作ができないようでした