This is a cache of https://qiita.com/yokoto/items/97e70ba3ef2436aa6dd7. It is a snapshot of the page at 2019-08-20T05:29:20.723+0000.
RailsアプリにWebpacker(React + TypeScript)をセットアップする - Qiita
Posted at

RailsアプリにWebpacker(React + TypeScript)をセットアップする


はじめに

作成中のRailsアプリのフロントエンドにReactを使いたかった。

Railsアプリ上でReactを利用する方法は複数あるらしい。


RailsでReact.jsを使ういくつかの方法

2016年時点で、RailsでReact.jsを使う方法はいくつかあって、どれを採用するかで悩みました。


  1. vendor/assets/javascripts にreact.jsを置いて利用する

  2. react-rails gem を利用する

  3. browserify-rails で npm管理して利用する

  4. railsプロジェクト内に、JavaScript開発用のディレクトリを用意して webpack + babel-loader で利用する

調査したところ、だいたいこんなパターンがあると思っていて、下に行くほどRailsよりもJavaScript開発の知識が必要になってくるイメージでした。


webpackを使った Rails上でのReact開発 - クックパッド開発者ブログ より

できるだけモダンな方法を採用したかったが、


  1. webpackをいきなり採用する自信がなかった

  2. 仕事先でWebpackerを使っているプロジェクトがあった

という理由で、Railsのgemとしてwebpackを扱えるWebpackerを採用することに。

せっかくなので個人的に勉強していたTypeScriptも合わせて導入してみる。


方法

READMEをちゃんと読んで進める。

rails/webpacker/README.md - Github

1.Webpackerのインストール


Gemfile.

gem 'webpacker'


$bundle install

$bundle exec rails webpacker:install

自分がこれから設定していくWebpack環境のビルドは以下のように行う。

webpack-dev-serverのビルド

$bin/webpack-dev-server

webpackのビルド

$bin/webpack

2.Reactを使えるようにする

$bundle exec rails webpacker:install:react

3.TypeScriptを使えるようにする

$bundle exec rails webpacker:install:typescript

$yarn add @types/react @types/react-dom

4.jsxファイルをtsxに変更

$mv hello_react.jsx hello_react.tsx

5.tsxファイルの中身を編集


app/javascript/packs/hello_react.tsx

import React from "react";

import ReactDOM from "react-dom";

interface HelloProps {
name: string;
}

const Hello: React.SFC<HelloProps> = props => (
<div>Hello {props.name}!</div>
)

Hello.defaultProps = {
name: "David",
}

document.addEventListener("DOMContentLoaded", () => {
ReactDOM.render(
<Hello name="React" />,
document.body.appendChild(document.createElement("div")),
)
})


Webpacker で React + TypeScript - Qiita より

6.ビルドが成功したらhello_react.tsxファイルを挿入したい任意のRailsのviewsファイル<%= javascript_pack_tag 'hello_react' %> という形で挿入。


app/views/static_pages/index.html.erb

...

<section>
<%= javascript_pack_tag 'hello_react' %>

</section>
...


7.1~5で作成されたor編集したファイルなど


package.json

{

"name": "MyRailsApp",
"private": true,
"dependencies": {
"@babel/preset-react": "^7.0.0",
"@rails/webpacker": "^4.0.6",
"@types/react": "^16.8.23",
"@types/react-dom": "^16.8.4",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"ts-loader": "^6.0.4",
"tslint": "^5.18.0",
"tslint-config-airbnb": "^5.11.1",
"tslint-loader": "^3.5.4",
"typescript": "^3.5.2",
"webpack-dev-server": "^3.5.1"
}
}


tsconfig.json

{

"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"*": ["node_modules/*", "app/javascript/*"]
},
"sourceMap": true,
"target": "es5",
"allowSyntheticDefaultImports": true, // 追加
"jsx": "react" // 追加
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}


tslint.json

// 追加↓

{
"extends": ["tslint-config-airbnb", "tslint-react", "tslint-config-prettier"],
"rules": {
"variable-name": [true, "ban-keywords", "check-format", "allow-pascal-case"]
}
}


webpacker.yml

...

extensions:
- .jsx // 追加
- .tsx
...

config/webpack/*.jsは特に修正しなかった気がする。

loaderの変更もややこそうだったのでなし。


config/webpack/environment.js

const { environment } = require('@rails/webpacker')

const typescript = require('./loaders/typescript')

environment.loaders.prepend('typescript', typescript)
module.exports = environment



config/webpack/loaders/typescript.js

const PnpWebpackPlugin = require('pnp-webpack-plugin')

module.exports = {
test: /\.(ts|tsx)?(\.erb)?$/,
use: [
{
loader: 'ts-loader',
options: PnpWebpackPlugin.tsLoaderOptions()
}
]
}



感想

いろんなファイルが生成されたのでどこをいじればいいかわからず大変だった。

Linterのエラーが出まくったりビルドが通らなくていろいろ修正したりして沼になったりしたが、READMEとエラー文に忠実に進めていくのが大事。

Webpack の考え方について