はじめに
create-react-app
便利ですね!
僕は react
は create-react-app
から入ったクチなので先輩方から「 react
は昔は環境構築大変だった」とよく聞きますがいまいちピンと来ていません。
というわけで create-react-app
が裏で何をやっているかまとめます。
対象読者
-
create-react-app
使ってはいるけど、何やってるかあんまり分かってない人(僕)
この記事でやること
-
create-react-app
でアプリ作成 -
create-react-app
でアプリ作成し、npm run eject
でcreate-react-app
コマンドでパッケージされた状態を外す - 1と2を比較
以下、
1 の create-react-app
のオリジナルの状態は create-react-app-org
ディレクトリ、
2 の npm run eject
は create-react-app-eject
ディレクトリ、
でやることにします。
1. create-react-app
を普通に実施
環境構築
node
はインストールされてる前提。
$ node -v
v8.11.1
$ npm -v
5.6.0
$ npm install -g create-react-app
$ mkdir create-react-app-org
$ cd create-react-app-org
$ create-react-app hello-world
$ cd hello-world
実行
以下のどちらか。
development 環境
$ npm start
production build 環境
$ cd src
$ npm run build
$ cd ../build
$ npm install -g http-server
$ hs
ブラウザでアクセス http://127.0.0.1:8080
はい、デフォルトのアプリ起動しました。
ほんと、簡単で素晴らしいですね。
ここで、 create-react-app hello-world
時のログ、
$ create-react-app hello-world
Success! Created hello-world at /path/to/create-react-app-org/hello-world
Inside that directory, you can run several commands:
npm start
Starts the development server.
npm run build
Bundles the app into static files for production.
npm test
Starts the test runner.
npm run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
We suggest that you begin by typing:
cd hello-world
npm start
Happy hacking!
$
が気になります。
2. create-react-app
を npm run eject
環境構築
$ mkdir create-react-app-eject
$ cd create-react-app-eject
$ create-react-app hello-world
$ cd hello-world
npm run eject
$ npm run eject
> hello-world@0.1.0 eject /path/to/create-react-app-eject/hello-world
> react-scripts eject
? Are you sure you want to eject? This action is permanent. Yes
Ejecting...
Copying files into /path/to/create-react-app-eject/hello-world
Adding /config/env.js to the project
Adding /config/paths.js to the project
Adding /config/polyfills.js to the project
Adding /config/webpack.config.dev.js to the project
Adding /config/webpack.config.prod.js to the project
Adding /config/webpackDevServer.config.js to the project
Adding /config/jest/cssTransform.js to the project
Adding /config/jest/fileTransform.js to the project
Adding /scripts/build.js to the project
Adding /scripts/start.js to the project
Adding /scripts/test.js to the project
Updating the dependencies
Removing react-scripts from dependencies
Adding autoprefixer to dependencies
Adding babel-core to dependencies
Adding babel-eslint to dependencies
Adding babel-jest to dependencies
Adding babel-loader to dependencies
Adding babel-preset-react-app to dependencies
Adding babel-runtime to dependencies
Adding case-sensitive-paths-webpack-plugin to dependencies
Adding chalk to dependencies
Adding css-loader to dependencies
Adding dotenv to dependencies
Adding dotenv-expand to dependencies
Adding eslint to dependencies
Adding eslint-config-react-app to dependencies
Adding eslint-loader to dependencies
Adding eslint-plugin-flowtype to dependencies
Adding eslint-plugin-import to dependencies
Adding eslint-plugin-jsx-a11y to dependencies
Adding eslint-plugin-react to dependencies
Adding extract-text-webpack-plugin to dependencies
Adding file-loader to dependencies
Adding fs-extra to dependencies
Adding html-webpack-plugin to dependencies
Adding jest to dependencies
Adding object-assign to dependencies
Adding postcss-flexbugs-fixes to dependencies
Adding postcss-loader to dependencies
Adding promise to dependencies
Adding raf to dependencies
Adding react-dev-utils to dependencies
Adding resolve to dependencies
Adding style-loader to dependencies
Adding sw-precache-webpack-plugin to dependencies
Adding url-loader to dependencies
Adding webpack to dependencies
Adding webpack-dev-server to dependencies
Adding webpack-manifest-plugin to dependencies
Adding whatwg-fetch to dependencies
Updating the scripts
Replacing "react-scripts start" with "node scripts/start.js"
Replacing "react-scripts build" with "node scripts/build.js"
Replacing "react-scripts test" with "node scripts/test.js"
Configuring package.json
Adding Jest configuration
Adding Babel preset
Adding ESLint configuration
Running npm install...
added 1 package and updated 2 packages in 8.329s
Ejected successfully!
Please consider sharing why you ejected in this survey:
http://goo.gl/forms/Bi6CZjk1EqsdelXk1
$
何が起きたのか?
create-react-app
コマンドで作られた環境は react-scripts
でまるっとまとめられていたのですが、それを解放して、必要なモジュールを一つ一つ手でインストールしたのと同じ状態になりました。
npm run eject
後の状態でも
development 環境
$ npm start
production build 環境
$ cd src
$ npm run build
$ cd ../build
$ npm install -g http-server
$ hs
ブラウザでアクセス http://127.0.0.1:8080
create-react-app
と同様、どちらでもアプリ実行可能です。
3. 比較
npm run eject
前後の比較をします。
package.json
create-react-app
素の状態
/path/to/create-react-app-org/hello-world$ cat package.json
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-scripts": "1.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
npm run eject
後
/path/to/create-react-app-eject/hello-world$ cat package.json
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"dependencies": {
"autoprefixer": "7.1.6",
"babel-core": "6.26.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-preset-react-app": "^3.1.1",
"babel-runtime": "6.26.0",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "1.1.3",
"css-loader": "0.28.7",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"eslint": "4.10.0",
"eslint-config-react-app": "^2.1.0",
"eslint-loader": "1.9.0",
"eslint-plugin-flowtype": "2.39.1",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.4.0",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"jest": "20.0.4",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",
"promise": "8.0.1",
"raf": "3.4.0",
"react": "^16.3.2",
"react-dev-utils": "^5.0.1",
"react-dom": "^16.3.2",
"resolve": "1.6.0",
"style-loader": "0.19.0",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.6.2",
"webpack": "3.8.1",
"webpack-dev-server": "2.9.4",
"webpack-manifest-plugin": "1.3.2",
"whatwg-fetch": "2.0.3"
},
//略
create-react-app
素の状態では、dependencies が react, react-dom, react-scripts の僅か3パッケージだったのに対し、 npm run eject
するとパッケージ数が途端に増えました。
ディレクトリ構成
create-react-app
素の状態
/path/to/create-react-app-org/hello-world$ tree -I 'node_modules'
.
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── registerServiceWorker.js
2 directories, 13 files
$
npm run eject
後
/path/to/create-react-app-eject/hello-world$ tree -I 'node_modules'
.
├── README.md
├── config
│ ├── env.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── paths.js
│ ├── polyfills.js
│ ├── webpack.config.dev.js
│ ├── webpack.config.prod.js
│ └── webpackDevServer.config.js
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── registerServiceWorker.js
5 directories, 24 files
$
create-react-app
素の状態では、ほぼソースファイルのみだったのに対し、 npm run eject
すると隠れていた config ファイルが現れます。
まとめ
本来大量のパッケージと設定ファイルをしこしこ用意して react
環境を作らねばならなかったところ、
create-react-app
コマンドは一発でその環境を用意し、良い感じに隠蔽し、ソースファイルを見やすく、開発しやすくするツールでした。
#もちろん、細かく手を入れたければ npm run eject
してカスタマイズ。もしくはイチから環境構築。
参考
Facebook公式のcreate-react-appコマンドを使ってReact.jsアプリを爆速で作成する
Facebook 公式ツール Create React App を使って React 開発の初歩を学ぶチュートリアル
2018 年 React と Redux のエコシステム総まとめ
ゼロから始めるJavaScript生活