概要
React は環境構築が非常に面倒なイメージがありますが、つい最近 Facebook が作った create-react-app
を使うと一瞬で環境構築が出来ます。
詳しくは下記の記事が参考になります。
Facebook公式のcreate-react-appコマンドを使ってReact.jsアプリを爆速で作成する
create-react-app
は npm run build
コマンドで本番環境で使われることを想定した最適化されたファイルを build ディレクトリ生成することが出来ます。
しかし、Ruby on Rails 等のフレームワークを使ってる場合は、/public
以下に js を配置しなければなりません。
そこでこの記事では、 build ディレクトリ以外の任意のディレクトリに最適化された js を配置する方法を記述します。
前提
- macOS Sierra バージョン 10.12.4
- node v6.2.2
- npm 3.9.5
- create-react-app 1.3.0
解決方法
まず、予め create-react-app
で生成したディレクトリで下記コマンドを実行し、設定ファイルをカスタマイズ出来るようにする。
npm run eject
弄るファイルは下記の3つ。
- /config/paths.js
- /config/webpack.config.prod.js
- /scripts/build.js
下記の手順で行う。
- 最適化されたファイルが生成されるディレクトリのパスを指定
- 生成される js の名前とパスを指定
- ファイル生成先ディレクトリが初期化されないようにする
最終的には、 public/js/[name].js
という形でファイルが生成されるようになる。
1. 最適化されたファイルが生成されるディレクトリのパスを指定
今回は build を public に変更してみる。
// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp('.env'),
appBuild: resolveApp('build'), // ここを変える
...
↓
// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp('.env'),
appBuild: resolveApp('public'), // ここを変える
...
2. 生成される js の名前とパスを指定
static/js/[name].[chunkhash:8].js
を js/[name].js
に変更する。
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: 'static/js/[name].[chunkhash:8].js', // ここを変える
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js', // ここも変える
...
↓
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: 'js/[name].js', // ここを変える
chunkFilename: 'js/[name].chunk.js', // ここも変える
...
3. ファイル生成先ディレクトリが初期化されないようにする
公式のコメントにもいらなかったら削除しろって書いてありますね。
measureFileSizesBeforeBuild(paths.appBuild)
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild); // これをコメントアウト
...
↓
measureFileSizesBeforeBuild(paths.appBuild)
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
// fs.emptyDirSync(paths.appBuild); // これをコメントアウト
...
まとめ
フロントエンドにはあまり詳しくないので、このようなアプローチが正しいかどうかはわかりません。
もし詳しい方で、ちゃんとした方法を知っている方がいらっしゃいましたら是非教えて頂けると幸いです。