はじめに
仕事でReactを使うようになったので勉強がてら自分でReact,Typescript,Railsを使ったアプリを勉強していましたが
意外と最初の設定でつまずいたのでまとめます。
Rails new
bundle init
#Gemfileにてrailsのコメントアウトを外す
bundle install --path vendor/bundle
bundle exec rails new .
bundle install
bundle update
Webpackerを除く
Gemfileからwebpackerを除きます。
React表示用のviewを作成
bundle exec rails g controller react-ui::home index
tsconfigを作成
typescriptを使うためにはtsconfigを作成しなくてはいけない
railsのルートディレクトリにtsconfig.jsonファイルを作成して中身を以下の様にする
{
"compilerOptions": {
"strictNullChecks": true,
"noUnusedLocals": true,
"noImplicitThis": true,
"alwaysStrict": true,
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": false,
"lib": ["dom", "ES2017"],
"module": "commonjs",
"target": "es5",
"jsx": "react",
"baseUrl": ".",
"paths": { "import-png": ["types/import-jpg"] },
"typeRoots": ["types", "node_modules/@types"]
}
}
npm install webpack -D
webpackを使える様にする
npm install webpack -D
npm install webpack-cli -D
npm isntall webpack-dev-server -D
webpack記載
railsのルートディレクトリにwebpack.config.jsファイルを作成する。
webpack.config.jsを以下の様に記載する
npm install typescript
npm install html-webpack-plugin -D
npm install webpack-manifest-plugin -D
npm install ts-loader style-loader css-loader file-loader url-loader -D
不要なエラーが発生するので vendor/bundle/ruby/2.6.0/gems 以下のwebpackerのフォルダを削除します。
const HtmlWebpackPlugin = require("html-webpack-plugin")
const ManifestPlugin = require("webpack-manifest-plugin")
const path = require('path');
module.exports = {
mode: "development",
entry: {
home: `${__dirname}/app/webpack/entry/home`
},
output: {
path: `${__dirname}/public/packs`,
publicPath: `${__dirname}/app/webpack`,
filename: "[name].js"
},
module: {
rules: [{
test: /\.(tsx|ts)$/,
loader: "ts-loader"
},
{
test: /\.css/,
use: [
"style-loader",
{
loader: "css-loader",
options: { url: true }
}
]
},
{
test: /\.(jpg|png)$/,
loader: "file-loader?name=/public/[name].[ext]"
},
{ test: /\.(eot|svg|woff|ttf|gif)$/, loader: "url-loader" }
]
},
watchOptions: {
poll: 500
},
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
plugins: [
new HtmlWebpackPlugin({
template: `${__dirname}/app/webpack/index.html`,
filename: "index.html"
}),
new ManifestPlugin({
fileName: "manifest.json",
publicPath: "/packs/",
writeToFileEmit: true
})
],
devServer: {
publicPath: "/packs/",
historyApiFallback: true,
inline: true,
hot: true,
port: 3035,
contentBase: "/packs/"
}
};
app/webpack以下にindex.htmlを作成して以下の様に記載します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
</html>
package.jsonにscriptを追加
package.jsonが作成されているはずなのでそのファイルを開きscriptを以下の様に設定する
"scripts": {
"start": "webpack-dev-server --hot --inline --contentbase public/packs/ --mode development"
},
これで npm start をコマンドを打ったときにwebpack-dev-serverが起動してくれる
reactを使えるようにする
npm install react -D
npm install react-dom -D
webpack.config.jsのentryからjavascriptを読み込むので
${__dirname}/app/webpack/entry/home
のフォルダにindex.tsxを作成します。
そして中身を以下の様にします。
import * as React from "react";
import { render } from "react-dom";
render(<div>Home</div>, document.getElementById("root"));
Rails側で読み込むロジック追加
webpackerを使わないのでjavascript_pack_tagは使えません。
ですので
react_ui/home/index.html.erbを以下の様にします。
<div id="root"></div>
<% if Rails.env == "development" %>
<script src="http://localhost:3035/packs/home.js"></script>
<% else %>
<script src="/packs/home.js"></script>
<% end %>
config/routes.rbに
root to: "react_ui/home#index"
を追加
layouts/application.html.erbの
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
を削除します。
動作確認
bundle exec rails s
npm start
を実行してlocalhost:3000にアクセスすれはHomeが表示されるはずです。
あとは好きにreactを書いていけばOKです。