3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.jsでReScript, tailwindを使う

Last updated at Posted at 2021-03-21

Next.js x ReScript

ReasonMLを利用するNext.jsのサンプルを利用

yarn create next-app --example with-reasonml with-reasonml-app

ライブラリをupgrade

yarn upgrade bs-platform@^9.0.2 reason-react@^0.9.1 react@^17.0.1 react-dom@^17.0.1

サンプルをコマンドで作った時はパッケージのバージョンが古いので更新する。

ReasonML -> ReScriptに変換

for f in pages/**/*.re; do; node_modules/.bin/bsc -format $f > ${f%.re}.res && rm $f; done;
for f in components/**/*.re; do; node_modules/.bin/bsc -format $f > ${f%.re}.res && rm $f; done; 
for f in bindings/**/*.re; do; node_modules/.bin/bsc -format $f > ${f%.re}.res && rm $f; done;

で一括でReasonML形式(.re)からReScript形式(.res)に変換できる。

動作確認

以下の二つをそれぞれ別のターミナルタブ/ウィンドウで実施

yarn dev:reason
yarn dev: next

tailwind

TailwindはCSSフレームワークの一つで、Next.jsで利用する方法が公式に載っているので概ね従う。

install

yarn add --dev tailwindcss@latest postcss@latest autoprefixer@latest
yarn tailwindcss init -p

Next.jsで読めるようにする

style/main.css
@tailwind base;
@tailwind components;
@tailwind utilities;
pages/_app.js
import '../styles/main.css'

export default function MyApp({ Component, pageProps }) {
    return(<div>
        <Component {...pageProps} />
    </div>);
}
tailwind.config.js
module.exports = {
  purge: [
      './pages/**/*.res',
      './components/**/*.res',
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

memo

_app.resから変換できないの?と思うが、
bsconfigでsuffix.bs.jsにしているので_app.resを書いても_app.bs.jsにしかならない。
suffixを書き換えれば.jsを出力することもできるが、.bs.jsが強く推奨されている。

また、スプレッド演算子...の利用が推奨されていない。
Props Spread

You can't.

cloneElementを利用することで、回避を試みる。

_app.res
%raw(`require("../styles/main.css")`)

let make = (~component, ~pageProps) => ReasonReact.cloneElement(
    component,
    ~props=pageProps,
    []
  );

let default = make

Failed to compile

が出て, global CSSが読み込めるのはどうあがいてもpages/_app.jsだけという事実は揺るがないとわかる。
ただ、上記のファイルのようにしてsuffixを.jsにしても動かなかったので、書き方が間違えている可能性がある[調査中]
_app.resの例もDestructuringになってないし。
まぁ、_app.jsぐらいJavaScriptでもええじゃろ。

動作確認

Headerを以下のように変更する。外側のclassNameborder-b bg-white py-2 md:py-4でtailwindを利用している。

components/Header.res
@react.component
let make = () =>
    <nav className="border-b bg-white py-2 md:py-4">
        <div>
            <Next.Link href="/">{ReasonReact.string("Home")}</Next.Link>
            <Next.Link href="/about">{ReasonReact.string("About")}</Next.Link>
        </div>
    </nav>

let default = make

header_change.png

#ちなみに

yarn dev~のところでbsbのエラーが出た場合は以下のスクリプトを実行するとと直ることがある。

first.sh
touch ./node_modules/bs-platform/index.js
sed -i -e 's/^{$/{\n  "main": "index.js",/g' ./node_modules/bs-platform/package.json

vercelにデプロイする場合はOVERRIDEを設定し、このスクリプトをbuildコマンドに含める。

./first.sh && yarn build

vercel_build.png

Future works

re-tailwindを用いて型を利用した設定が可能?
少し試した感じでは動かなかったので要調査。

追記

rescript用のreactライブラリがあったので、そちらを利用する。

ReasonReact -> RescriptReact

yarn

yarn remove reason-react
yarn add @rescript/react

migration

bsconfig.json
- "bs-dependencies": ["reason-react"],
+ "bs-dependencies": ["@rescript/react"],
Header.res
-             <Next.Link href="/">{ReasonReact.string("Home")}</Next.Link>
-             <Next.Link href="/about">{ReasonReact.string("About")}</Next.Link>
+             <Next.Link href="/">{React.string("Home")}</Next.Link>
+             <Next.Link href="/about">{React.string("About")}</Next.Link>

その他の場所についても、ReasonReact.stringReact.stringに置き換える。

他の表現についても、ライブラリのドキュメントに記載されているので確認されたし。

package.json
-     "dev:reason": "bsb -clean-world -make-world -w",
+     "dev:rescript": "bsb -clean-world -make-world -w",

package.jsonについては変えなくても大丈夫だが変えたくなる。

#参考文献
Next.js - Example app using ReasonML & ReasonReact components
ReScript - Migrate from BuckleScript/Reason
ReScript Forum - Purpose, alternatives to next-transpile-modules in next ReScript projects
Tailwind CSS - Install Tailwind CSS with Next.js
ReScript - Configuration - suffix
ReasonReact - Props Spread
ReasonReact - cloneElement
ReScript - Destructuring
re-tailwind
rescript-react
ReScript - rescript-react - Migrate from ReasonReact

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?