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

22時に寝ようと思って2時に寝る。

備忘録や日記を書いてます。きょうは早く寝よう。

CentOS6.8 - MySQL5.1 から MySQL5.6へバージョンアップする

環境

  • CentOS release 6.8 (Final) 64bit

今回はRails5.0のアプリ開発の際に、絵文字(utf8mb4)に対応するためにMySQL5.1からMySQL5.6へのバージョンアップの必要がありました。

既存MySQL5.1を削除する

現在インストールされているMySQLを確認する

# rpm -qa|grep mysql
mysql-libs-5.1.73-8.el6_8.x86_64
mysql-server-5.1.73-8.el6_8.x86_64
mysql-5.1.73-8.el6_8.x86_64
mysql-devel-5.1.73-8.el6_8.x86_64

これらを削除する(今回は開発環境のためバックアップは取っていませんが、必要に応じて削除前に行うようにしてください)

# yum erase mysql-libs-5.1.73-8.el6_8.x86_64 mysql-server-5.1.73-8.el6_8.x86_64  mysql-5.1.73-8.el6_8.x86_64 ysql-devel-5.1.73-8.el6_8.x86_64
...
Removed:
  mysql.x86_64 0:5.1.73-8.el6_8                                  mysql-libs.x86_64 0:5.1.73-8.el6_8                                  mysql-server.x86_64 0:5.1.73-8.el6_8

Dependency Removed:
  MySQL-python.x86_64 0:1.2.3-0.3.c1.1.el6     cronie.x86_64 0:1.4.4-15.el6_7.1     cronie-anacron.x86_64 0:1.4.4-15.el6_7.1     crontabs.noarch 0:1.10-33.el6     mysql-devel.x86_64 0:5.1.73-8.el6_8
  perl-DBD-MySQL.x86_64 0:4.013-3.el6          postfix.x86_64 2:2.6.6-6.el6_7.1

Complete!

ログを見てみるとDependency Removed(依存関係にあったものも削除)されたことがわかりますが、必要に応じて再インストール後に導入してあげてください。

MySQL5.6を導入する

MySQL :: Download MySQL Yum Repository

今回は、MySQL公式のyumリポジトリを導入します。

# yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm

正常にリポジトリが導入できたら、さっそくインストールします。

# yum -y install mysql-community-server
# mysqld --version
mysqld  Ver 5.6.36 for Linux on x86_64 (MySQL Community Server (GPL))

導入できました。自動起動設定をして、起動してみます。

# chkconfig mysqld on
# service mysqld start
Starting mysqld:                                           [  OK  ]

MySQLに入ってみます。

# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye

いけました!

余談

Column count of mysql.user is wrong. Expected 43, found 39.

対話形式で初期設定できるmysql_secure_installationを実行するとエラーが起きました。

#  mysql_secure_installation
...

Set root password? [Y/n] Y
New password:
Re-enter new password:
ERROR 1558 (HY000) at line 1: Column count of mysql.user is wrong. Expected 43, found 39. Created with MySQL 50173, now running 50636. Please use mysql_upgrade to fix this error.
root password update failed!
Cleaning up...

これに対しては、MySQLのバージョンアップの際に既存テーブルの互換性をチェックして、必要に応じて「いい感じにやってくれる」らしいmysql_upgradeを実行したら、解決しました。

# mysql_upgrade -p
Enter password:
Looking for 'mysql' as: mysql
Looking for 'mysqlcheck' as: mysqlcheck
Error: Failed while fetching Server version! Could be due to unauthorized access.
FATAL ERROR: Upgrade failed
[root@localhost ~]# mysql_upgrade -p
...
OK
#  mysql_secure_installation
...

All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

Cleaning up...
# 

Railsでのバージョンアップに関わっての対応

そのままではマイグレーションが通りませんでした。

# rake db:migrate
rake aborted!
LoadError: libmysqlclient_r.so.16: cannot open shared object file: No such file or directory - /usr/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/extensions/x86_64-linux/2.2.0-static/mysql2-0.4.5/mysql2/mysql2.so
/vagrant/paters_rails/config/application.rb:7:in `<top (required)>'
/vagrant/paters_rails/rakefile:4:in `require_relative'
/vagrant/paters_rails/rakefile:4:in `<top (required)>'
(See full trace by running task with --trace)

これは、gemのmysql2を再インストールすることで、いい感じに設定し直してくれます…が、その前に必要なモジュールであるmysql-develがインストールされてないエラーが出ました。

# gem uninstall mysql2
Successfully uninstalled mysql2-0.4.5
[root@localhost paters_rails]# gem install mysql2
Fetching: mysql2-0.4.5.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
    ERROR: Failed to build gem native extension.

    /usr/local/rbenv/versions/2.2.3/bin/ruby -r ./siteconf20170417-21958-1ruy28h.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for ruby/thread.h... yes
checking for rb_thread_call_without_gvl() in ruby/thread.h... yes
checking for rb_thread_blocking_region()... no
checking for rb_wait_for_single_fd()... yes
checking for rb_hash_dup()... yes
checking for rb_intern3()... yes
checking for rb_big_cmp()... yes
checking for mysql_query() in -lmysqlclient... no
-----
mysql client is missing. You may need to 'apt-get install libmysqlclient-dev' or 'yum install mysql-devel', and try again.
-----
*** extconf.rb failed ***

extconf failed, exit code 1

Gem files will remain installed in /usr/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/mysql2-0.4.5 for inspection.
Results logged to /usr/local/rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/extensions/x86_64-linux/2.2.0-static/mysql2-0.4.5/gem_make.out

yumでインストールしてあげます。

# yum install mysql-devel
...
Installed:
  mysql-community-devel.x86_64 0:5.6.36-2.el6

Complete!

再度、gemをmysql2をインストール

# gem install mysql2
Done installing documentation for mysql2 after 1 seconds
1 gem installed

いけました。以上です。

参考

RSpec - テストでは画像アップローダを無効にする

Cloudinary::CarrierWave::UploadError

現在開発しているRailsアプリでは、Userのプロフィール画像をCarrierWaveを用いて、Cloudinaryに画像をアップロードする方法で実装しています。 このUserモデルに関わるテストを行うときはFactoryGirlを用いてテストデータを用意しています。

FactoryGirl.define do
  factory :user do
    sequence(:email) { |i| "#{i}_#{Time.current.to_i}_#{Faker::Internet.email}" }
    name Faker::Name.name
    profile Faker::Lorem.sentence
    password "userpassword"
    user_image { fixture_file_upload Rails.root.join('spec/fixtures/files/sample_500x500.png'), 'image/png' }
  end
end

この状態で、テストを実行すると、以下の結果になります。(一部抜粋)

Failures:

  1) Articles GET /api/v1/articles 記事一覧を取得する パラメータを指定しない
     Failure/Error: let!(:articles) { create_list(:article, 3) }

     Cloudinary::CarrierWave::UploadError:
       cloud_name is disabled
     # ./spec/requests/articles_spec.rb:6:in `block (4 levels) in <top (required)>'

Finished in 3.73 seconds (files took 11.97 seconds to load)

今回、テストで画像に対して複雑なテストをするわけでもないため、Cloudinaryの画像をアップロードするロジックは噛ませる必要がありません。 そのため以下の解決方法をとりました。

config.enable_processing = false if Rails.env.test?

config/initializers/carrier_wave.rbを作成し、以下を記述します。

CarrierWave.configure do |config|
  config.enable_processing = false if Rails.env.test?
end

こうすることで、テスト環境に限りアップロード処理をスキップすることができ、テストも無事、通るようになります。

.

Finished in 2.7 seconds (files took 7.97 seconds to load)
1 examples, 0 failures

以上です。

参考

stackoverflow.com

Wercker - 「Choose a repository」で目的のリポジトリが見つからない

Werckerで「Choose a repository」フォームで所属しているOrganizationのPrivate Repositoryが見つからない

WerckerでCI環境を構築しようと試みたところ、Create Applicationフォームでつまづきました。 最初の画像の通り、はじめに「Choose a repository」というフォームがあるのですが、ここで自分が所属するOrganizationのプライベートリポジトリが表示されず、選択できませんでした。

解決方法:WerckerをGitHub上でConfigureして,該当リポジトリをGrant accessする

ルー語っぽくなって非常にわかりづらいですが、順を追って説明します。

1. 以下のページにアクセスし,Configureリンクをクリック

Install Wercker · Integrations Directory · GitHub

2. Organization accessの中からWerckerからのアクセスを許可したいOrganizationをGrant accessする

f:id:azuuun:20170318225042p:plain

上の画像のように,自分がそのOrganizationの権限を得ている場合はWerckerからのアクセス要求を「Grant access」することが可能です。 できない場合は、管理者アカウントから設定する必要があります。

3. 再度,WerckerのCreate Applicationフォームでリポジトリを検索すると,無事先ほど「Grant access」したリポジトリが選択可能になっています。

f:id:azuuun:20170318225525p:plain

先ほど,yurueというOrganizationのWerckerへのアクセス許可を行いました。すると画像の通り、Werckerからyurueのリポジトリにアクセスが可能となり,検索に引っかかってくるようになりました。

以上です。

参考

Organization-approved applications

MySQL5.5系がservice mysqld startで起動しない

症状

こちらの記事を参考に、無事MySQL5.5系をインストールすることが出来ました。

blog.ybbo.net

しかし、いざ起動させようとすると、FAILDとなります。

[root@localhost mysql]#  service mysqld start
MySQL Daemon failed to start.
Starting mysqld:                                           [FAILED]

エラーログを見てみます。

[root@localhost mysql]# cat /var/log/mysqld.log
170302  4:23:25 [Note] Plugin 'FEDERATED' is disabled.
170302  4:23:25 InnoDB: The InnoDB memory heap is disabled
170302  4:23:25 InnoDB: Mutexes and rw_locks use GCC atomic builtins
170302  4:23:25 InnoDB: Compressed tables use zlib 1.2.3
170302  4:23:25 InnoDB: Using Linux native AIO
170302  4:23:25 InnoDB: Initializing buffer pool, size = 128.0M
170302  4:23:25 InnoDB: Completed initialization of buffer pool
InnoDB: Error: checksum mismatch in data file ./ibdata1
170302  4:23:25 InnoDB: Could not open or create data files.
170302  4:23:25 InnoDB: If you tried to add new data files, and it failed here,
170302  4:23:25 InnoDB: you should now edit innodb_data_file_path in my.cnf back
170302  4:23:25 InnoDB: to what it was, and remove the new ibdata files InnoDB created
170302  4:23:25 InnoDB: in this failed attempt. InnoDB only wrote those files full of
170302  4:23:25 InnoDB: zeros, but did not yet use them in any way. But be careful: do not
170302  4:23:25 InnoDB: remove old data files which contain your precious data!
170302  4:23:25 [ERROR] Plugin 'InnoDB' init function returned error.
170302  4:23:25 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
170302  4:23:25 [ERROR] Unknown/unsupported storage engine: InnoDB
170302  4:23:25 [ERROR] Aborting

170302  4:23:25 [Note] /usr/sbin/mysqld: Shutdown complete

解決手順

enz0.net

いろいろ、記事を探してみると、バージョンアップ前から作成されている元々あったMySQLデータを一度別の場所に退避して、起動してみると良いらしい。 MySQLのデータのパスは設定ファイルの/etc/my.cnfに記載されています。

[root@localhost mysql]# vi /etc/my.cnf

[mysqld]
datadir=/var/lib/mysql

この場合だと/var/lib/mysqlです。恐らくデフォルトで、/var/lib/mysqlだと思います。

このディレクトリに何が置いてあるか、というと。

[root@localhost /]# cd /var/lib/mysql/
[root@localhost mysql]# ls
auto.cnf        ibdata1          ib_logfile1_tes  hoge_development  test
ib_buffer_pool  ib_logfile0_tes  mysql            hoge_test

なんか色々入ってます。このMySQLRailsで使用しているので、hoge_developmenthoge_testなどの既存DBが置いてあるがわかります。 このすべてをどこかにバックアップ(退避)しつつ、

[root@localhost mysql]# ls

空の状態を確認して、再度MySQLを起動してみましょう。

[root@localhost mysql]#  service mysqld start
Initializing MySQL database:  170302  4:25:09 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
170302  4:25:09 [Note] /usr/sbin/mysqld (mysqld 5.5.54) starting as process 15584 ...
170302  4:25:09 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.
170302  4:25:09 [Note] /usr/sbin/mysqld (mysqld 5.5.54) starting as process 15591 ...

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h localhost.localdomain password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

Please report any problems at http://bugs.mysql.com/

                                                           [  OK  ]
Starting mysqld:                                           [  OK  ]

起動できたっぽいです。 入れるかな。。。

[root@localhost mysql]# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.54 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

入れました! あとはdumpしたデータベースを復元して、完了です。

参考

React - カスタムコンポーネントの基本

カスタムコンポーネントを作ってレンダーする

azunobu.hatenablog.com

前回、HTML要素からコンポーネントを作成し、レンダーする方法を学んだ。

一方でReactではHTML要素をコンポーネントにするよりも、カスタムコンポーネントを作る場合のほうが多い。 カスタムとは具体的に、「独自のスタイル要素を指定してH1要素にデザインをあてる」といった意味ではなく、 部品となるカスタムコンポーネントをクラスとして定義して、HTMLドキュメントに要素を差し込む、という意味です。

手順

  1. createClassメソッドでカスタムコンポーネントを定義する
  2. renderメソッドで定義したカスタムコンポーネントを指定して要素を作成
  3. getElementByIdで差し込む位置を指定する

といった手順を踏んで、カスタムコンポーネントを定義し、レンダーします。

書いてみる

ディレクトリ構造はこのようになっています。

.
└── hello_react
    ├── sample.html
    └── src
        └── react_script.js

sample.html

HTMLはいつもどおりです。bodyにid=contentのdiv要素を置いておきます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Hello React</title>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script type="text/babel" src="src/react_script.js"></script>
</head>
<body>
<div id="content">

</div>
</body>
</html>

このid=contentのdiv要素の中身にカスタムコンポーネントとして、以下のコンポーネントを差し込みます。

<div class="hello-world-box">
    <h1>Hello World!!</h1>
</div>

src/script.js

var HelloWorldBox = React.createClass({
    render: function () {
        return (
            <div className="helloWorldBox">
                <h1>Hello World!!</h1>
            </div>
        );
    }
});

順を追って、読んでみます。

はじめに、1行目でReact.createClassメソッドで定義するカスタムコンポーネントHelloWorldBox変数に代入します。 カスタムコンポーネント命名規則として、代入する変数名はキャメルケースとなっています。

そして、クラスの中身としてrenderメソッドを定義しています。 ここでは、レンダーしたいHTML要素を返すようにしています。

ここで注意ですが、クラス名についてHTML的な表記ではなくてclassName="helloWorldBox"というような表記へと変える必要があります。

ReactDOM.render(
    <HelloWorldBox />,
    document.getElementById('content')
);

次に、このカスタムコンポーネントを基にして要素を作成し、HTMLドキュメントに差し込む位置を指定して、レンダーする部分を書いています。 こちらは、通常のコンポーネントと同じです。

全体としてはこのようなかたちになります。

var HelloWorldBox = React.createClass({
    render: function () {
        return (
            <div class="helloWorldBox">
                <h1>Hello World!!</h1>
            </div>
        );
    }
});

ReactDOM.render(
    <HelloWorldBox />,
    document.getElementById('content')
);

ちなみにですが、<HelloWorldBox />の部分は

React.createElement(HelloWorldBox)

という風にも書けます。

動作を確認してみます。

https://gyazo.com/a83b62e34be314ce458d6f324428531c

うまく、差し込まれていることがわかります。

以上です。

参考

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発

React - コンポーネントの基本

コンポーネントを作ってHTMLにレンダリングする

今回はReactで作成するアプリケーションとして最も基礎的な構成要素となるコンポーネント定義の方法ついて。

ディレクトリ構造

azunobu.hatenablog.com

前回、HTMLファイルの中にJSコードを混在させて書いていましたが、今回はHTMLファイルとJSファイルを切り分けて、見通しを良くしていきます。

最終的に今回は以下のような構造にしました。

.
├── sample.html
└── src
    └── react_script.js

srcディレクトリを作成し、その中にreact_script.jsを作成し、HTMLファイルはは以下のように記述しました。

1点注意しなければならないのは、今回のようにローカルで実行したい場合、Chromeだとセキュリティの関連でローカルは外部のJSファイルを読み込むことは禁止されているのでエラーとなってしまいます。 そのため今回の場合はFireFoxを用いて、動作を確認していきます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Hello React</title>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script type="text/babel" src="src/react_script.js"></script>
</head>
<body>
<div id="content">

</div>
</body>
</html>

head要素では、ReactとBabelを読み込んだ後に、今回作成したreact_script.jsを読み込ませています。 また、body要素ではid=contentのdiv要素を用意しています。

そして、今回やりたいことは、id=contentのdiv要素内にReactから任意の文字列のh1タグをレンダリングすることです。

Reactのコードを書いていく

先ほど作成したsrc/react_script.jsに書いていきます。

シンプルにH1タグを指定する場合

https://gyazo.com/fab0ac46830fabcb4a6a505b46c06a48

ReactDOM.render(
    React.DOM.h1(null, 'Hello, world!'),
    document.getElementById('content')
);

何をやっているのか、コードを読むと分かる感じがしていいですね。

まず1行目のReactDOMパッケージのrenderメソッドによって、「HTMLを生成して所定の位置へと出力する」処理を行います。

renderメソッドは引数は2つ取っています。

  • 第1引数:Reactのコンポーネントから生成するHTML要素
  • 第2引数:生成したHTML要素をどこに埋め込むのか

第1引数では今回、React.DOMのh1メソッドを利用し、<h1>Hello, world!</h1>という要素を作ることを指定しています。 このh1メソッドでは第1引数にnullを渡していますが、ここにはstyleといった要素の属性を指定することができます。

H1タグに属性を指定する場合

今回はstyle属性でh1要素にスタイルをあてたいと思います。

ReactDOM.render(
    React.DOM.h1({
            style: {
                fontSize: '1.2em',
                color: '#242424',
                backgroundColor: '#FFF200'
            }
        },
        'Hello, world!'
    ),
    document.getElementById('content')
);

では動作を確認してみます。

https://gyazo.com/b8fc437a9ee09d19866fd603b301b8f6

このように、要素の属性指定が反映されていることが確認できます。

なお、属性を指定するときに注意すべき点としては、CSSの属性background-colorなどの属性名はbackgroundColorというように、キャメルケース(CamelCase)で表記する必要がある点です。 Reactは他の単語や変数名などもJavaScriptのオブジェクトのようにキャメルケースで表現する場合が多いようです。

今回は基本のコンポーネントの作成とレンダーについて学びました。

以上です。

参考

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発

React - babel-browserとJSXとは何か

何気なく書いた babel-browserとは何か

azunobu.hatenablog.com

前の記事でHello Worldした際に、HEAD要素の一つに

<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>

というものがありました。 ここで読み込んでいるbabel-browserは一体何なのでしょうか。

JSX

facebook.github.io

babel-browserを知るためにはまず、JSXという拡張を知る必要があります。

JSXは、XMLに似たJavaScriptシンタックスの拡張です。Reactでは、単純なJSXのシンタックスの変換を使うことができます。 ReactでJSXの使用は強制されているわけではないですが、木構造とReactの特性を定義しやすいシンタックスであるため、JSXを使用することをおすすめしています。 デザイナーのようなカジュアルな開発者にとっても馴染みやすいものとなっています。

つまり、JSXを用いることでJSの中でXMLタグ、またHTMLタグをを使用することができるようになります。 一般的に現在普及しているブラウザには、JSコードのなかにタグを書いてしまうとブラウザはコードを解釈できず実行できない場合があります。

そこで、そういったXMLを含んだ次世代JSコードを動的に変換し、すべてのブラウザでも解釈できるように頑張ってくれるライブラリがBabel、つまりCDNで読み込んだbrowser.min.jsスクリプトです。

もっと詳しく次世代JSコードとは何なのか

JSにはECMAScriptという言語仕様が定義されています。 これにはバージョンがいくつかあり、次世代JSとして2015年に採択されたECMAScript2015というものがあります。

ちなみにですが、ECMAScript2015(以降、ES2015)という名称ですが、策定された2015年の当初はES6と呼ばれていました。そのため、記事によってはES6と表記されて紹介されていることもあります。

現在このES2015に対応できていないブラウザがまだ存在しているため、ES2015で書かれたコードはES6に変換する必要があり、 その時に変換してくれるライブラリの一つとしてBabelがあります。

ES5とES2015のコードの違い

以前のHello WorldしたHTMLファイルの中身から任意に書いたスクリプト部分を取り出して比較してみます。

ES2015で書いた場合

<script type="text/babel">
    ReactDOM.render(
            <h1>Hello, world!</h1>,
        document.getElementById('root')
    );
</script>

ES5では、解釈できない<h1>Hello, world!</h1>というXMLが含まれています。

ES5で書いた場合

<script>
    ReactDOM.render(
      React.createElement(
          'h1',
          null,
          'Hello, World'
      ),
        document.getElementById('root')
    );
</script>

なんとなく馴染みのある、書き方です。

アプリを公開するとき

今回は、ユーザのブラウザ上でBabelを読み込み、各々で変換するようになっていますが、 これは変換する手間がかかり、効率がよくないため、通常は公開段階であれば 既にBabelを用いて変換されたコードが配信されることになるのが普通のようです。

今回は、何気なくスクリプトとして読み込んでいたBabelライブラリについて、また、なぜ変換する必要があるのかについてECMAScriptに触れてかんたんにまとめました。

以上です。

参考

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発