RailsでどうJS(とSass)を書いていくか
僕の書いていくときの方針。普段やってることをまとめるために書いた。
Webpackerは使いたくない
基本的にwebpackを使っていきたい。
webpackerの設定の書き方が微妙によくわからないのが一つ。
jsやcssといった部分がrailsの管理下に置かれるのがいやというのが一つ。
あるディレクトリの下に置いたものを無自覚に全てコンパイルしてまとめてしまう、というアプローチがあまり好きではないのが一つ。
この点に関してはimportなどの仕方を考えれば問題がないように思えるけど、まあwebpackを使用する前提だったし、深く考えていない。
Webpackを使いたい
webpackの設定ファイル自体はこんな感じで、どのファイルに何をコンパイルさせるか、を明示的に書いていきたい。
適当にディレクトリ丸っとコンパイル、みたいなことはしたくはない。使用する処理はできるだけ小さくしたい。
まあ大きくコンパイルしてキャッシュを効かせた方が効率が良い、ということはあるかもしれない。その辺は要計測か。
var webpack = require('webpack')t
var path = require('path')
var autoprefixer = require("autoprefixer");
var process = require("process");
let time = new date().gettime()
let env = process.env.env
let entry = {
"admin" : [
"./frontend/src/admin/index.ts" ,
"./frontend/src/admin/index.sass" ,
"./frontend/src/admin/sidemenu.sass" ,
"./node_modules/muicss/dist/css/mui.min.css" ,
"./node_modules/muicss/dist/js/mui.min.js" ,
] ,
"list" : [
"./frontend/src/crud/csvupload" ,
"./frontend/src/crud/csvupload.sass" ,
] ,
"front/application" : [
"./frontend/src/front/index.ts" ,
"./frontend/src/front/index.sass" ,
] ,
}
let plugins = [
new webpack.defineplugin({
'process.env.node_env': json.stringify('production')
}),
new webpack.loaderoptionsplugin({
options: {
postcss: [
autoprefixer({ browsers: ['last 2 versions'] }),
process
]
}
})
];
module.exports = {
cache:true ,
entry: entry ,
output: {
filename: "[name].js?[hash:6]",
path: __dirname + "/app/assets/javascripts"
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
{
test: /\.css$/,
use: [{
loader: "style-loader" // creates style nodes from js strings
}, {
loader: "css-loader" // translates css into commonjs
}]
},
{
test: /\.sass$/,
use: [{
loader: "style-loader" // creates style nodes from js strings
}, {
loader: "css-loader" // translates css into commonjs
}, {
loader: "sass-loader"
}, {
loader: "import-glob-loader"
}]
},
{
test: /\.tsx?$/,
loader: "awesome-typescript-loader" ,
options: {
configfilename: 'tsconfig.json'
},
},
{
test: /\.(jpg|png|woff|woff2|eot|otf|ttf|svg)$/,
loader: 'url-loader?limit=100000&name=/[hash].[ext]'
}
]
},
plugins: plugins ,
};
TypeScriptを使いたい
前の記事でも書いたけど基本的にTypeScriptを使いたい。
assetpipelineは使いたい
正直ここは悩んでいて、jsもまあ適当にpublicの下にでも放り込んでおけばよいと思いはしている。
フロント領域をRailsに管理させたくないというのであれば、これも切ってしまって良いのでは?という悩みはある。
jsのバージョンを上げたらjsのパスが変わってくれて、キャッシュが完全にクリアされることはメリットかなと思っている。
フィンガープリントがつくことにそれほど大きくメリットを感じていなくて、気づいたら使わなくなっている可能性はある。
turbolinkは使いたくない
なんかあんまりメリットを感じない。
jsのevent周りでうまく動かない印象が強い。
railsに精通してないと言われれば確かにそうなんだけど、前述したけどフロントの領域をrailsに管理させたくない。
Rails側のデータ類をどうやってjsに渡すのか
基本的にテンプレートはslimで書いている。
その中で値は、適当なinput要素を作って、typeをhiddenで宣言、valueには.to_jsonした値を渡したりする。
def disptacher_with_item
@items = item.all
end
input type="hidden" id="items" value=@items.to_json
本当はたぶんデータバインディングとか使っていい感じにするとかしたほうがよさそうだし、データが重いんならAPIとかしつらえたほうが良いですね
画像にどうアクセスしていくのか
テンプレートからアクセスする場合
普通に描くのと一緒で適当にpublilcにでも放り込んでおけばよいかな
JSからアクセスする場合
特にReactからアクセスするときとかだけど、代替Public以下に放り込んでNginxから直接アクセスするようにしている。
Webpack経由でバイナリをJSにイイ感じにまとめたいという欲はあるけどうまくいかなかった記憶が強い
Sassからアクセスする場合
これはむしろSass/Webpackからアクセスできる位置に置いてJSにまとめている
HTMLとJSとSassの組み立て方
割とJS自体は臨機応変に書けばよいとは思っている。
代替大変なことになるのはCSSとHTMLかと思っている。
HTMLとJSの組み合わせを考えると
全部Reactのページ(遷移とかはReactで行っていない非
スタイルシートはReactのクラスとセットで運用すればよさそう。
Reactのコンポーネントと対応する形でスタイルシートを書いていけば、使いまわしとかは気にしなくてよいはず。
ページの一部でReactを使うページ
大変。
コンポーネント的な粒度が、HTMLとReactのコンポーネントで異なっている。
HTMLLで使いたいスタイルシートはページ.sass的になるし、ReactのものはReactで使うスタイルシートになる。
個人的にはReactを大部分で使うならあきらめて全部Reactで書くのが楽かも。
SPA
全部Reactのコンポーネントでやるのでコンポーネント単位でスタイルシートを書いていけばいいしHTMLのことも気にしないでいいので特に問題なさそう